Interactive Rebase
Interactive rebase is a powerful tool for rewriting commit history. You can squash, reorder, edit, and even delete commits before sharing your work.
What is Interactive Rebase?
Interactive rebase (git rebase -i) lets you modify commits:
- Squash: Combine multiple commits into one
- Reword: Change commit messages
- Edit: Modify commit content
- Reorder: Change commit order
- Drop: Remove commits entirely
- Fixup: Squash without keeping the message
Starting Interactive Rebase
# Rebase last 3 commits
git rebase -i HEAD~3
# Rebase from specific commit (not including it)
git rebase -i abc123
# Rebase onto main
git rebase -i main
The Interactive Editor
When you run git rebase -i HEAD~3, an editor opens:
pick abc1234 Add user model
pick def5678 Add user validation
pick 789abcd Fix typo in user model
# Rebase 123abc4..789abcd onto 123abc4 (3 commands)
#
# Commands:
# p, pick = use commit
# r, reword = use commit, but edit the commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like "squash", but discard this commit's log message
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
#
# These lines can be re-ordered; they are executed from top to bottom.
#
# If you remove a line here THAT COMMIT WILL BE LOST.
Squashing Commits
Combine multiple commits into one:
Before
pick abc1234 Add user model
pick def5678 Add user validation
pick 789abcd Fix typo in user model
After (combine all into first)
pick abc1234 Add user model
squash def5678 Add user validation
squash 789abcd Fix typo in user model
Save and close. You'll get a new editor to write the combined message:
# This is a combination of 3 commits.
# This is the 1st commit message:
Add user model
# This is the commit message #2:
Add user validation
# This is the commit message #3:
Fix typo in user model
# Please enter the commit message for your changes.
Edit to:
Add user model with validation
- Created User class
- Added email validation
- Added password validation
Using Fixup
Like squash but discards the commit message:
pick abc1234 Add user model
fixup def5678 fix typo
fixup 789abcd another fix
The result has only "Add user model" message.
Creating Fixup Commits
# Make fix for an earlier commit
git commit --fixup=abc1234
# Later, autosquash them
git rebase -i --autosquash main
Git automatically marks fixup commits with fixup.
Rewording Messages
Change commit messages without changing content:
pick abc1234 Add user model
reword def5678 validation
pick 789abcd typo fix
When you save, Git stops to let you rewrite "validation" message.
Editing Commits
Stop and modify a commit:
pick abc1234 Add user model
edit def5678 Add validation
pick 789abcd Add tests
Git stops at def5678. You can:
# Make changes
# ...
# Amend the commit
git add .
git commit --amend
# Continue rebase
git rebase --continue
Reordering Commits
Simply change the order:
Before
pick abc1234 Third feature
pick def5678 First feature
pick 789abcd Second feature
After
pick def5678 First feature
pick 789abcd Second feature
pick abc1234 Third feature
Dropping Commits
Remove a commit entirely:
pick abc1234 Add feature
drop def5678 Debug code (remove this)
pick 789abcd Add tests
Or just delete the line.
Common Workflows
Clean Up Before PR
# See your commits
git log --oneline main..HEAD
# Interactive rebase
git rebase -i main
# Squash related commits
# Reword unclear messages
# Drop debug/WIP commits
# Force push
git push --force-with-lease
Combine WIP Commits
Before:
WIP: start feature
WIP: more work
WIP: almost done
Fix bug
Add tests
After:
Add new feature with tests
Split a Commit
Use edit to stop at a commit, then:
# Reset the commit (keep changes)
git reset HEAD~1
# Create multiple commits
git add part1.js
git commit -m "Add part 1"
git add part2.js
git commit -m "Add part 2"
# Continue
git rebase --continue
Handling Conflicts
During interactive rebase, you might hit conflicts:
# Fix conflicts
git add conflicted-file.js
# Continue
git rebase --continue
# Or abort everything
git rebase --abort
Safety Tips
Create Backup Branch
git branch backup-before-rebase
git rebase -i HEAD~5
# If something goes wrong:
git checkout backup-before-rebase
Use Reflog
If you mess up:
# Find where you were before
git reflog
# Reset to that point
git reset --hard HEAD@{5}
Never Rebase Pushed Commits
Unless it's your personal branch and you'll force push.
Autosquash Feature
For automatic squashing:
# Create commit that should be squashed into abc123
git commit --fixup abc123
# Create commit with message to squash
git commit --squash abc123
# Rebase with autosquash
git rebase -i --autosquash main
Git automatically orders and marks fixup/squash commits.
Configure as default:
git config --global rebase.autosquash true
Summary
- Interactive rebase rewrites commit history
- Use
git rebase -i HEAD~nto start - pick: Keep commit as-is
- squash/fixup: Combine with previous
- reword: Change message
- edit: Stop to modify
- drop: Remove commit
- Clean up before sharing (PRs)
- Never rebase shared/public history
- Use
--autosquashfor fixup commits
In the next lesson, we'll learn about cherry-picking commits.

