Home DevOps Interactive Rebase: Squash, Reword, Edit and Reorder Commits Like a Pro
Intermediate 3 min · July 07, 2026

Interactive Rebase: Squash, Reword, Edit and Reorder Commits Like a Pro

Interactive rebase: squash, reword, edit, reorder commits.

N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Everything here is grounded in real deployments.

Follow
Production
production tested
July 07, 2026
last updated
214
articles · all by Naren
Before you start⏱ 25 min
  • Basic Git commit workflow
  • Comfortable with command line
  • Understanding of Git history as a DAG
 ● Production Incident 🔎 Debug Guide ⚙ Triage Commands
Quick Answer

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.

✦ Definition~90s read
What is Interactive Rebase?

Interactive rebase is a Git command that lets you rewrite commit history by squashing, rewording, editing, or reordering commits. It's the power tool for cleaning up messy local branches before merging.

Imagine you're writing a report and you've made several rough drafts.
Plain-English First

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.

messy-history.bashBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# io.thecodeforge — DevOps tutorial

# Simulate a messy branch
git init messy-repo
cd messy-repo
echo "first draft" > file.txt
git add . && git commit -m "Add feature X"
echo "fix typo" >> file.txt
git add . && git commit -m "fix typo"
echo "actually working" > file.txt
git add . && git commit -m "WIP"
echo "final version" > file.txt
git add . && git commit -m "final"

# Now clean it up with interactive rebase
git rebase -i HEAD~4
# In editor: squash the last 3 commits into the first, reword the first commit
# Result: one clean commit "Add feature X"
Output
Successfully rebased and updated refs/heads/main.
Never Do This:
Never interactive rebase a branch that has been pushed to a shared remote. You'll rewrite commit SHAs, causing chaos for anyone who based work on the old history. If you must, coordinate with the team and force-push with --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.

squash-example.bashBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# io.thecodeforge — DevOps tutorial

# Start with a branch that has 3 commits for one feature
git log --oneline
# Output:
# a1b2c3d Add payment validation
# e4f5g6h Fix null pointer in validation
# i7j8k9l Add unit tests for validation

# Squash the last two into the first
git rebase -i HEAD~3
# In editor, change to:
# pick a1b2c3d Add payment validation
# squash e4f5g6h Fix null pointer in validation
# squash i7j8k9l Add unit tests for validation
# Save and exit, then write a new commit message: "Add payment validation with tests"

# Result: one commit
git log --oneline
# Output:
# m1n2o3p Add payment validation with tests
Output
Successfully rebased and updated refs/heads/main.
Senior Shortcut:
Use 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.

reword-example.bashBASH
1
2
3
4
5
6
7
8
9
# io.thecodeforge — DevOps tutorial

# Change the message of the last 2 commits
git rebase -i HEAD~2
# In editor, change 'pick' to 'reword' on the commits you want to edit
# Save and exit, then Git opens an editor for each reworded commit
# Write the new message and save

# Example: change "fix bug" to "fix: correct off-by-one error in pagination"
Output
Successfully rebased and updated refs/heads/main.
Production Trap:
Rewording a commit that's already in a shared branch (e.g., main) will change its SHA. This breaks any tags or references to that commit. Only reword commits that are local or in a feature branch you control.

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.

edit-example.bashBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
# io.thecodeforge — DevOps tutorial

# Suppose commit a1b2c3d added both login and logout. You want to split them.
git rebase -i HEAD~3
# Mark a1b2c3d as 'edit', save and exit
# Git stops at that commit

# Now reset to the previous commit, keeping changes staged
git reset HEAD^
# Now you have unstaged changes for both login and logout

# Stage and commit login only
git add login.html login.js
git commit -m "Add login page"

# Stage and commit logout only
git add logout.html logout.js
git commit -m "Add logout page"

# Continue rebase
git rebase --continue
Output
Stopped at a1b2c3d... Add login and logout
You can amend the commit now, with
git commit --amend
Once you are satisfied, run:
git rebase --continue
The Classic Bug:
If you forget to stage changes after editing, Git will treat the commit as empty and abort. Always run 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.

reorder-example.bashBASH
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
# io.thecodeforge — DevOps tutorial

# Current order:
# 1: Add user model
# 2: Add admin panel
# 3: Add user authentication

# You want authentication before admin panel
git rebase -i HEAD~3
# In editor, reorder lines:
# pick <hash> Add user model
# pick <hash> Add user authentication
# pick <hash> Add admin panel
# Save and exit

# Git will apply commits in the new order. If conflicts occur, resolve them and run:
git add .
git rebase --continue
Output
Successfully rebased and updated refs/heads/main.
Senior Shortcut:
Before reordering, check dependencies with 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.

Interview Gold:
Interviewers love asking: 'When would you NOT use interactive rebase?' The answer: when the branch is shared, when commits are tagged, when you need to remove sensitive data (use filter-repo), or when you're in a time crunch. Knowing when not to use a tool is a sign of seniority.
● Production incidentPOST-MORTEMseverity: high

The 47-Commit Trainwreck That Broke CI

Symptom
CI pipeline failed with merge conflicts on every PR. Team spent hours resolving the same conflicts.
Assumption
Team assumed it was a merge strategy issue — maybe they needed to rebase onto main more often.
Root cause
A junior dev had rebased a shared feature branch that 3 other devs had based their work on. The rewritten commits caused Git to see entirely new histories, leading to repeated conflicts.
Fix
Established a rule: never interactive rebase a branch that others have pushed to or based work on. Use git rebase --onto only for local cleanup before push.
Key lesson
  • Interactive rebase rewrites commit SHAs — treat it as a local-only operation.
  • Once you push, the history is public.
Production debug guideSystematic recovery paths for the failure modes engineers actually hit.3 entries
Symptom · 01
Rebase aborts with 'could not apply' and a conflict
Fix
1. Run 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.
Symptom · 02
After rebase, commits are missing or duplicated
Fix
1. Check git reflog to find the pre-rebase state. 2. git reset --hard HEAD@{N} to restore. 3. Re-attempt rebase with correct instructions.
Symptom · 03
Force push rejected because remote has new commits
Fix
1. git fetch origin 2. git rebase origin/main 3. git push --force-with-lease (safer than --force).
★ Interactive Rebase Triage Cheat SheetFirst-response commands for when things go wrong — copy-paste ready.
Rebase conflict: `could not apply <hash>...`
Immediate action
Check which files are conflicted
Commands
git status
git diff
Fix now
Resolve conflicts, git add ., git rebase --continue
Accidentally aborted rebase and lost changes+
Immediate action
Check reflog for the lost state
Commands
git reflog
git reset --hard HEAD@{N}
Fix now
Find the commit before rebase and reset to it
Force push rejected due to remote changes+
Immediate action
Fetch and rebase onto remote
Commands
git fetch origin
git rebase origin/main
Fix now
git push --force-with-lease
Rebase left detached HEAD+
Immediate action
Check current branch
Commands
git branch
git log --oneline -5
Fix now
git checkout <branch> or git switch - to return
OperationUse CaseRisk LevelWhen to Avoid
SquashCombine multiple related commits into oneLowWhen commits are logically separate
RewordChange commit message onlyLowOn shared branches (changes SHA)
EditAmend or split a commit mid-historyHighWhen you can use git commit --amend instead
ReorderRearrange independent commitsMediumWhen commits have dependencies
⚙ Quick Reference
5 commands from this guide
FileCommand / CodePurpose
messy-history.bashgit init messy-repoWhy Interactive Rebase Exists
squash-example.bashgit log --onelineSquashing Commits
reword-example.bashgit rebase -i HEAD~2Rewording Commits
edit-example.bashgit rebase -i HEAD~3Editing Commits
reorder-example.bashgit rebase -i HEAD~3Reordering Commits

Key takeaways

1
Interactive rebase rewrites commit SHAs
never use it on shared branches.
2
Squash related commits into one logical change; reword to fix messages; edit to split commits; reorder to tell a better story.
3
Always check git reflog before a risky rebase
it's your safety net.
4
If you're on a deadline, skip the cleanup. Ship first, polish later.
INTERVIEW PREP · PRACTICE MODE

Interview Questions on This Topic

Q01SENIOR
How does interactive rebase handle merge commits? What happens if you tr...
Q02SENIOR
When would you choose interactive rebase over `git merge --squash` for c...
Q03SENIOR
What happens if you reorder two commits that both modify the same file? ...
Q04JUNIOR
What is the difference between `git rebase -i` and `git commit --amend`?
Q05SENIOR
You're in the middle of an interactive rebase and realize you made a mis...
Q06SENIOR
How would you design a Git workflow that minimizes the need for interact...
Q01 of 06SENIOR

How does interactive rebase handle merge commits? What happens if you try to rebase a branch that contains merge commits?

ANSWER
By default, 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.
FAQ · 4 QUESTIONS

Frequently Asked Questions

01
How do I squash the last 3 commits into 1 using interactive rebase?
02
What's the difference between squash and fixup in interactive rebase?
03
How do I change a commit message that's not the most recent?
04
Can I undo an interactive rebase after I've completed it?
N
Naren Founder & Principal Engineer

20+ years shipping production infrastructure and CI/CD at scale. Everything here is grounded in real deployments.

Follow
Verified
production tested
July 07, 2026
last updated
214
articles · all by Naren
🔥

That's Git. Mark it forged?

3 min read · try the examples if you haven't

Previous
Git Revert: Safe Undo for Pushed Commits
23 / 47 · Git
Next
Git Bisect: Find the Commit That Introduced a Bug