Interactive Rebase: Cleaning Up Local Commits Before Anyone Sees Them
Interactive rebase lets you squash, reword, and drop messy local commits before pushing. Here's how the commands work, a real example, and why the golden rule matters.
04 Sept 2025, 17:02 UTC

You finish a feature with a commit history that tells the story of your afternoon, not the story of the change: "wip", "fix typo", "actually fix it this time", "undo that". Pushing that as-is forces every reviewer to read your debugging diary. The useful fix is git rebase -i, which lets you rewrite your local commits into a small, readable set before anyone else fetches them.
The thesis is simple: treat interactive rebase as an editing pass over your own unpublished work. It is safe and valuable on local topic branches, and genuinely dangerous on branches other people have already pulled.
What the interactive commands actually do
Running git rebase -i HEAD~N opens your editor with a list of the last N commits, oldest first, each prefixed with a command. You change the command word (or reorder lines) and save; Git then replays the commits according to your instructions. The main commands:
pick— keep the commit as-is.reword— keep the change but rewrite the commit message.squash— fold this commit into the previous one, combining both messages for editing.drop— discard the commit and its changes entirely.edit— pause the rebase at this commit so you can amend it (add forgotten files, split it, fix content).
Because every rewritten commit gets a new hash, this is history rewriting — which is exactly why it must stay local.
A worked example: five messy commits into two
Say git log --oneline -5 on your feature branch shows:
a1b2c3d wip
e4f5g6h add rate limiting middleware
7i8j9k0 fix typo
l1m2n3o add tests for rate limiter
p4q5r6s actually fix header nameRun, in your repo, on the feature branch (no special permissions needed — it's your local history):
git rebase -i HEAD~5In the editor, mark the typo and header fixes as squash under the middleware commit, and drop the meaningless wip if its changes are superseded:
pick e4f5g6h add rate limiting middleware
squash 7i8j9k0 fix typo
squash p4q5r6s actually fix header name
pick l1m2n3o add tests for rate limiter
drop a1b2c3d wipGit will stop to let you combine the squashed commit messages, then replay the rest. Verify afterwards with git log --oneline -5: you should see fewer commits with new hashes and clean messages. Also run your test suite — squashing can silently combine changes in ways that break the build.
Handling conflicts mid-rebase
If a replayed commit conflicts with an earlier rewritten one, Git pauses and marks the conflicted files. The recovery sequence is: resolve the conflict markers in each file, git add the resolved files, then git rebase --continue. If you realize the whole rebase was a mistake, git rebase --abort returns the branch to its pre-rebase state.
The trade-off: rewritten hashes and the golden rule
Interactive rebase changes commit hashes. If the branch already exists on a remote, your next push will be rejected, and forcing it (git push --force) diverges history for anyone who fetched the old commits. Hence the golden rule: only rebase local or personal topic branches, never shared branches like main or develop.
The other sharp edge is drop: dropped commits are unreferenced and eventually garbage-collected. Your safety nets are the reflog (git reflog show <branch> shows the pre-rebase tip, which you can restore with git reset --hard <old-hash>) or, better, a cheap backup before you start: git branch backup/my-feature.
A practical workflow to adopt
- Before pushing, run
git log --onelineand decide what the history should say. - Create a backup branch, then run
git rebase -i HEAD~N. - Verify with
git log --onelineand your test suite. - Push only if the branch has never been shared; if it has, push normally and leave the history alone, or coordinate a force-push with your team.
Practice once on a disposable branch. After that, a two-minute rebase before every push becomes the cheapest readability win in your Git workflow.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.