5 ms·
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 r
by waffletower 5y ago
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)
- tharkun__ 5y agoI would argue that you only loose irrelevant information and you gain the ability to rollback. Without squashing, you are actually way worse off for a "10 times a day release regimen". We release every hour and we squash and rebase with a straight master history. This enables us to almost mechanically just roll back to the previous commit that was out on Prod, should something happen and it's very easy to skip (revert) just one ticket and let the rest go out. No guessing, no manual figuring out which 7 commits belong to the ticket in question, potentially 6 of them had the ticket number in the commit message like they should, but the 7th, which coincidentally is actually commit number 3 in the sequence but interleaved with other ticket's commits the developer switched some numbers and instead of ticket ABC-123 he wrote ABC-132. Now we have a production incident and a completely garbled attempt to undo it. We have none of those issues. Each ticket is one commit. If you revert one commit, you are guaranteed to have a working piece of software and you won't have a potentially not even compiling intermediate commit that was subsequently fixed up during a PR, which can happen without squashing.
- gouggoug 5y ago>No guessing, no manual figuring out which 7 commits belong to the ticket in question, potentially 6 of them had the ticket number in the commit message like they should, but the 7th, [...] Lots of people it seems don't know this: _you can revert a merge commit_, which includes _all_ the commits that were part of the merge. So, if you have a feature branch with 7 commits, you merge those 7 commits _with a merge commit_, if you need to rollback, you rollback _the merge commit_, which includes all 7 commits.
- jka 5y agoThe fact that not many people know this unfortunately leads to a side-effect that it is less widely supported by third-party tooling around git. In terms of simplicity (for example, 'git revert x' is natural-language-like and expresses the intent and meaning), and also in terms of tooling compatibility, that generally leads me to prefer squash commits. One other thing that squash commits can enable is a sense of developer freedom within their branch(es). There's no need to keep the history super hygienic within each branch; there can be plenty of reverts, experimental commits, etc; the eventual merged product ends up looking clean regardless.
- u801e 5y agoBut if only 1 of the 7 commits was actually the cause of the issue, then why would you want to revert all 7 of them instead of just the one?
- tharkun__ 5y agoIf you have 7 commits it's very likely that 3 of those commits at least don't build because they were intermediary checkpoints. Then there's the one commit that contains the buggy code and if you revert that it breaks the whole thing and it doesn't work. Now you gotta revert the whole thing anyway, all 7 commits (or the merge). Why bother with all this time and energy? If each single commit in your straight master history is one self contained thing it's easy to revert that whole thing and done. We are also talking SaaS here with releases going out multiple times a day. So if something is very broken it's likely to be noticed very quickly and the breaking change is probably the last commit on master and you don't even have to revert it. You just deploy HEAD^ to Prod while you create a PR to fix the problem.
- u801e 5y agoOne can ensure that every commit passes the tests suite and linting by running something like: git rebase --exec "test_cmd" --exec "lint_cmd" base_branch and any commit that doesn't pass can be fixed until you get to the point where all commits in the branch pass. Then you can find the commit that caused the issue, revert it and then make another commit that fixes the issue in the next PR (and ensure that the test suite passes for both commits with the --exec parameter to rebase. > If each single commit in your straight master history is one self contained thing it's easy to revert that whole thing and done. Not really. The more lines and files that are affected by applying the commit, the more likely there will be conflicts when trying to revert it. While that won't be the case if the commit (or merge commit) is the current head of the branch, but if other commits and merges have been made since then, then conflicts are fare more likely. On the other hand, smaller commits are much easier to revert because they tend to not change many files or many lines of code. > We are also talking SaaS here with releases going out multiple times a day. So if something is very broken it's likely to be noticed very quickly That's assuming that it's "very" broken and it's noticed quickly. Those assumptions don't always hold.
- vikingcaffiene 5y ago> Each ticket is one commit. If you revert one commit, you are guaranteed to have a working piece of software and you won't have a potentially not even compiling intermediate commit that was subsequently fixed up during a PR, which can happen without squashing. This is the key point and I liked it so much that I bookmarked it. Hope you don’t mind. :) I frequently have to debate with my teammates on the value of squash merging into our mainline branches. Another value add that squash merge brings is that it enables what I call “accidental documentation”. You get a easy to parse log of work that was done and a link right to the PR with a description and any discussion around it. As a lead I frequently need to coordinate teammates and communicate technical decisions. It’s invaluable to be able to just pull up the commit log and go right to the work in question without having to wade through a bunch of noise. It also helps a ton with writing release notes.