This post was originally posted in the newsletter GitBetter. If you are interested in leveling up your game in Git, you can subscribe to it.
Before learning how to squash commits let’s see what is git squash first.
Git squash is a technique that helps you to take a series of commits and condense it to a few commits.
For example, assume that you have a series of n commits. By squashing you can make all the n-commits to a single commit.
Squashing is mainly used to condense a large number of commits to make it to a small number of meaningful commits. So that we can make the git history clearer.
It is also used while merging branches. Most people will advise you to always squash the commits and rebase it with the parent branch (like master or develop).
So when you are squashing and rebasing with the parent branch, the history of the main branch will be very clean and will have only meaningful commits.
For example, consider the following git history
In that, you can see the last three commits. Those three commits explain that we have added a new file and have added some content.
It’s good to have it as a single commit that explains that the new file has been added with some content. So let’s see how to squash the last three commits to a single commit.
git rebase -i HEAD~3
git rebase -i is an interactive tool that helps you to squash commits. And it comes up with various options. But let’s discuss only git squash.
Don’t worry if you are not very comfortable with git-rebase. Squashing commit is a very simple technique to achieve with interactive git-rebase (i.e) git rebase -i
HEAD~3 explains that we are taking the last three commits.
The interactive rebase will open up the editor. And you can see how rebase -i has taken the last three commits. And note the number of options that it has.
Let’s concentrate only on squash.
As mentioned earlier, let’s make it to a single commit.
You can see that we have marked the last two commits to squash. You can use squash or s to mark the commit to squash.
In the above example, the squashed commits will be merged to the main commit (i.e) the commit marked as the pick.
After marking the commits you can save the editor.
After saving the editor, rebase -i will open another editor to enter the commit message like the below image.
After editing your commit message you can save this editor. Note that the line starting with # will be ignored.
The git log as follows
I have edited the commit message and also note that we have squashed those three commits to a single commit.
And note that the commit hash has also changed. git rebase will always create a new commit with respective changes.
Remember that squashing will change the git history. So if you have already pushed the branch to remote then it is not advisable to squash.
Always squash before you push the changes to remote.
You can also use the fixup option to squash commits. Fixup is the same as squash but it won’t allow you to edit the commit message. It will take the main commit (i.e) the commit marked as the pick as the commit message.
Let’s see an example
You can use fixup or f to pick up the commits. After picking up the commits you can save the editor. The interactive rebase will save the commit message.
The git history is as follows
Note that the Git has taken the main commit message and squashed the other two commits into it. And also note that the commit hash has been changed too.
Git also provides the option to squash when you are merging a branch. This is a very useful command and comes in handy very much.
Most of us will be working in branches. We will be checking out branches to build a new feature or to fix some quick bugs.
So when we are ready to merge those changes to the main branch (master or develop) then squashing those changes will make more sense.
So consider the below command
git merge --squash target_branch_name
This command will take all the commits from the target branch, squash them, and stage all changes in the current branch. Then you can commit all the changes in a single commit.
Let’s see an example
You can see that we are merging a branch to develop with —squash option. Git will take all the changes and have staged those changes.
Github also provides the option to squash commits. This is also a very helpful feature that comes in handy when you are merging a pull request.
You can squash and merge the changes. So that all the five commits will be condensed to a single commit.
You can see that a single commit is made with a relevant commit message.
I hope you learned something :)
Thank you for reading :)