Drill: Interactive Rebase to Clean Up Commits¶
Goal¶
Use interactive rebase to squash, reorder, and edit commits before pushing to create a clean commit history.
Setup¶
- A git repository with several small or messy commits on a feature branch
- Commits that have NOT been pushed to a shared remote
Commands¶
Set up a practice scenario:
mkdir /tmp/rebase-drill && cd /tmp/rebase-drill && git init
echo "base" > file.txt && git add file.txt && git commit -m "initial"
echo "v1" >> file.txt && git add file.txt && git commit -m "WIP: start feature"
echo "v2" >> file.txt && git add file.txt && git commit -m "fix typo"
echo "v3" >> file.txt && git add file.txt && git commit -m "WIP: more progress"
echo "v4" >> file.txt && git add file.txt && git commit -m "actually fix the thing"
echo "v5" >> file.txt && git add file.txt && git commit -m "cleanup"
View the commits to be rebased:
Start interactive rebase (last 5 commits):
GIT_SEQUENCE_EDITOR="sed -i '2s/pick/squash/;3s/pick/squash/;4s/pick/squash/;5s/pick/squash/'" git rebase -i HEAD~5
The rebase todo list uses these commands:
- pick - keep the commit as-is
- squash (s) - combine with previous commit, edit message
- fixup (f) - combine with previous commit, discard message
- reword (r) - keep commit but edit message
- drop (d) - remove the commit entirely
To reorder commits, change the line order in the editor.
After conflicts during rebase:
Abort a rebase in progress:
What to Look For¶
- After squashing, multiple commits become one with a combined message
fixupis like squash but automatically discards the commit message- Reordering commits may cause conflicts if later commits depend on earlier ones
- The reflog preserves the pre-rebase state for recovery
Common Mistakes¶
- Rebasing commits that have already been pushed to a shared branch
- Squashing all commits into one when some logical separation is valuable
- Not checking
git logafter rebase to verify the result looks correct - Forgetting that rebase rewrites commit hashes (all downstream refs change)