Interactive Rebase, Fixup & Autosquash
Reshape a messy branch into a clean, reviewable story with interactive rebase, fixup commits, and autosquash.
You already know git rebase -i reorders and squashes commits. The senior move is to let Git line those edits up for you so you barely think about it.
The fixup + autosquash loop
You are deep in a feature branch and spot a typo that really belongs in an earlier commit. Instead of a new "fix typo" commit that clutters history, make a fixup aimed at that commit:
git commit --fixup <target-sha>— records a commit titledfixup! <target subject>.git rebase -i --autosquash <base>— reorders everyfixup!right under its target and pre-marks itfixup, so you just save and quit.
Rebase verbs worth knowing
- pick — keep the commit as-is.
- reword — keep the changes, edit the message.
- squash — fold into the previous commit and combine messages.
- fixup — fold in and discard this commit's message.
- edit — stop here so you can amend or split the commit.
- drop — delete the commit entirely.
Turn on autosquash permanently with git config --global rebase.autosquash true and you never pass the flag again.
Example
# Spot which older commit a small fix belongs to
git log --oneline
# 9c1f2a3 (HEAD) wip
# 4b7d8e1 Add rate limiter
# a1b2c3d Add API client
# Stage the fix and aim it at that commit
git add limiter.js
git commit --fixup 4b7d8e1
# Let Git slot every fixup! next to its target automatically
git rebase -i --autosquash a1b2c3d~1
# The editor opens already ordered — just save and quitWhen to use it
- A developer squashes fifteen WIP commits from a feature branch into three logical commits before opening a pull request for review.
- A contributor uses --fixup commits throughout development and then runs rebase --autosquash before the PR merge to produce a clean history automatically.
- A team uses interactive rebase to reorder commits so related changes are grouped together, making the diff easier to follow in review.
More examples
Interactive rebase to squash commits
Opens the last five commits in an editor where pick keeps, squash merges into the previous, reword edits the message, and fixup merges silently.
# Rebase the last 5 commits interactively
git rebase -i HEAD~5
# In the editor:
# pick a1b2c3d feat: add checkout page
# squash 4e5f6a7 WIP progress
# squash 8b9c0d1 more WIP
# reword 2e3f4a5 feat: add payment step
# fixup 9a8b7c6 fix typoCreate a fixup commit for autosquash
--fixup names the commit after the target commit with a 'fixup!' prefix; --autosquash then slots and squashes it without manual editor work.
# After discovering a small bug in commit a1b2c3d
git add src/checkout.js
git commit --fixup=a1b2c3d
# Creates: fixup! feat: add checkout page
# Later, rebase collapses it automatically
git rebase -i --autosquash HEAD~6Reorder commits during interactive rebase
Simply dragging lines in the editor reorders which commits are replayed first, letting you group related changes before pushing.
git rebase -i HEAD~4
# Change the order in the editor:
# pick 3c1f9e2 feat: add product listing
# pick a1b2c3d feat: add checkout page
# pick 8b9c0d1 feat: add payment step
# pick 2e3f4a5 test: add e2e checkout tests
Discussion