Another way to squash all your commits is to reset the index to master
:
Note: Git's default branch name is still master
with Git version 2.41 (Q3 2023), as seen in git init
man page.
Git version 2.28 (Q3 2020) introduced configurable default branch names, which means your remote repository may optionally use another default branch name such as main
. In order to provide the most universally applicable examples, as well as avoid confusion, this answer shall assume Git's default configuration.
If you need the following commands to work for any default branch, replace master
with ${defaultBranch}
.
And define defaultBranch=$(git config --get init.defaultBranch || echo main)
.
Back to the solution: (to squash all your commit) reset the index to master
:
git checkout yourBranch
git reset $(git merge-base master $(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 master 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 master $(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.