When you run git rebase -i HEAD~5
, Git opens a text file in your editor showing your last 5 commits. Each line starts with a command - pick
, squash
, drop
, etc. You edit this file to tell Git what to do with each commit, save it, and pray nothing breaks.
The official Git rebase documentation explains the technical details, but here's what actually happens in practice.
Here's what those commands actually do in practice:
- pick - Leave the commit alone (this one usually works fine)
- reword - Change the commit message (will open your editor again - hope you remember how to exit vim)
- edit - Pause the rebase so you can modify the commit (you'll forget you're mid-rebase and panic later)
- squash - Combine with the previous commit, keep both messages (creates walls of text nobody reads)
- fixup - Combine with previous commit, throw away this message (perfect for your "fix typo" commits)
- drop - Delete the commit entirely (accidentally deleted the commit that fixed the critical bug? oops)
- exec - Run a command (will fail and abort your entire rebase at the worst possible moment)
When Interactive Rebase Becomes a Nightmare
Large repositories are slow as hell: Rebasing 50+ commits in a repo with 10,000+ commits? Go get coffee. Maybe lunch. The operation can take 10-15 minutes and there's no progress bar to tell you if it's stuck. Performance optimization for large repositories becomes critical, and GitHub's tips for large monorepos can help.
Merge conflicts mid-rebase: Nothing quite like resolving the same conflict 15 times because you're squashing commits that touched the same file. Git pauses, you fix conflicts, git add .
, git rebase --continue
, repeat until you question your career choices. Stack Overflow has extensive guidance for handling these situations, and this conflict resolution tutorial covers the painful reality.
Binary files break everything: Try to rebase commits with large images or compiled binaries. Git will churn through megabytes of data for every commit, making the process painfully slow.
The editor nightmare: Interactive rebase opens in whatever your $EDITOR
is set to. If that's vim and you don't know vim, you're fucked. :wq
to save and quit, :q!
to abandon ship. GitHub's guide to associating text editors shows how to escape this hell, and this Stack Overflow thread has alternatives for easier rebasing.
The Golden Rule (That Everyone Breaks Eventually)
Never rebase commits you've already pushed to a shared repository. Everyone knows this rule. Everyone breaks it eventually. When you do, you'll need to force push (git push --force
) and every teammate who pulled your branch will hate you because their local copies are now completely screwed.
The "safe" way is git push --force-with-lease
which checks if anyone else has pushed since your last pull. But let's be honest, you'll use --force
because you're in a hurry and think you know what you're doing. Atlassian's guide on merging vs rebasing explains when to avoid this, and Git best practices emphasizes team workflow considerations.
What Actually Happens Under the Hood
Interactive rebase replays each commit one by one, creating entirely new commit objects with new SHA-1 hashes. Even commits you didn't touch get new hashes because their parent commits changed. This is why you can't just rebase willy-nilly on shared branches - you're literally rewriting history. The Pro Git book's chapter on rewriting history covers the technical mechanics, while Git internals documentation explains how commit objects actually work.
For a 10-commit rebase, Git creates 10 new commit objects and updates all the references. If conflicts happen, Git stops mid-process and leaves you in a weird detached HEAD state that confuses everyone.
The typical workflow looks like this:
git rebase -i HEAD~5
## Edit the todo file
## Git starts replaying commits
## Conflict! Fix it manually
git add .
git rebase --continue
## Another conflict!
git add .
git rebase --continue
## Finally done... wait, did I drop the wrong commit?
Most developers learn interactive rebase the hard way - by accidentally deleting important commits or getting stuck mid-rebase with no idea how to continue or abort. This comprehensive tutorial shows the complete workflow, and Nathan LeClair's guide helps overcome the fear factor.