[HN Gopher] Two Years of Squash Merge (2019)
___________________________________________________________________
Two Years of Squash Merge (2019)
Author : m_a_g
Score : 45 points
Date : 2021-04-30 18:34 UTC (4 hours ago)
(HTM) web link (blog.dnsimple.com)
(TXT) w3m dump (blog.dnsimple.com)
| chmaynard wrote:
| Here's an alternative that appears to accomplish the same thing:
| # checkout feature branch git switch feature #
| reset HEAD while preserving changes to working tree #
| commits on feature branch will become orphans git reset
| --soft main # commit all changes on feature branch
| git add -A; git commit -m <feature description> #
| checkout the main branch and merge git switch main
| git merge feature
| gouggoug wrote:
| I will always fight tooth and nail against squash merge.
|
| Squash merge has the major disadvantage of getting rid of
| valuable meaningful git history.
|
| Squash merge is not the proper solution for keeping your git
| history clean, it is a hack using the side effect of squash.
|
| Keeping your git history clean is a matter of policy, best-
| practices and education:
|
| Developers should be required to submit _clean_ PRs, that is,
| PR's whose git history has been organized and refactored in such
| a way that it removed "clean up commits", "typo fix", etc.
|
| When you squash merge a feature branch that has thousands of
| lines of code, and 6 months later you have a bug introduced by
| this feature branch, it becomes extremely hard to find which line
| introduced the bug.
|
| On the other hand, if you kept the history, and if this history
| was clean from the get go, it becomes easy to read the commits
| one-by-one and understand the issue.
|
| Don't use squash+merge.
|
| edit: I see numerous comment saying, in essence, "squash+merge"
| is what gets rid of the dirty history. No, developers must learn
| the existence of `git rebase --interactive`, which is the command
| to use to clean your git history[0]. "squash" is one possible
| action, among others, that helps cleaning the history.
|
| [0]: https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History
| hinkley wrote:
| Squash merge is for people who are so wedded to the idea that
| you should guess why the code is the way that it is instead of
| looking it up, that they want to make sure nobody else can do
| it either.
|
| You know, assholes.
|
| It's fine if you don't want to use something, or use it, as
| long as it doesn't drag your whole team into your decision.
| Which squash merge does.
| [deleted]
| bennysomething wrote:
| Disagree, having a bunch of commits made up of undo, redo ,
| dunno what I'm doing , oh no now I know, commits is pretty
| annoying. Squash solves that (for me, when dealing with other
| peoples merges). Obviously just my opinion etc
| marton78 wrote:
| The problem is real and the parent commenter addresses it:
| learn interactive rebasing to craft a beautiful commit
| history.
| streblo wrote:
| > Developers should be required to submit _clean_ PRs, that is,
| PR's whose git history has been organized and refactored in
| such a way that it removed "clean up commits", "typo fix", etc.
|
| The only way I've ever seen this accomplished is through Github
| squash and merge.
| drtz wrote:
| > When you squash merge a feature branch that has thousands of
| lines of code, and 6 months later you have a bug introduced by
| this feature branch, it becomes extremely hard to find which
| line introduced the bug.
|
| The article makes an argument that each commit should be "a
| single logical change." Squashing thousands of lines of code
| from a long-running feature branches into a single commit is
| obviously not what the author is suggesting.
| FunnyLookinHat wrote:
| > Squash merge has the major disadvantage of getting rid of
| valuable meaningful git history.
|
| I think the main point of the article is that the Git history
| is often *not* valuable (because it's hard to enforce good
| commit messages). Your later points are very valid, however,
| and that's why I argue for smaller pull requests (and never
| merging a PR into main that leaves it in a broken state).
| Cymen wrote:
| I am in agreement however I suspect many developers have never
| seen the usage of "git bisect" to track down a bug and fix it.
| Once you see the power of that, I think one can come to
| appreciate more the granular git history that is present when
| not using squash commits.
|
| Of course, git bisect still works with squash commits it just
| makes your job as the bug fixer much harder because typically
| squashed commits are quite large so you have to figure out what
| in the N lines of code introduced the defect.
| calpaterson wrote:
| > Developers should be required to submit _clean_ PRs, that is,
| PR's whose git history has been organized and refactored in
| such a way that it removed "clean up commits", "typo fix", etc.
|
| A complete and utter waste of time. You spend more time messing
| about with rebase than solving problems.
|
| When you're digging through VCS history due to a bug you often
| ignore the commit message anyway - if the code did what it
| seemed to do you wouldn't be there.
| sebastialonso wrote:
| I think I'm missing something here. How valuable is to have
| 20 commits of "fix this error" , "fix the fix of the error",
| "revert all fixes", "real fix".... etc? I'd argue a PR with
| many commits such as these, conveys little no no useful
| information, when the actual change is 1-3 LOC.
|
| what about cleaning and filtering out useless commits, by
| soft reseting the branch and commiting just the actual
| changes to merge. Sure, it can take a lot of time, but it's
| done once, by you, after all you're supplying the changes.
| And if it takes a really long time, you're doing it wrong in
| the first place by submitting PRs with many LOC.
|
| Have you tried rebasing branches with dozens of short useless
| commits? _That 's_ a real waste of time, and everyone needs
| to do this if you want to update your main branch. So you've
| now multiplied the amount of wasted time for everyone.
| preordained wrote:
| Could not agree more...I wish I had more of substance to add,
| but an upvote didn't feel sufficient
| qudat wrote:
| Agreed but I also think this depends heavily on context. If
| the organization cares a lot of clean commit messages, have a
| nice git history, and want PRs to be submitted in a clean
| state, great!
|
| This is not always the case. I've worked on codebases where
| we rarely scan the git history messages for anything useful,
| it's just as easy for us to dig into the code to figure out
| what's wrong.
| thom wrote:
| Do people here have examples of some bugs for which they had
| to resort to VCS history to find the cause? I'm struggling to
| picture a single bug in my whole career where this would have
| been quicker than just following the logic of the code. If
| there's information in commit messages that isn't evident in
| the code itself, that seems a terrible way to live.
| detaro wrote:
| As parent said, history is not just commit messages.
|
| Trivial example from yesterday: "this worked last week...
| what did they even touch inbetween?", look at the most
| relevant commit diff, context makes it obvious someone just
| accidentally deleted a line too many while replacing a code
| block.
|
| For more complex stuff, it's helpful for "what were they
| trying to do with this line", "what's the requirements
| document they worked off when they wrote this", "which
| other versions are likely to have this bug too", "Is this
| new and I can go ask whoever wrote this about it or is it
| years old", ...
| pizza234 wrote:
| As wrote in another comment, bisecting (which is for me a
| significant tool) relies on history (specifically, a
| granular one). However, it also must a disciplined history.
| thom wrote:
| What's an example of a bug you've had to bisect for
| recently? Forgive me, it just seems like such a last
| resort thing.
| LocalPCGuy wrote:
| I don't bisect regularly, but when I do, it's usually
| trying to figure out what the original reason for
| introducing the code that is problematic is. The entire
| point is on projects big enough, you may not be able to
| just "follow the logic" enough to know that your fix the
| to apparent bug isn't re-introducing some regression that
| was fixed previously.
|
| So bisect to me, is a way to figure out where and why the
| code was changed the way that it was, so I have a better
| understanding of the changes I can make going forward.
|
| That doesn't mean the change made in the past was correct
| and must be maintained (obviously something is broken),
| or that it might be that the obvious solution based on
| following the code logic is correct. But that doesn't
| mean I wasted time making sure I best understand the
| reasoning behind the changes made. But this is also why I
| don't resort to it very often, because it isn't necessary
| in all cases (I'd even say it isn't necessary in most
| cases).
|
| Bisect also allows you to see other changes made in the
| commit in question, and around that commit, so you get a
| better overall picture of the logic.
| Rapzid wrote:
| I agree with you in part, depending on the project, if that
| means just squashing it down first. This at least can keep
| the integration branch somewhat sane and without a bunch of
| intermediate commits that are junk and won't build.
|
| For this reason I prefer people to rebase on the integration
| branch instead of merging it in to stay current; unless there
| is a reason not to. And a lot of open source projects require
| PRs that to be pre-squashed or be able to be squashed before
| merging!
|
| However, there is a time and place still for deliberately
| crafting the PR commits. For instance if you are wanting the
| reviewer to be able to review chunks of the PR in
| isolation/stages, or if you want each of the commits to be
| buildable.. I suppose also for review/testing.
|
| This all depends on the project and other factors like the
| wider org.
| dyeje wrote:
| It's a prime example of engineers mistaking aesthetics for
| utility.
| tablespoon wrote:
| > A complete and utter waste of time. You spend more time
| messing about with rebase than solving problems.
|
| Eh. Not really. A clean history is a good resource for
| figuring out what was changed and _why_. Cleaning up history
| isn 't even that much work anyway.
|
| > When you're digging through VCS history due to a bug you
| often ignore the commit message anyway - if the code did what
| it seemed to do you wouldn't be there.
|
| Only if the commit messages are shitty, which unfortunately
| they often are. I try to summarize what I'm changing and what
| I indent those changes to accomplish, because if there's one
| thing I hate doing, it's spending more time than necessary to
| puzzle out what I (or a coworker) was thinking at the time.
|
| VCS history can be a pretty powerful tool, but a messy
| history discourages the use of it.
| throwaway1777 wrote:
| Strongly disagree. Mainline branch commit history should be
| clean atomic commits that you can roll back. Otherwise you
| are just asking for trouble on any merge conflict or hotfix
| scenario.
| gregmac wrote:
| > A complete and utter waste of time. You spend more time
| messing about with rebase than solving problems.
|
| Unless you're using a garbage client (eg, the git CLI) a
| rebase to get rid of the "typo" "oops" type commits (when you
| forgot something) takes I'd say 10-20 seconds.
|
| Most commonly I do this when I have several changes on the go
| at once and forget to commit a fixed unit test, new import,
| or something like that. I usually realize it right away, so
| my commit will usually be "add test" or "amend 2 commits ago"
| or something to remind myself which one it goes to (and it
| sticks out, because my other commits are usually in the
| format "PROJ-1234: Add new --host command-line option").
|
| > When you're digging through VCS history due to a bug you
| often ignore the commit message anyway - if the code did what
| it seemed to do you wouldn't be there.
|
| I presume this is doing a bisect or something to narrow down
| where a bug was introduced?
|
| My experience comes from the opposite side. Usually I
| identify the line of code causing a bug, it makes me go "wtf,
| what is this even supposed to be doing?" so I do a git blame.
| Hopefully the commit message is useful and ideally leads me
| back to the original bug/ticket, so I can figure out what the
| original intent/fix was, rather than inadvertently breaking
| something (or re-causing a different bug it fixed). I'll also
| note that in code that is well-commented and well-tested,
| this step is rarely necessary.
|
| As an example, say I come across something like this:
| if (port > 443) ignoreErrors = true;
|
| Clearly, this was added to solve some some problem, but even
| without any context it's pretty obviously a _bad_ solution to
| whatever that problem is. Git blame lets me go back to see
| what the original reason /bug was, evaluate if it's still
| relevant and then either fix it properly or safely remove
| this line.
| sethherr wrote:
| > I'll also note that in code that is well-commented and
| well-tested, this step is rarely necessary.
|
| This is the most important line from this comment.
|
| If I'm using blame or bisect, it means I did something
| wrong.
|
| I merge 10 times a day - and if it takes me a minute,
| because I'm slower than you - that means it's ten minutes a
| day. Add the cognitive load of the whole process and the
| added time of explaining it to other team members - 10
| minutes is an underestimate.
|
| I'm going to spend that time writing tests and comments,
| since even you note that they're the better option.
|
| Squash is good enough. I spend my energy improving the
| right things.
| codesnik wrote:
| git CLI isn't so bad for that, why? I do --fixup commits
| all the time, git commit -i gives me all the power to
| reorder, merge and even split commits.
| FalconSensei wrote:
| > My experience comes from the opposite side. Usually I
| identify the line of code causing a bug, it makes me go
| "wtf, what is this even supposed to be doing?" so I do a
| git blame.
|
| If the commit message is something like: PROJECT-
| TICKETNUMBER Description, you can you know... see the
| ticket/issue along with full details and discussions?
| pizza234 wrote:
| > A complete and utter waste of time. You spend more time
| messing about with rebase than solving problems.
|
| I'm also one of those "micro committers".
|
| Because of this attitude, many hundreds pedantic commit
| rebases after, I'm now a better programmer (and I also spend
| next to no time with that type of rebases).
|
| This is because I have now a much higher capacity (and speed)
| of breaking down problems into smaller, self-contained,
| steps.
|
| There is a common understanding that VCs are just storages.
| VCs actually map the mental model of the developer. Having a
| precise, clear, granular VC history has a bidirectional
| relationship with being a precise, granular, clear developer.
| mrkeen wrote:
| > You spend more time messing about with rebase than solving
| problems
|
| Rebase should be quick and straightforward. If it's not,
| you've got bigger problems.
|
| By rebasing, you're taking responsibility for changing the
| codebase as it exists now, rather than how it used to be.
| lifeisstillgood wrote:
| I think you are using got commit log as a form of
| documentation.
|
| I half-agree. I don't agree devs should spend (much) time
| cleaning up their logs as opposed to actually writing docs
| (inline) that help the next person
|
| I do agree that there is rarely a good (even half good)
| _history of decisions_. This is never the Jira / tickets kept
| outside of the system.
|
| But it is also no good abusing the commit log as a form of ...
| journal. (I know that sounds silly but )
|
| I think an actual journal / blog kept by the dev lead will be
| much more useful
| oftenwrong wrote:
| There's definitely value in putting documentation where it
| will be seen. For developers, writing in a code comment or
| commit message is a good bet. If there's an issue, they'll be
| in the code, and they'll be in the commit log, and they'll
| see what you've written.
|
| At times I've been asked to document things in a company
| wiki. Typically nobody reads it and it never gets updated
| when others make changes to the code.
| garmaine wrote:
| > On the other hand, if you kept the history, and if this
| history was clean from the get go, it becomes easy to read the
| commits one-by-one and understand the issue.
|
| Or git-bisect.
| edoceo wrote:
| maybe its not 100% one way or the other?
|
| I love squash for somethings, but not others
|
| today I brought in one big merge, 20+ commits , so don't squash
| it.
|
| but I also have 20 "little fix" branches, with 1,2 commits each
| which I merge all together and squash in as one merge to main.
| sevencolors wrote:
| This is exactly how i run my project.
|
| Amazing that folks get into these "two sides" debate. The
| reality is always a grey area. And you should be flexible
| enough to see the benefits of the different variations. With
| some guidelines on how to make a decision.
| PaulDavisThe1st wrote:
| hah, a big merge. in the next month or so, i will need to
| merge a branch with nearly 500 commits that change more that
| 15k lines of code, under development for more than a year.
|
| but yeah, like your "one big merge", i do not intend to
| squash it (though there are actually some arguments in favor
| that only kick on with a merge of this size).
| codesnik wrote:
| Mandatory squash merge would be very bad, right. But it sounds
| like success of this policy is highly dependent on the code
| size of average PR. I really liked to work at place where
| commits were usually squash-rebased, which got rid of most
| "typo"s, but long lived huge feature branches lived mostly
| usual life. And if possible, some logically atomic and finished
| groundwork parts of feature branches were extracted and squash-
| rebased into master ahead of time, slimming feature branch,
| sometimes to the point that feature branch could be squash-
| rebased too. Git blame was VERY pleasant to work with, and git-
| bisect would actually work if need would arise.
| jtchang wrote:
| > Squash merge has the major disadvantage of getting rid of
| valuable meaningful git history.
|
| There are reasons against it but the real world is messy.
| Developers tend to commit things, recommit, undo, redo, move
| things around. Is this valuable history? It can be but I would
| say 99% of the time it's more valuable to have a good commit
| message about what was intended rather than what actually
| happened.
|
| The idea of squash merge is to make the history clean from the
| get-go as you said.
| eximius wrote:
| If only there was a way to have our cake and eat it too.
|
| I'm assuming there is because I'm assuming those squashed
| commits are floating somewhere in the reflog and somehow
| connected to the squashed commits in a way that should still
| let you bisect if only we had a tool to make it not suck.
|
| Alas, maybe someone with greater git-fu can inform us.
| waffletower wrote:
| There are, as I answered separately:
|
| `git log -p --first-parent`
| rubyist5eva wrote:
| In the article he says he keeps the original branch with all
| of the history around after they squash them with a reference
| to the original PR in the squashed merge commit message. So
| you can always just checkout the original branch and go
| digging in the full history.
| waffletower wrote:
| Unwieldy to keep branches around even on moderate sized
| teams/projects. You don't need them to have a `squashed`
| view of history when needed. I am surprised that developers
| still cling to this outdated squashing regimen when pull
| request tools found on github, gitlab, bitbucket etc.
| already provide synthetic squash views derived from atomic
| commits by default.
| rubyist5eva wrote:
| How is it unwieldy? They don't even show up locally when
| you `git branch` unless you've checked them out.
| Otherwise they just sit there doing nothing, there is
| literally no maintenance required on them once they've
| been squashed into mainline. Most central repositories
| end up having hundreds (or even thousands) of "finished"
| branches that nobody ever looks at anyway.
| waffletower wrote:
| Depends on configuration if you wind up having that many.
| I use `git branch -v` often to figure out what branch a
| colleague is working on. I guess I could apply my same
| logic and use filtering tools here as well. But I don't
| see the benefit of squashing the merge commits when git
| CLI, github etc. can give you the same view without the
| gratuitous data loss.
| scott0129 wrote:
| I would agree with your points if not for the fact that "clean
| up commits" or "typo fix" is a necessary result of PR's.
|
| Your teammate will request changes in your code, and the only
| way to cleanly communicate "yes I made that change, and ONLY
| that change" is through these clean-up commits.
|
| Otherwise, if you amend/force-push or open an entirely new PR,
| 99% of the diff are things that your team has already seen and
| reviewed.
|
| Squash merges let you clearly communicate how you addressed PR
| comments, while also keeping the master history clean.
| mrkeen wrote:
| I don't mind this. I want my reviewers to look at the state
| of the new code - not the diff, and not the diff of the diff.
|
| Address PR comments using the PR comments.
| jcelerier wrote:
| > Otherwise, if you amend/force-push or open an entirely new
| PR, 99% of the diff are things that your team has already
| seen and reviewed.
|
| gerrit has solved this issue for years by showing the diffs
| between each successive revision of a patch.
|
| e.g. look here the files at different origin patchsets :
| https://codereview.qt-
| project.org/c/qt/qtwayland/+/321246/3....
| jonhohle wrote:
| This was a feature of ReviewBoard as well. The history of
| code review changes was maintained by the tool separately
| from commit history.
| pjc50 wrote:
| It took me a while to get a workflow that actually works
| with Gerrit, and I occasionally think of trying to do some
| kind of autosquash so I can have successive commits
| locally. In practice I just use --amend all the time.
|
| Careful use of setting upstream and of course pull=rebase
| makes keeping up with trunk manageable.
| leafmeal wrote:
| Fixup commits are a good way to work around this.
| https://git-scm.com/docs/git-commit#Documentation/git-
| commit...
|
| You still create your "clean up" commits, but it's done in a
| way where git can automatically squash everything back
| together in the end.
|
| See also https://git-scm.com/docs/git-
| rebase#Documentation/git-rebase...
| maxioatic wrote:
| Huh, never knew about this. Seems quite useful. Thanks!
| ginja wrote:
| I do agree that PRs should have a clean history. However:
|
| - Services like GitHub allow you to restore the original
| branch, so you never actually lose history. So I don't see any
| major drawbacks of squashing on merge.
|
| - If your PRs are several thousand lines long, they probably
| should've been broken up into multiple PRs (your reviewer will
| appreciate it)
| pizza234 wrote:
| > - Services like GitHub allow you to restore the original
| branch, so you never actually lose history. So I don't see
| any major drawbacks of squashing on merge.
|
| There's definitely a drawback, and it's bisecting, which is
| actually a big deal.
|
| Bisecting allows in a semi-automated (depending on the issue)
| bisecting what otherwise can be a large diff.
|
| But of course, it requires a disciplined history - otherwise,
| bisecting just won't work.
| marcinzm wrote:
| Can't you just bisect twice. Once to find the PR and a
| second time within the PR's branch?
| finnh wrote:
| Spot-on for both counts. Preserving a PR's individual commits
| in the master branch is insane - many of those commits won't
| represent a fully working system anyway, so why keep them in
| master?
| sjoruk wrote:
| > many of those commits won't represent a fully working
| system anyway
|
| This is entirely within the control of the developer(s)
| working on the project. Whether it's worth it is up to the
| people working on it. It's certainly not insane though -
| it's much easier to fix merge/rebase conflicts when each
| commit is small and easy to reason about.
| finnh wrote:
| > it's much easier to fix merge/rebase conflicts when
| each commit is small and easy to reason about.
|
| I agree, but I'd say it in the context of PRs. It's much
| easier to fix issues (and avoid them) when _PRs_ are
| small & easy to reason about.
| asimpletune wrote:
| Hey, so this POV comes up a lot, and I have to say that I think
| it mistakes how git commits _should_ work, but I'll add that
| you can sort of have both.
|
| First, in a production branch, git commits should be thought of
| as functions. Like "Apply commit X, get feature Y, unapply it
| and you get the reverse". So the problem with preserving full
| git history in master is that it breaks that invariant. You
| have to sort of do like a range of commits, but then that
| doesn't really always work because often times other commits
| can be interleaved into yours.
|
| To understand how I mean, just look at Linux or open source
| software projects, where the technical experts are more or less
| gatekeepers and aren't accountable to any other influence.
| You'll find that commits work this way, and their history is
| squashed. (Maintainers will also force you to rebase before
| merging and basically put all the work on you to get the PR in
| ship shape, which is a lot different from a corporate
| environment)
|
| Ok, but then to your point about preserving valuable, more
| granular commits, well, the solution is you just leave that
| remote branch up, either in your fork or elsewhere (but
| probably in your fork). These branches should have formal names
| identifying a ticket (at work) or an RFC or whatever, so it
| should be easy for people to discover what happened. They can
| see this remote issued a PR to this remote to implement RFC-123
| or whatever, and they can go to that remote and see the
| granular commits if you preserved.
|
| Sorry, this is like a never ending debate and there are very
| strong opinions, but I sincerely think that in this situation
| there is actually a right answer. People who already know how
| to do this or are super familiar with open source, maintainers
| or team leads or whatever, I think don't see the point in
| fighting over it, since they can just enforce whatever they
| want in their gatekeeper role. However, the truth is that
| there's sort of a fundamental misunderstanding that the
| majority of the population has around git and I think it's
| better to engage and explain when you get the chance.
| cortesoft wrote:
| > When you squash merge a feature branch that has thousands of
| lines of code, and 6 months later you have a bug introduced by
| this feature branch, it becomes extremely hard to find which
| line introduced the bug.
|
| So, the only way that I can think that having the squash commit
| broken into individual commits would help to find the one
| broken line is because it would enable git bisect to find the
| failing commit.
|
| However, that implies that each individual commit inside that
| feature branch worked on its own. If that is the case, a better
| suggestion would be to break up the giant feature branch into
| smaller sub features that can be merged as they are completed
| [deleted]
| Ozzie_osman wrote:
| > When you squash merge a feature branch that has thousands of
| lines of code, and 6 months later you have a bug introduced by
| this feature branch, it becomes extremely hard to find which
| line introduced the bug.
|
| I try to avoid feature branches with "thousands of lines of
| code" on most of my teams, and have been pretty successful.
| Those types of feature branches create a lot of other problems.
| On the other hand, small, incremental pull requests that get
| merged back to master and have really short lifespans, along
| with things like feature flags to decouple delivering code from
| delivering functionality have worked really well.
|
| In this world, squash merges are awesome, because any squash
| merge is basically a "commit" in the other world, and
| developers can feel free to commit however they want within the
| branch.
| FalconSensei wrote:
| I love squash-merge, and never had to see which specific commit
| inside a PR/MR changed a line. In my current project we use
| `JIRA-### Title` and the MR title (Gitlab). All information is in
| the ticket. Also, IF I needed to see the detailed commit history
| for that merge, Gitlab still has it. We try to have our ticket to
| be small, so any merge shouldn't have a long commit history
| anyway.
| deathanatos wrote:
| Squash & merge is objectively worse than rebase && merge --no-
| ff.1 (Roughly what the article calls "no fast-forward".) "No
| fast-forward" meets all of the criteria the article's author
| proposes:
|
| > 1. Combines all the code changes related to a single logical
| change
|
| Yes: the merge commit is that.
|
| > 2. Provides an explanatory commit message that helps people
| understand the intent of the change
|
| This is no more or less true that squash & merge. (Although, I
| don't off the top of my head remember how good the automatic
| message in Github is.) But that's more a problem of an automatic
| message than it is the merge strategy, & squash and merge also
| has this. (I've seen numerous squash commits with "Fix CI, Fix
| CI, Code formatting, Fix Lint warning" in them...
|
| Good commit messages boils down to the discipline of the coder.
| (And a reviewer being able to say, "Can you write a better commit
| message?".)
|
| > 3. If you pick this commit independently from the history, it
| makes sense on its own
|
| The merge commit.
|
| What you lose with squash & merge is the history. The author does
| sort of address this:
|
| > _In case you are wondering if we are losing the individual
| changes, the answer is no. Each squash merge references back to a
| PR where the whole changes are tracked:_
|
| And while this is technically true, it's a reference only in the
| textual message (which Github will nicely turn into a link, but
| you must be in Github for that). "No fast-forward" will maintain
| those references in the git commit parent information, which
| means that tooling like git bisect should be able to see into it.
| But with a squashed commit, the closest you get is "some commit
| in this PR", essentially. Same with reverts: if just one commit
| on a feature branch is bad, you can simply revert that one
| commit. (Or, if most of the branch is bad, you can revert the
| merge commit & cherry-pick the good bits.)
|
| If you don't want to see all the feature branch commits in the
| history, you can just follow first parents.
|
| 1I prefer a quick rebase prior to merge but after code-review, as
| it is a good balance between the resulting history being
| readable, and not rewriting history while your reviewer is
| looking at it. But the argument here should hold regardless; the
| definition the article uses is sufficient, too.
| hmsimha wrote:
| This is great! The takeaway for me is that with squash merge you
| get one commit with all the changes which (optimally) has the
| full context in the commit message.
|
| My typical workflow is basically the same, but with putting all
| that context in the merge commit. This allows you to find it with
| a bit of work (blame to find the commit line, then figure out
| where that was merged in, then find the merge commit). Squash
| merge puts all that context in one commit, and keeps a linear
| history. I had assumed squash merge squashes the commits, then
| creates a merge commit still, which would mean you'd probably do
| something like combining messages for each commit in the squash
| commit message, then capturing the overview in merge commit.
|
| The article says you can still find the individual commits via
| PR, which is a minor disadvantage as it means you can only do
| exploration of these via github. If you've deleted the topic
| branch on github are they still accessible? If it's been garbage
| collected by git (or never existed locally if you're looking at
| someone else's changes), is there a way to check them out?
| decebalus1 wrote:
| The older I get the more I find these discussion as
| counterproductive as figuring out where to put the bike shed.
|
| I worked in teams that did squash merge and in teams that didn't.
| And in teams where some did and some didn't, on the same repo. In
| the grand scheme of things it didn't matter, except for
| hardliners who had nothing better to talk about.
| allenu wrote:
| Yep, I agree. In my ideal world, everybody (including me) would
| have pristine commits that are broken up logically. There
| wouldn't be small commits created as part of code review to fix
| things up based on feedback. You'd just have a single "Add
| feature X" or "Fix bug Y".
|
| However, it's an imperfect world and there are trade-offs. It's
| hard to train people to do things the right way, and then
| policing when they do it the wrong way or putting roadblocks in
| place to make them do it the right way takes energy, and often
| the benefit is minor. It really depends on how frequently you
| pore through your history to find an offending bug and a whole
| bunch of other team policy that isn't directly related to git
| commits.
|
| I used to spend a lot of energy rebasing so that I could have a
| beautiful history, but honestly it hasn't benefited me that
| much. I still rebase, but I'm not so strict about it on my
| commits, nor others. I'd rather spend my focus and energy
| elsewhere.
|
| Just do what the team is comfortable with and be flexible.
| jakeva wrote:
| > figuring out where to put the bike shed.
|
| Anyway, the _real_ question is what color to paint the bike
| shed?
| scubbo wrote:
| I agree with your point, but, tangentially, I do find it
| amusing that "where to put the bike shed" is actually _more_
| impactful than what I thought "bike-shedding" referred to
| (arguing about what _colour_ to paint the bike shed for a
| nuclear reactor). At least the location of the bike shed
| actually has some (small) effect on people's commute!
| bob1029 wrote:
| I file this one under: It Depends(tm)
|
| If your software development process requires that multiple
| people have a hand in each pull request, or these pull requests
| are part of a more complex merge graph, then I can clearly see
| the argument for NOT doing squash merge. This is plainly obvious
| to me and I would be on your side for not going down the squash
| path. Knowing who was responsible for each part is a very
| important thing.
|
| If your software development process only ever has a single
| author per pull request, and these are only ever directed from
| work branch->master branch, then I would strongly argue for doing
| the squash merge option. This is what we do today, because we
| find it to be the ideal blend of hiding subjective commit styles
| while still preserving essential knowledge about who did what.
|
| Occasionally, we will break our own rules (oops i didn't squash
| that one), but we don't make a big deal out of it. There are way
| more important things to worry about most of the time. There is
| only ever 1 specific commit hash you build your software at, so
| it doesn't really matter if the branch has 1 or 10,000 commits in
| it.
| waffletower wrote:
| Many developers naively sell `git squash` using a clarity
| argument. By squashing you lose historical information: there are
| times when the content of a merge requires a paper trail, times
| when individual commits can aid to separate the portions of a
| merge you would like to keep versus those you would like to
| rollback. Perhaps in a 10 times a day release regimen you decide
| never to look for such history. One size does not fit all,
| however.
|
| I prefer a "have your cake and eat it too" approach. Keep the
| commit history. Use readily available tools to squash when
| performing analysis should you choose:
|
| `git log -p --first-parent` (git 2.31+ ability available in early
| versions of git with different syntax)
| Pxtl wrote:
| Squash was the thing that convinced me that the emperor has no
| clothes. Realizing that I was going to either have to train every
| junior, every four-month community-college student brought in on
| co-op to modify their history in an awful UI with tons of
| gotchas, _or_ I would have to accept the downsides of squash?
|
| It's so stupid.
|
| Git desperately needs a layer above the commit that groups
| related commits together into a semantically commit-like object
| that you can show in history and jump to its HEAD and cherry-
| pick. Because the squash is a dumb hack, and meticulously editing
| your history is not productive work.
|
| I want squash. But I want squash without all the boneheaded
| implementation-detail downsides of squash. I want squash where I
| can put up a PR and keep working and then not have to deal with
| the cherry-pick pain if I want to build off that work after it
| merges. I want squash where I can leave the branch up after the
| merge and still see that it's behind the main branch.
|
| But git's simple "everything is a commit" model makes that
| impossible.
| eMGm4D0zgUAVXc7 wrote:
| > Git desperately needs a layer above the commit that groups
| related commits together into a semantically commit-like object
| that you can show in history and jump to its HEAD and cherry-
| pick.
|
| It's called a "branch" :) The commit-like object to represent
| it is the merge commit.
|
| If you need to group related things in a branch in a more fine-
| grained fashion then do sub-branches and merge them into the
| branch with "--no-ff" so you get a merge commit for each to
| describe them.
| operator-name wrote:
| Can't you achieve something similar with `--no-ff` and tags?
| Qerub wrote:
| It would be nice if GitHub allowed comments on commit messages
| and not only the changes so that they could be discussed for the
| benefit of learning and improvement.
|
| Squash merge commit messages are currently not reviewable at all
| since they are not entered until just before the merge.
|
| I'd prefer for nothing at all to be able to enter the main branch
| without review, if not for anything else to protect myself
| against my own mistakes.
|
| Guess I should give Gerrit a shot.
| f154hfds wrote:
| My org has started to strongly recommend squashing before merging
| (in my opinion one step less extreme than the forced squash-merge
| mentioned in the article). I tend to consider this a decent
| principle in general but rules are made to be broken.
|
| My main concern is if anyone ever commits based off of a pre-
| squashed branch. They won't be able to simply merge upstream
| after their parent has been squashed, they will now have to
| cherry-pick or incur strange redundant merge conflicts as they no
| longer share history.
|
| For a small team whose features tend to be short-lived before
| going upstream this won't likely be a problem but believe me, if
| you ever need long-lived feature branches on a larger team,
| squashing them can cause more trouble than your nice history will
| gain.
| tediousdemise wrote:
| My old team's git workflow required us to rebase our feature
| branches to develop before merging, and our branch could only
| contain a single commit. The commit needed a special formatting
| (short title, description, and story number) so it would get
| picked up by Jira scripts.
|
| Although the history was super clean, the extra upkeep was a
| small annoyance. I felt like tearing my hair out when there were
| 10 other merge requests pending and never knew which would be the
| next to merge with develop. An auto-rebase feature (assuming no
| merge conflicts) would have saved me countless pointless minutes.
| nickbauman wrote:
| Generally, time spent twiddling with the repo is time not spent
| delivering code. It's a distraction. Yes git has all these
| features that lets you do that and those feature matter when
| you're committing to the Linux repo which has thousands of eyes
| and your commit history has to help you communicate to a very
| wide audience. But the vast majority of us are not using git like
| this. I've used git bisect so rarely all this is overkill.
| gouggoug wrote:
| - Generally time spent writing documentation is time not spent
| delivering code.
|
| - Generally time spent commenting code is time not spent
| delivering code.
|
| - Generally time spent diagramming on a white board is time not
| spent delivering code.
|
| - Generally time spent writing specs is time not spent
| delivering code.
|
| Yet, doing all of these are actually extremely important. How
| much importance you give each one of them is up to you that's
| for sure.
|
| So, "Generally, time spent twiddling with the repo is time not
| spent delivering code", is true, it's nonetheless important,
| and, this statement disregards the fact that "twiddling"
| usually only takes a few minutes.
| bonzini wrote:
| Time spent twiddling with the repo is time saved in the future
| debugging or writing documentation.
|
| You can have large refactoring PRs for which splitting them
| further really makes little sense(*), but that have a huge risk
| of introducing regressions. Being able to bisect them is much
| easier with a properly maintained repository.
|
| (*) And then you spend time twiddling with GitHub, which is the
| same as twiddling with the repo except with worse tools.
| wbronchart wrote:
| I love clean linear history, but I don't like squash&merge, and I
| don't like the other options that the github interface gives you
| either.
|
| Plug: I wrote a script recently that merges github pull requests
| but preserves linear git history (basically, rebase + merge)
|
| https://pypi.org/project/git-pr-linear-merge/
___________________________________________________________________
(page generated 2021-04-30 23:01 UTC)