Last Updated: February 25, 2016
·
25.79K
· rizwaniqbal

Squash your commits with git rebase

I dont' know if this one has been covered before, but I couldn't find it in my list of protips, so sharing it anyways.

There are times when you are working on a big feature and have a lot of commits that make it a pain while going through code review.

Also, a lot of us really commit early, commit often for different reasons, be it Unit Testing or testing the code on different regions. However, this is a nifty trick to combine all your commits together.

You can use git rebase to combine everything together.

Say you have a branch that has 4 commits. git log --oneline -4 :

766c833 Finishes Payment Module
5baaa20 Add a few more files
630e451 Modify some code
03b37e9 Add Gateway API classes

We can combine these commits by rebasing to the first commit. There are two ways to do this. You can either do git rebase -i <commit-hash> OR git rebase -i HEAD~4.

Git will now put you into an editor with the above text in it, and a little explanation of what can be done. You have plenty of options available to you from this screen, but right now we’re just going to squash everything into one commit. So, changing the first four lines of the file to this will do the trick:

pick 03b37e9 Add Gateway API classes
squash 630e451 Modify some code
squash 5baaa20 Add a few more files
squash 766c833 Finishes Payment Module

Basically this tells Git to combine all four commits into the the first commit in the list. If you rebased it using the HEAD option another editor will pop up once this is done. This is to modify the commit messages.

If you want everything to be merged into a single commit and and not combined into the first commit, you can reset the branch to the first commit, add all the files and amend the commit message.

With the same example above:

$ git reset 03b37e9
$ git log --oneline -1
03b37e9 Add Gateway API classes

When you do a git status, it will show you all uncommitted changes. Just add all the files again :

git add .

and, commit them with a new message:

git commit -a --amend -s -m "Finishes CCAvenue integration"

This will give us a fully squashed branch.

$ git log --oneline
2268cc6 Finishes CCAvenue integration

References

@owocki

http://gitready.com/advanced/2009/02/10/squashing-commits-with-rebase.html

http://feeding.cloud.geek.nz/2010/08/combining-multiple-commits-into-one.html