How to rewrite history with git rebase
Interactive rebase lets you edit a series of commits before sharing them. Golden rule: only rewrite commits you have not pushed to a shared branch.
Start an interactive rebase
To edit the last 4 commits:
git rebase -i HEAD~4
Git opens an editor listing commits, oldest first:
pick a1b2c3 add parser skeleton
pick d4e5f6 fix typo
pick 987654 implement tokenizer
pick fedcba tests for tokenizer
Common actions
Change pick to:
| Command | Effect |
|---|---|
pick |
keep commit as-is |
reword |
keep changes, edit message |
squash / s |
merge into previous commit, combine messages |
fixup |
merge into previous, discard message |
drop |
delete the commit |
edit |
pause here to amend manually |
Typical cleanup — squash the typo fix into the parser commit:
pick a1b2c3 add parser skeleton
fixup d4e5f6 fix typo
pick 987654 implement tokenizer
squash fedcba tests for tokenizer
Save and close; Git replays the commits.
Fixing a specific commit
Use edit to stop at a commit, make changes, then continue:
# ...make edits...
git add -p
git commit --amend
git rebase --continue
When conflicts appear
Rebase applies commits one at a time. On conflict:
# resolve files, then
git add <file>
git rebase --continue
# or bail out entirely:
git rebase --abort
After rewriting pushed history
If you must push rewritten commits to your own PR branch:
git push --force-with-lease
--force-with-lease refuses to overwrite work someone else pushed since your last fetch — always prefer it over --force.