Squash recent Git commits into one
Use interactive rebase or a soft reset to combine private commits, preserve a backup, and avoid rewriting unrelated shared history.
For a simple linear branch, run git rebase -i HEAD~N and keep the oldest selected commit as pick. Mark the following commits as squash or fixup to fold them into it.
Inspect the boundary first
Start with a clean working tree, create a backup branch, and inspect the selected commits:
git status --short
git branch backup-before-squash
git log --oneline --graph -8
git rebase -i HEAD~3
HEAD~3 follows first parents. It must exist, and a merge-containing history needs more deliberate selection than “the last three lines.” If you need to include the repository's root commit, use an appropriately reviewed git rebase -i --root operation instead.
For three ordinary commits, the todo list is ordered oldest first:
pick a1b2c3d Add the login endpoint
squash e4f5a6b Correct a response message
squash b7c8d9e Clarify a code comment
Save the todo list, then edit the combined commit message when prompted. Resolve any conflicts, stage their resolutions, and continue with git rebase --continue.
Choose squash or fixup
squash combines the selected changes and lets you edit a message assembled from the original messages. Plain fixup folds the change into the preceding commit while discarding the fixup commit's message. It is useful for small corrections whose intent already belongs in the earlier message.
Review the final diff and run tests. A completed rebase does not establish that the new commit has the intended content or authorship.
Use a soft reset as an alternative
For a clean index and working tree, and a reviewed linear boundary:
git reset --soft HEAD~3
git diff --cached
git commit -m "Add the login endpoint"
The reset preserves the current index and working tree, then the new commit records their staged state relative to the earlier tip. This approach is not limited to changes in one file. Unrelated pre-existing staged changes would also be included, which is why the initial clean-state check matters.
Handle published history and mistakes
Rewriting a published personal branch needs coordination and an appropriately reviewed --force-with-lease push. On a shared branch, a squash integration through the team's pull-request workflow can combine the feature at the target without rewriting everyone's existing branch history.
During an active rebase, git rebase --abort returns to its starting state. After it completes, inspect the backup or reflog to plan recovery; avoid a blind hard reset over new work.
git log origin/main..HEAD --oneline identifies commits not reachable from the fetched mainline. It does not prove that every commit is yours or safe to rewrite. Check authorship, dependencies, merge structure, and collaboration expectations before selecting the squash range.
See git-rebase, git-reset, and git-push.
Contact us
Join the community
to join the community
Try Guance
Start online and pay only for what you use.
Get startedChoose a Guance plan