How to Squash Last N Commits in Git?
Contents
We often need to squash several related commits to make the commit history cleaner. There are several different ways to achieve this.
Here, suppose we want to squash last 2 commits.
Using git rebase
I have covered this method in my previous post, so I won’t repeat it here.
soft reset, then commit
First, we run the soft reset command:
git reset --soft HEAD~2
This will reset last two commits, but keep their changes.
If you run git status
command, you will see that you have uncommitted changes.
These changes are a combination of changes in last two commits.
Now, you just commit again and write the new commit message:
git commit -m "some msg blah blah blah"
hard reset, then merge –squash
First, we run the hard reset command:
git reset --hard HEAD~2
This will discard changes in the recent two commits, but there are actually not lost.
HEAD@{1}
represents where your HEAD was before you use hard reset.
HEAD@{2}
represents your HEAD two moves ago. So HEAD@{}
variable logs your HEAD movement.
We can check the HEAD movement using git reflog
. An example output is like this:
0073058 (HEAD -> master) HEAD@{0}: commit: 9th
618c9fd HEAD@{1}: commit: 8th
ed79391 HEAD@{2}: commit: Squashed commit of the following:
f0fb17b HEAD@{3}: reset: moving to HEAD~2
b2ee13a HEAD@{4}: reset: moving to HEAD
b2ee13a HEAD@{5}: reset: moving to HEAD
b2ee13a HEAD@{6}: reset: moving to HEAD
b2ee13a HEAD@{7}: reset: moving to HEAD
b2ee13a HEAD@{8}: reset: moving to HEAD
b2ee13a HEAD@{9}: reset: moving to HEAD
b2ee13a HEAD@{10}: reset: moving to HEAD
b2ee13a HEAD@{11}: commit: 7th
004a853 HEAD@{12}: commit: sixth
f0fb17b HEAD@{13}: commit: fifth
d9f10ed HEAD@{14}: commit: fourth
774b308 HEAD@{15}: commit: thrid
ad2fb58 HEAD@{16}: commit: second
efe6902 HEAD@{17}: commit (initial): first
Now, we will run git merge --squash HEAD@{1}
to squash the recent two commits.
The merge window should be pre-populated with the commit message of recent two commits.
References
- Squash my last X commits together using Git
- Meaning of
HEAD@{N}
notation: https://stackoverflow.com/a/21911246/6064933 - Difference between
merge --squash
and rebase: https://stackoverflow.com/q/2427238/6064933