The so-called writings of Michael Gorsuch.

Squashing Git Commits

All too often while modifying some chef recipe, I make commit after commit after commit. Many times my local branch’s commit messages look a little like this:

commit 473c878c8bf249a474da9faf57333288aaa0d22f
Author: Michael Gorsuch <michael.gorsuch@gmail.com>
Date:   Mon Mar 21 16:53:10 2011 -0500

    recipes[apache2]: crap. typo.

commit 27bda2b580c8fb697615fca84933d2f89d26c70b
Author: Michael Gorsuch <michael.gorsuch@gmail.com>
Date:   Mon Mar 21 08:58:40 2011 -0500

    recipes[apache2]: added ability to generate sites based on attributes

...

I don’t like merging that sort of mess back in to the main branch, as it can cause some headaches when you have a large team that would rather be doing other things than watching you backtrack all over the codebase.

A colleague asked me to check into git’s rebase functionality. What I found was scary but ever so useful.

Let’s squash these commits together, making it look as if the typo had never occurred.

Use the following command:

$ git rebase -i HEAD~2

-i tells git to use interactive mode, i.e. launch $EDITOR, and HEAD~2 is more or less saying get the past two commits.

When I run this, VIM gives me the following:

pick 0259fff recipes[apache2]: added ability to generate sites based on attributes
pick ad68659 recipes[apache2]: crap. typo.

# Rebase be9f5a0..ad68659 onto be9f5a0
#
# Commands:
#  p, pick = use commit
#  r, reword = use commit, but edit the commit message
#  e, edit = use commit, but stop for amending
#  s, squash = use commit, but meld into previous commit
#  f, fixup = like "squash", but discard this commit's log message
#  x, exec = run command (the rest of the line) using shell
#
# If you remove a line here THAT COMMIT WILL BE LOST.
# However, if you remove everything, the rebase will be aborted.
#

Let’s go ahead and do a fixup here, pretending that this change never happened. Just change the top two lines to look like so:

pick 0259fff recipes[apache2]: added ability to generate sites based on attributes
f ad68659 recipes[apache2]: crap. typo.

Now if you exit out of vim, your change will take place. Look at the commit log now:

commit 8654333d73b46f93ae111b40986dff8329b813a2
Author: Michael Gorsuch <michael.gorsuch@gmail.com>
Date:   Mon Mar 21 08:58:40 2011 -0500

    recipes[apache2]: added ability to generate sites based on attributes
...

Fixed and you look more perfect than ever.