Git: How to squash all commits on branch

Another way to squash all your commits is to reset the index to main:


(Reminder: Note: since Git 2.28 (Q3 2020), the default branch is configurable, and now (2021+) set to main, no longer master.)

If you need the following commands to work for any default branch, replace main with ${defaultBranch}.
And define defaultBranch=$(git config --get init.defaultBranch || echo master).
For Git previous to 2.28, defaultBranch will be set to master.
For for recent Git versions, it will be main.


Back to the solution: (to squash all your commit) reset the index to main:

git checkout yourBranch
git reset $(git merge-base main $(git branch --show-current))
git add -A
git commit -m "one commit on yourBranch"

This isn’t perfect as it implies you know from which branch “yourBranch” is coming from.
Note: finding that origin branch isn’t easy/possible with Git (the visual way is often the easiest, as seen here).

Note: git branch --show-current has been introduced with Git 2.22 (Q2 2019).


Or, as noted by Hiroki Osame in the comments:

git switch yourBranch
git reset --soft $(git merge-base main HEAD)
git commit -m "one commit on yourBranch"
  • no need for git branch --show-current since HEAD is already a reference to that branch.
  • no need for git add -A, since git reset --soft only moves HEAD, and leaves the index untouched (in other words, the files are already “added”).

EDIT: you will need to use git push --force (or git push --force-with-lease)
See “git push --force-with-lease vs. --force


Karlotcha Hoa adds in the comments:

For the reset, you can do

git reset $(git merge-base main $(git rev-parse --abbrev-ref HEAD)) 

[That] automatically uses the branch you are currently on.
And if you use that, you can also use an alias, as the command doesn’t rely on the branch name.

Leave a Comment