Introduction: Thoughts on git merge –squash
More and more I’m squashing when I merge my git branches. I’ve been using this at my day job for about a month, and have some thoughts.
I think there’s some benefit here:
- easy change log creation
- easy to roll back an entire feature
- I feel we’ve gotten better with “Scrum Bookkeeping”: We have a format for our single commits: “OJIRABOARD-42: blah blah ticket title”. Makes it easy to correlate some work with a ticket, and if you spent half a day doing something extra, well create a ticket or pull that ticket you did into the sprint. (Get points for that work you did!)
git bisectis now possible- same clean “no merge bubbles” result as you’d get with aggressive
git rebase-ing, except nobody has to actually rebase
I’ve also noticed some disadvantages:
- you now have no good way of tracking when individual commits happen (which is a problem I have with
git rebasetoo: if you have to go back to the Git logs to prove your billable hours, it just isn’t possible. (Yes, actually happened to a teammate a four or five years ago) - We don’t have the Big Squash Merge Button in our Github Enterprise install, so merging is by hand.
- I think our pull requests have gotten bigger. Maybe because of the ceremony around Scrum Bookkeeping, that we know it’s a pain to merge these, or maybe it’s just settling into a new codebase (which we are).
- … but this Scrum Bookkeeping falls down a bit if you need to make a QA related change to a feature you’ve already merged. (make a new ticket? have TWO commits about OJIRABOARD-42 ????)
Fixing git merge –squash: Introducing git squash-check
So my normal squashing workflow is:
$ git checkout master
$ git merge --squash mybranch
$ git commit -am "OJIRABOARD-42: Yoddle"
There’s a problem here: merging by hand means that things can theoretically change between your code in the branch and the code you committed to master. Because git merge --squash dumps all your changes from that branch into your working directory, you can change things at will. This is usually not what you want.
Maybe you squashed into a dirty working copy, or somehow deleted a file. You can’t be sure your commit is accurately the code that was in the branch and got reviewed (especially since you did it with -a, which I normally don’t use… except there’s no way could this commit and the branch be different. Welcome to computer science, where the more you swear it’s not possible… well it is.
NO MORE UNCERTAINTY, I have a tool for that!
$ git checkout master
$ git merge --squash mybranch
$ echo "booo" > super_important.js
$ git commit -am "OJIRABOARD-42: Yoddle"
$ git squash-check mybranch
Files /tmp/branch_to_head and /tmp/commit_to_head differ
SOME DIFFERENCES WERE FOUND!
124a125,127
> diff --git a/super_important.js b/super_important.js
> boooo
< all.the.source
NO GOOD, STOP! commits are different, did something extra get in?
Thanks, git squash-check!