The main reason from what I can see is as follows:
- The GitHub UI for merging pull requests currently (Oct 2015) does not allow you to edit the first line of the commit message, forcing it to be
Merge pull request #123 from joebloggs/fix-snafoo
- The GitHub UI for browsing the commit history currently does not allow you to view the history of the branch from the
--first-parent
point of view
- The GitHub UI for looking at the blame on a file currently does not allow you to view the blame of the file with the
--first-parent
point of view (note that this was only fixed in Git 2.6.2, so we could forgive GitHub for not having that available)
So when you combine all three of these situations above, you get a situation where unsquashed commits being merged look ugly from the GitHub UI.
Your history with squashed commits will look something like
1256556316... Merge pull request #423 from jrandom/add-slideshows
7hgf8978g9... Added new slideshow feature
56556316ad... Merge pull request #324 from ahacker/fix-android-display
787g8fgf78... Hotfix for android display issue
f56556316e... Merge pull request #28 from somwhere/select-lang-popup
9080gf6567... Implemented pop-up to select language
Whereas without squashed commits the history will look something like
1256556316... Merge pull request #423 from jrandom/add-slideshows
7hgf8978g9... Added new slideshow feature, JIRA # 848394839
85493g2458... Fixed slideshow display issue in ie
gh354354gh... wip, done for the week
789fdfffdf... minor alignment issue
56556316ad... Merge pull request #324 from ahacker/fix-android-display
787g8fgf78... hotfix for #5849564648
f56556316e... Merge pull request #28 from somwhere/select-lang-popup
9080gf6567... implemented feature # 65896859
gh34839843... minor fix (typo) for 3rd test
When you have a lot of commits in a PR tracing where a change came in can become a bit of a nightmare if you restrict yourself to using the GitHub UI.
For example, you find a null pointer being de-referenced somewhere in a file... so you say "who did this, and when? what release versions are affected?". Then you wander over to the blame view in the GitHub UI and you see that the line was changed in 789fdfffdf
... "oh but wait a second, that line was just having its indent changed to fit in with the rest of the code", so now you need to navigate to the tree state for that file in the parent commit and re-visit the blame page... eventually you find the commit... it's a commit from 6 months ago... "oh **** this could be affecting users for 6 months" you say... ah but wait, that commit was actually in a Pull Request and was only merged yesterday and nobody has cut a release yet... "Damn you people for merging commits without squashing history" is the cry that can usually be heard after about 2 or 3 code archeology expeditions via the GitHub UI
Now let us consider how this works if you use the Git command line (and super-awesome 2.6.2 which has the fix for git blame --first-parent
)
- If you were using the Git command line, you would be able to control the merge commit message completely and thus the merge commit could have a nice summary line.
So our commit history would look like
$ git log
1256556316... #423 Added new slideshow feature
7hgf8978g9... Added new slideshow feature, JIRA # 848394839
85493g2458... Fixed slideshow display issue in ie
gh354354gh... wip, done for the week
789fdfffdf... minor alignment issue
56556316ad... #324 Hotfix for android display issue
787g8fgf78... hotfix for #5849564648
f56556316e... #28 Implemented pop-up to select language
9080gf6567... implemented feature # 65896859
gh34839843... minor fix (typo) for 3rd test
But we can also do
$ git log --first-parent
1256556316... #423 Added new slideshow feature
56556316ad... #324 Hotfix for android display issue
f56556316e... #28 Implemented pop-up to select language
(In other words: the Git CLI lets you have your cake and eat it too)
Now when we hit the null pointer issue... well we just use git blame --first-parent -w dodgy-file.c
and we are immediately given the exact commit where the null pointer de-reference was introduced to the master branch ignoring simple whitespace changes.
Of course if you are doing merges using the GitHub UI then git log --first-parent
is really crappy thanks to GitHub forcing the first line of the merge commit message:
1256556316... Merge pull request #423 from jrandom/add-slideshows
56556316ad... Merge pull request #324 from ahacker/fix-android-display
f56556316e... Merge pull request #28 from somwhere/select-lang-popup
So to cut a long story short:
The GitHub UI (Oct 2015) has a number of shortcomings with how it merges pull requests, how it presents the commit history and how it attributes blame information. The current best way to hack around these defects in the GitHub UI is to request people to squash their commits before merging.
The Git CLI doesn't have these issues and you can easily choose which view you want to see so that you can both discover the reason why a particular change was made that way (by looking at the history of the unsquashed commits) as well as see the effectively squashed commits.
Post Script
The final reason often cited for squashing commits is to make backporting easier... if you only have one commit to back port (i.e. the squashed commit) then it is easy to cherry pick...
Well if you are looking at the git history with git log --first-parent
then you can just cherry pick the merge commits. Most people get confused cherry picking merge commits because you have to specify the -m N
option but if you got the commit from git log --first-parent
then you know that it is the first parent that you want to follow so it will be git cherry-pick -m 1 ...