Last Updated: May 1, 2025
Interactive Rebase Squash
git rebase -i HEAD~4Interactive rebase last 4 commits
pick → squashIn rebase editor: change 'pick' to 'squash' to meld into previous
pick → fixupChange 'pick' to 'fixup' — squash AND discard the commit message
pick → rewordChange 'pick' to 'reword' to edit the commit message only
pick → dropRemove the commit entirely from history
git rebase -i --autosquash HEAD~5Auto-squash fixup!/squash! commits automatically
git rebase -i --rootRebase ALL commits from the root (rewrite entire history)
git rebase --continueContinue after resolving conflicts during rebase
Fixup & Autosquash Workflow
git commit --fixup target-commitCreate a fixup commit targeting a specific commit
git commit --squash target-commitCreate a squash commit with message preservation
git rebase -i --autosquash mainAuto-reorder and squash fixup!/squash! commits
git config --global rebase.autosquash trueEnable autosquash by default
git commit --fixup=amend:/regex/Fixup the commit whose message matches regex
git rebase -i --autosquash --keep-emptyAutosquash but preserve intentional empty commits
Squash Merge Strategies
| Item | Description |
|---|---|
Squash Merge | GitHub/GitLab: squash all PR commits into one on merge |
Merge Commit | Keep all individual commits, add merge commit (full history) |
Rebase Merge | Linear history, all commits preserved, no merge commit |
Semi-Linear Merge | Rebase then merge commit — linear history with merge marker |
Squash + Branch Delete | Default for most teams: one clean commit per feature |
Interactive Squash | Manually combine related commits, keep logical separations |
Best Practices
| Item | Description |
|---|---|
Squash WIPs | Squash 'WIP', 'fix typo', 'oops' commits before sharing |
Keep Logical Units | One commit per logical change — don't squash everything |
Clean Before Review | Interactive rebase to polish history before opening PR |
Commit Messages Matter | A squashed commit needs a high-quality message |
Don't Squash Shared History | Never rebase/squash commits already pushed to shared branches |
Autosquash Config | Set globally: git config --global rebase.autosquash true |
Squash != Amend | Squash combines commits; amend replaces the last commit |
Co-Author Credit | Use Co-authored-by: in squashed merge to credit contributors |
Pro Tip: Squash WIP commits before merging, but keep logical steps separate. A PR with one mega-commit is as unhelpful as one with 50 'fix typo' commits.