Aaron M. Rice

Better squashing with git merge-base

If you’re in the git situation where you want to rebase your working branch onto an updated master and you also want to squash your branch’s commits, it is to your advantage to squash before you rebase. Intuitively, if you squash a bunch of commits into a single one, you’ll have fewer & better conflicts (or at least no worse) to resolve when the commit is applied to a new base.

If you merely invoke git rebase -i master, git will rebase and then begin applying all of your commits, potentially forcing you to deal with conflicts that wouldn’t have come up while applying your squashed commits to the new base.

The invocation git merge-base HEAD master will return the hash of the base commit shared by both master and your branch, the branch base before you rebase.

To squash your branch’s commits first, you want to git rebase -i onto your base’s original branch, i.e. git merge-base HEAD master. In your shell, you’d type something like git rebase -i $(git merge-base HEAD master). This lets your squash your commits without changing the base first. Then you can follow up with a simple git rebase master to pull your squashed commits to the newest master.

To put it all together, what you probably want to use to squash and rebase:

git rebase -i $(git merge-base HEAD master) && git rebase master

or its slightly shorter equivalent:

git rebase -i $(git merge-base @ master) && git rebase master