Git: Squash Commits
Last updated
Squashing combines several commits into one, so a messy series of "wip", "fix typo", "actually fix it" commits becomes a single clean commit. The usual tool is interactive rebase - git rebase -i - where you mark the commits to fold together. Because squashing rewrites history, do it before you push, or on a branch only you are working on.
Try these in the terminal playground - a real shell in your browser, nothing to install.
Syntax
| Command | What it does |
|---|---|
git rebase -i HEAD~3 | Interactively rebase the last 3 commits |
git rebase -i main | Rebase every commit since main |
git merge --squash feature | Squash a branch's commits into one on merge |
git reset --soft HEAD~3 && git commit | Squash the last 3 commits without rebase |
Interactive rebase commands
In the editor that opens, change pick to one of these.
| Keyword | What it does |
|---|---|
pick | Keep the commit as-is |
squash (s) | Fold into the previous commit, merge messages |
fixup (f) | Fold in but discard this commit's message |
reword (r) | Keep the commit but edit its message |
Worked example
Squash the last three commits into one before pushing.
| Step | Action | Result |
|---|---|---|
| 1 | git rebase -i HEAD~3 | Opens the last 3 commits in the editor |
| 2 | Set commits 2 and 3 to squash | Marks them to fold into the first |
| 3 | Save & edit the combined message | Three commits become one clean commit |
Git squash commits FAQ
How do I squash the last N commits in Git?
Run
git rebase -i HEAD~N (for example HEAD~3 for the last three). In the editor, leave the first commit as pick and change the rest to squash (or fixup to drop their messages). Save, edit the combined commit message, and the commits collapse into one.What's the difference between squash and fixup?
Both fold a commit into the previous one.
squash keeps the commit's message and lets you combine it with the others in an editor. fixup discards the commit's message entirely, keeping only the earlier commit's message - handy for "oops, small fix" commits you don't want in the final message.How do I squash a whole branch when merging?
Use
git merge --squash feature, then git commit. This applies all of the branch's changes as staged changes and lets you record them as a single commit on the target branch, without bringing over the branch's individual commits. GitHub's "Squash and merge" button does the same thing.Can I squash without an interactive rebase?
Yes.
git reset --soft HEAD~N moves the branch back N commits while keeping all their changes staged, then a single git commit records them as one. It's a quick way to squash the most recent commits without opening the rebase editor.Can I practice this online?
Yes. Open the terminal playground to run interactive rebase in a real shell in your browser - nothing to install. Coddy's free interactive Git course also covers rebasing and cleaning up history step by step.