A working branch grows honest mess: “wip”, “fix”, “actually fix the fix”, a debug commit with a dump in it. Reviewers deserve better, and interactive rebase is how the branch tells a clean story before they see it.
Open the editor on your own commits#
git rebase -i main
Git lists the commits your branch adds, oldest first, each marked pick. Reorder the lines to reorder the commits; change the verb to change what happens to each.
The four verbs that matter#
reword- keep the change, rewrite the message. For every commit whose message you would not say out loud.squash- fold a commit into the one above it and combine the messages. For “and the test for it” commits.fixup- fold in and discard the message. The typo fixes and “forgot a semicolon” commits disappear into the commit they belong to, which is exactly where they belonged all along.drop- delete the commit. The debug dump goes here.
Save, and Git replays the branch with your edits. If a squash or reorder conflicts, resolve as usual and git rebase --continue; git rebase --abort returns everything to how it was.
The two rules#
- Only rewrite commits nobody else has. Interactive rebase rewrites history, so it belongs to your own unpushed branch - the same boundary as plain rebase and reset.
- If the branch was already pushed, the tidy version goes up with
git push --force-with-lease, never bare--force- the lease refuses if a reviewer pushed anything meanwhile.
When it goes wrong#
A rebase that produced nonsense is not lost. The reflog remembers the branch’s pre-rebase position; git branch rescue HEAD@{n} on that entry, inspect, and try again. Tidying is safe precisely because the escape hatch is reliable.
The goal is not a fake-perfect history. It is a branch where every commit is one idea, described once - the version of the work you would have written if you had known the ending from the start.
Share this post
Keep reading
Annotating Commits with git notes: Metadata Without Rewriting History
Some things belong on a commit but not in it: review links, benchmark results, the ticket nobody remembered to reference. git notes adds them after the fact, no rebase required.
Backing Up Your Git Server So It Actually Restores
Every clone is a partial backup - but hooks, config and server state live outside the repo. Mirror, bundle, copy off-site, and rehearse the restore.
Cherry-Picking: One Commit Without the Branch
Cherry-pick copies a single commit onto your branch and leaves the rest behind. Right for hotfixes across release branches, wrong as a sync strategy.