Play video

Squashing essentially allows you to combine commits together. This is useful for re-packaging commits that are related to eachother in the pursuit of cleaning up history before pushing to an upstream master, or when you’re doing some cleanup on your local development branches.

The basics

Say I have a graph that looks like this. You can see I split off some commits onto a bug fix branch:

I’ll need to get my commits back onto mainline, and I can use merge or rebase to do that; however, with either solution, all my local branch commits would be preserved. Usually, preserving commits like this is a good idea, but let’s say you made a typo somewhere and had to create another commit to fix the spelling error. Or you have a bunch of local commits related to a bug fix, but you’d really rather just have all of those related commits under one roof. Enter squashing.

Squashing allows you to rewrite history and combine together commits.

In practice: the actual commands

Now that you know what squash is, let’s take a look the actual commands. Again, we’ll say my starting point is my bug fix branch with 3 commits.

It would be nice if I didn’t have to preserve these extraneous commits as separate entities since they are all related to a bug fix. I’d rather combine them together into one clean commit.

With my bug fix branch checked out, I’ll start by running the interactive rebase command with HEAD~3. This lets Git know I want to operate on the last three commits back from HEAD.

git rebase -i HEAD~3

Git will open up your default terminal text editor (most likely vim) and present you with a list of commits:

pick 7f9d4bf Accessibility fix for frontpage bug
pick 3f8e810 Updated screenreader attributes
pick ec48d74 Added comments & updated README
 
# Rebase 4095f73..ec48d74 onto 4095f73 (3 commands)
#
# Commands:
# p, pick <commit> = use commit
# r, reword <commit> = use commit, but edit the commit message
# e, edit <commit> = use commit, but stop for amending
# s, squash <commit> = use commit, but meld into previous commit
...

There are a couple options here, but we’ll go ahead and mark commits we’d like to meld with it’s successor by changing pick to squash. (If you’re using VIM, type i to enter insert mode)

pick 7f9d4bf Accessibility fix for frontpage bug
squash 3f8e810 Updated screenreader attributes
squash ec48d74 Added comments & updated README

Press ESC then type :wq to save and exit the file (if you are using VIM)

At this point Git will pop up another dialog where you can rename the commit message of the new, larger squashed commit:

# This is a combination of 3 commits
# This is the 1st commit message:

Accessibility fix for frontpage bug

# This is the commit message for #1:

Updated screenreader attributes

# This is the commit message for #2:

Added comments & updated README

# Please enter the commit message for your changes. Lines starting
# with '#' will be ignored, and an empty message aborts the commit
...

Simply saving this file without making changes will result in a single commit with a commit message that is a concatination of all 3 messages. If you’d rather rename your new commit entirely, comment out each commit’s message, and write you’re own. Once you’ve done, save and exit:

That’s it. You can either merge or rebase your branch back to mainline.