Combine two commits during an interactive Git rebase
Use squash or fixup to combine adjacent commits, adjust a pending rebase plan, and recover safely when the relevant commits have already been replayed.
In an interactive rebase, change the newer commit's action from pick to squash to combine it with the preceding commit. Use fixup when you want to discard the newer commit's message. If the rebase is already running, the right approach depends on which commits remain in its todo list.
Combine the last two of three commits
Start with a clean working tree and at least three commits after the chosen base:
git rebase -i HEAD~3
The todo list is ordered oldest first. Suppose it contains:
pick a1b2c3d Add login endpoint
pick e4f5a6b Fix validation message
pick c7d8e9f Correct another validation message
To combine only the last two, leave the first two actions as pick and change the third:
pick a1b2c3d Add login endpoint
pick e4f5a6b Fix validation message
squash c7d8e9f Correct another validation message
Git replays the first commit unchanged in purpose, then combines the second and third. When prompted, edit the combined message and save it. Changing both the second and third lines to squash would combine all three commits, which is a different operation.
Choose squash or fixup
squashcombines the changes and opens a message editor containing the contributing messages.- Plain
fixupcombines the changes while discarding that commit's message, keeping the preceding commit's message.
For a small follow-up correction, change the third line to fixup instead. More advanced fixup -C and fixup -c forms have different message behavior; do not assume every fixup variant discards its message.
Change a rebase that has already started
Inspect the current state:
git status
git rebase --edit-todo
--edit-todo lets you change the remaining plan. If the two commits are still pending, arrange them next to each other and mark the later one squash or fixup. It does not automatically undo commits that have already been replayed.
If you are paused on a conflict, resolve it, stage the affected files, and use git rebase --continue. If the relevant commits have already passed or the plan is unclear, save any conflict-resolution work you want separately, then restart deliberately:
git rebase --abort
git rebase -i HEAD~3
Aborting returns the branch to its pre-rebase state; it can discard work done while resolving that rebase.
FAQ
Can I combine commits that have already been pushed?
Yes, but the rewritten history normally needs a non-fast-forward update. Coordinate with anyone using the branch, review the remote tip, and use a scoped --force-with-lease push if the server permits it. Shared protected branches usually need a different workflow.
How do I avoid keeping several fix-typo messages?
Use plain fixup, or edit the squash message to describe the final change clearly. Commit messages should explain the combined result.
Can I combine nonadjacent commits?
You can reorder lines in the interactive todo list and then squash adjacent entries. Reordering changes when each patch is applied, so dependencies can cause conflicts or change the result. Review and test the final code rather than treating a clean rebase as proof of correctness.
See git-rebase 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