Note to self: comparing two branches in git and squashing several commits into one

June 2nd, 2009

I always forget how to do this so I’m writing it down (especially as it’s really easy and git, as usual, makes me feel stupid as Linus is so much smarter than me).

Suppose you’ve been working in branch X and you’re about to merge those changes into branch Y …

  • work in branch X and make your commits as needed
  • switch to branch Y git checkout Y
  • compare the differences between X and Y git log Y..X – the order here is important; it is merge-target..merge-source
  • merge the changes from X (merge-source) into Y (merge-target) git merge X

Even better, before doing the merge, while you are still in branch X, you can squash multiple commits into a single one. This way, branch Y, when you examine the log, has a single entry “implemented feature X”, instead of thirty-five entries all related to feature X in some way.

  • examine the log git log or even better git log --pretty=oneline
  • choose the commit that immediately precedes the one that starts your piece of work (probably the last one before you branched to start work on feature X)
  • start an interactive rebase session – this is git-fancy-talk for picking some commits and typing a message – git rebase -i THE-COMMIT-ID-OF-THE-COMMIT-YOU-SELECTED-ABOVE
  • Your favourite editor (or nano) will open listing the commits for feature X – edit the word “pick” to “squash” for all except the top entry, save and exit
  • Your favourite editor will open again – again showing your commit messages – add a line at the top stating something like “implementation of feature X” and leave the list of individual commits on separate lines below it (adding in a Fixes #123 or whatever your issue tracker demands as the last line), save and exit
  • Now if you do a git log you will see a single commit with a nice “implementation of feature X” log message
  • And you’re all set to merge to your master branch without cluttering its history with a long string of commit messages

3 Responses to “Note to self: comparing two branches in git and squashing several commits into one”

  1. Caius Says:

    When editing tv squash commit message I usually prepend all the commit messages with ‘* ‘ which is markdown or textile for a list.

    Looks pretty enough in plaintext, but even better when your bug tracker parses it into HTML.

  2. Caius Says:

    s/tv/the/ # stupid iPhone

  3. Caius Says:

    You can also miss out the current branch when using the .. notation. ..master is the equivalent of HEAD..master and vice versa.

    So if I’m on branch foo and want to diff against master I can just use git diff master..