Interactive Rebase: Squash, Reword, Edit and Reorder Commits Like a Pro
Interactive rebase: squash, reword, edit, reorder commits.
20+ years shipping production infrastructure and CI/CD at scale. Everything here is grounded in real deployments.
- ✓Basic Git commit workflow
- ✓Comfortable with command line
- ✓Understanding of Git history as a DAG
Run git rebase -i HEAD~N to interactively rebase the last N commits. In the editor, change 'pick' to 'squash', 'reword', 'edit', or reorder lines. Save and exit to apply changes.
Imagine you're writing a report and you've made several rough drafts. Interactive rebase is like going back to your stack of drafts, picking the best parts from each, rewriting the titles, and arranging them in a logical order — all without retyping the whole thing. You end up with a clean, coherent final document that hides the messy process.
You've been there: a branch with 47 commits, half of them 'fix typo', 'oops', 'WIP', and 'please work'. Merging that into main is a crime scene. Interactive rebase is your cleanup crew — it rewrites history so your commits tell a coherent story. But it's not a toy. I've seen devs nuke weeks of work because they rebased a shared branch. This article is about using it right: squashing, rewording, editing, and reordering commits in production workflows. By the end, you'll know exactly when to reach for interactive rebase, how to execute each operation safely, and — more importantly — when to walk away.
Why Interactive Rebase Exists: The Messy History Problem
Every developer makes mistakes. You commit a typo, then fix it. You add a feature in three half-baked steps. Before you know it, your branch looks like a Jackson Pollock painting. Merging that into main pollutes the project history with noise. Interactive rebase lets you clean up before anyone sees it. It's the difference between a public diary and a curated memoir. Without it, code review becomes a nightmare — reviewers have to wade through 'fix' commits to find the actual logic. With it, each commit tells a single, coherent story.
--force-with-lease.Squashing Commits: The Art of the Single Logical Change
Squashing combines multiple commits into one. Use it when you have a series of 'fix' commits that should be part of the original commit. The classic pattern: you write a feature, then fix a bug in it, then improve formatting. Those three commits should be one. Squash merges their changes and lets you write a single message. The key: squash only commits that are conceptually the same change. Don't squash unrelated features — that defeats the purpose of atomic commits.
git rebase -i --autosquash if you've already marked commits with fixup! or squash! prefixes. It automatically arranges them. Run git commit --fixup=<commit> to create a fixup commit, then rebase with --autosquash.Rewording Commits: Fixing Messages Without Changing Code
Commit messages are documentation. A bad message like 'fix stuff' is useless. Rewording lets you change the message of any commit without altering its content. Use it when you realize a message is misleading, or when you want to follow a convention (e.g., 'feat: add login' instead of 'added login'). The operation is safe — it only changes the commit metadata, not the diff.
Editing Commits: Splitting or Amending Mid-History
Editing a commit pauses the rebase at that commit, letting you amend its content. Use it when you need to split a commit into smaller ones, or when you realize a commit includes changes that belong elsewhere. The workflow: mark the commit with 'edit', then when Git stops, make your changes, stage them, and run git commit --amend to modify the commit. Then git rebase --continue to proceed. This is powerful but dangerous — you're rewriting history, and conflicts can cascade.
git status after editing to ensure you have staged changes before continuing.Reordering Commits: Telling a Better Story
Sometimes commits are in the wrong order. Maybe you fixed a bug before adding the feature that introduced it. Reordering lets you rearrange commits to make logical sense. The rule: reorder only if the commits are independent — if commit B depends on changes in commit A, moving B before A will cause conflicts. Git will try to apply patches in the new order, and if they conflict, you'll have to resolve manually.
git log --oneline --graph to see the parent-child relationships. If two commits modify the same file, reordering is risky. Use git diff <commit1> <commit2> to see if they overlap.When Not to Use Interactive Rebase
Interactive rebase is not for every situation. Never use it on commits that have been pushed to a shared branch — you'll rewrite history and break everyone's work. Also avoid it on commits that are tagged or referenced in release notes. If you need to remove sensitive data, use git filter-branch or git filter-repo instead. For simple message changes on the last commit, git commit --amend is faster. And if you're on a deadline, don't clean up history — just merge and move on. Perfection is the enemy of shipping.
The 47-Commit Trainwreck That Broke CI
git rebase --onto only for local cleanup before push.- Interactive rebase rewrites commit SHAs — treat it as a local-only operation.
- Once you push, the history is public.
git status to see conflicted files. 2. Resolve conflicts manually. 3. git add . 4. git rebase --continue. 5. If stuck, git rebase --abort to return to original state.git reflog to find the pre-rebase state. 2. git reset --hard HEAD@{N} to restore. 3. Re-attempt rebase with correct instructions.git fetch origin 2. git rebase origin/main 3. git push --force-with-lease (safer than --force).git statusgit diffgit add ., git rebase --continue| File | Command / Code | Purpose |
|---|---|---|
| messy-history.bash | git init messy-repo | Why Interactive Rebase Exists |
| squash-example.bash | git log --oneline | Squashing Commits |
| reword-example.bash | git rebase -i HEAD~2 | Rewording Commits |
| edit-example.bash | git rebase -i HEAD~3 | Editing Commits |
| reorder-example.bash | git rebase -i HEAD~3 | Reordering Commits |
Key takeaways
git reflog before a risky rebaseInterview Questions on This Topic
How does interactive rebase handle merge commits? What happens if you try to rebase a branch that contains merge commits?
git rebase drops merge commits and linearizes history. Use git rebase --preserve-merges (deprecated) or --rebase-merges to keep them. Without it, the merge is flattened, which can lose the context of branch integration.Frequently Asked Questions
20+ years shipping production infrastructure and CI/CD at scale. Everything here is grounded in real deployments.
That's Git. Mark it forged?
3 min read · try the examples if you haven't