Using Git is like eating olives. First you think it sucks, then you try it a bit, next thing you know you’re at a party swilling Musigny and pounding Kalamatas like they’re going out of fashion.

I personally have committed some of the worst sins possible with the Gits. I’ve been yelled at on team projects, have done things with the pull command which I’m sure Linus never intended, and have merged branches which should never, ever, be merged. But over time I’ve come to respect Git for what it is – a way to tell the story of your project source and how it has evolved over time.

So let’s jump into storyteller mode. At present I am working in a large team which has a Git repository with a number of contributors. For this reason it’s important to maintain a level of discipline when committing, as when the number of users increases, the tolerance for ambiguity in commits (both content and messages) changes in an inverse manner. Consider the following git history scenario:

All those "WIP" commit messages don’t tell the reader much of what has been going on in that repo. What would be much better would be to squash them into one meaningful commit, with a well worded commit message. Enter git’s interactive rebase (aka: rebase -i). Interactive rebase allows us to ‘alter’ the history of a git repo by performing a number of changes, including removing commits, squashing commits and changing commit messages. In this case, to squash the 4 "WIP" commits into one meaningful commit requires just one simple command line command:

$ git rebase -i [sha of the commit prior to the first commit you wish to squash]

so specifically:

$ git rebase -i 3bea...

performing this will open your elected git text editor, presenting the following:

pick fg97... WIP
pick a21c... WIP
pick 996p... WIP
pick nj46... WIP
# Rebase 75a4a84..e1bcaba onto 75a4a84
#
# 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
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
#
# However, if you remove everything, the rebase will be aborted.
#
# Note that empty commits are commented out

All we have to do now is follow Linus’ instructions, and replace the word pick with squash for all the commits except fg97... and then save and close the document. Git will work its magic, will present you with a commit message editor again where you can now add a new “squashed” commit message and hey presto!, you now have a nice looking repo with a nice looking history:

Persevere with Git – it’s worth it! There are fantastic docs over at Git-SCM so you can try using the command line; with persistence you’ll find it’s 100x better than Sourcetree or GitHub’s Git UI.