Photo from Chile

Using Git Rebase to Squash Commits

A Git command that can be very useful, yet is often overlooked by beginners (such as myself) is the rebase command. I admit to not fully understanding all of its uses, but there is one simple use for it that I have found myself taking advantage of lately. Here's the scenario:

You have a remote Git repository, perhaps hosted at GitHub. You want to work on a new feature, so you create a local branch on your machine:

view plain print about
1git checkout -b newBranch

You make some changes and commit them to the local branch:

view plain print about
1git commit -a -m"My first set of changes"

You make some more changes and commit them to the local branch:

view plain print about
1git commit -a -m"My second set of changes"

You make some more changes and commit them to the local branch:

view plain print about
1git commit -a -m"My third set of changes"

You now have three separate commits that relate to one feature, and the feature is complete. You could simply push the changes to your remote, but then you'd end up with three commits on the remote that are not particularly meaningful. The only reason you have three commits in your local repo is that you completed the work in three steps. Perhaps you'd rather have just one commit reported in the remote repo for this feature. Thankfully git rebase allows you to do that very simply.

If you issue a git log command, you'll see something similar to this:

I can see from this that I have three commits corresponding to the changes that I made for the feature. To squash these three commits into one, and specify a commit message for the group, I can use git rebase, with the -i (which stands for interactive), argument:

view plain print about
1git rebase -i HEAD~3

The HEAD~3 tells git that I want to rebase the past three commits.

This will pop open my text editor, which I have configured to be TextMate, with some rebasing instructions. The file will look something like this:

This is quite convenient as git actually provides you with some instructions. I want to combine the second and third commit with the first, so I edit the file to look like this:

When I save and close the file, git will pop open another file in the editor to edit our commit message:

From here I can either choose to accept the three individual commit messages that were picked up from our three commits, or I can remove them (or comment them out) and provide our own commit message. I'm going to remove the original commit messages and replace them with a single one that reads "A bunch of changes to support new feature A". When I save and close this file I'll be back at the command line with a message similar to this:

I can now merge these changes back into the master branch:

Now when I issue the git log command again, I'll see my previous three commits squashed into one:

It's as simple as that. Now you do need to be careful using the rebase command with remotes when you are collaborating with others. You should avoid rebasing commits that have already been pushed to a remote. There is also a lot more to rebasing than this simple example, but it's not a bad place to start. Happy rebasing!

This is a good example use of git rebase, one I haven't run across. Last Friday I was doing research on git rebase but I decided to not use it. I had a May sprint branch that had received some commits after our June sprint branch was created. I was thinking git rebase would help move the June branch so it's first commit was after the last May commit. After reading so many warnings about rebase I just avoided it.
# Posted By Aaron West | 6/7/10 10:08 AM
@Aaron - At my work we are using git. Our workflow is built around rebasing when pulling in changes from upstream. Our workflow is based on this blog entry,
# Posted By Mike Henke | 6/7/10 1:37 PM
Awesome post! The step-by-step with expected results was very helpful getting me through this activity for the first time.
# Posted By Stephen Lee | 2/25/11 6:15 PM
Thanks you very much for that really clear explanation !
# Posted By Michaël | 2/26/12 7:43 AM
Thanks! - 2 years on, this post is still helping people!
# Posted By Jay | 8/1/12 2:55 AM
Thanks! - 3 years on, this post is still helping people! :)
# Posted By Vladimir | 11/20/13 9:44 PM