Home/Learn/Git/Interactive Rebase — Rewrite History Like a Pro

Interactive Rebase — Rewrite History Like a Pro

Advanced
Advanced

git rebase -i lets you reorder, squash, edit, split, or drop commits before merging. It is the tool for turning a messy development history into clean, reviewable commits.

Overview

During development, it is natural to make messy commits: "WIP", "fix typo", "actually fix it", "add tests finally". Interactive rebase lets you clean this up before submitting a PR — squash related commits, rewrite vague messages, reorder to tell a coherent story, or drop accidental debug commits. This is the difference between a commit history that reads like documentation and one that reads like a rough draft. Remember the golden rule: only rebase commits that have NOT been pushed to shared branches.

Interactive Rebase Commands

git rebase -i opens an editor showing all commits in the range. You change the command word before each commit to control what happens.

Interactive rebase commands
# Open interactive rebase for last 5 commits
git rebase -i HEAD~5

# The editor opens with:
# pick a3f8c12 Add user registration
# pick 9d2e441 WIP login
# pick 7b2e441 fix typo
# pick 3d9f2e0 fix login properly
# pick 2c1a8b7 add tests for login
#
# Commands:
# pick   = use commit as-is
# reword = use commit but edit message
# edit   = stop to amend the commit
# squash = meld into previous commit (keep both messages)
# fixup  = meld into previous commit (discard this message) ← most common
# drop   = remove the commit entirely
# reorder= just rearrange the lines

# Modified:
# pick a3f8c12 Add user registration
# reword 9d2e441 WIP login         ← fix the message
# fixup 7b2e441 fix typo           ← squash into previous
# squash 3d9f2e0 fix login properly ← squash, keep message
# pick 2c1a8b7 add tests for login

Common Patterns: Squash, Fixup, Reword

Three patterns cover 90% of interactive rebase use: squash/fixup (combine commits), reword (fix messages), and drop (remove commits).

Squash, fixup, drop patterns
# ── SQUASH related commits before a PR ──────────────────

# Before (messy):
# 7b2e441 WIP: payment
# a3f8c12 fix payment validation
# 9d2e441 actually fix it
# 3d9f2e0 add payment tests

# git rebase -i HEAD~4, then change to:
# pick 7b2e441 WIP: payment
# squash a3f8c12 fix payment validation
# squash 9d2e441 actually fix it
# squash 3d9f2e0 add payment tests

# After (clean, single commit):
# f1a2b3c Implement payment gateway with validation and tests

# ── FIXUP (squash without keeping the message) ────────────

# pick 7b2e441 Implement payment gateway
# fixup a3f8c12 fix typo            ← message discarded
# fixup 9d2e441 fix another typo    ← message discarded

# ── DROP debug commits ────────────────────────────────────

# pick a3f8c12 Add payment gateway
# drop 9d2e441 console.log debug    ← completely removed
# pick 7b2e441 Add payment tests

Splitting a Commit

Sometimes a commit does too much and should be two. Use edit to stop on a commit, reset it, then stage and commit the pieces separately.

Splitting a commit into two
# git rebase -i HEAD~3
# Change the target commit from "pick" to "edit":
# pick a3f8c12 Previous commit
# edit 9d2e441 Add auth AND payment (too much!)  ← change to edit
# pick 7b2e441 Later commit

# Git pauses at that commit. Undo it (keep changes in working dir):
git reset HEAD~1

# Now stage and commit in two pieces:
git add src/auth/
git commit -m "Add user authentication"

git add src/payment/
git commit -m "Add payment gateway"

# Continue the rebase
git rebase --continue

Key Points to Remember

  • 1git rebase -i HEAD~N opens the last N commits for editing — reorder, squash, fixup, drop, reword
  • 2fixup silently discards the commit message and merges changes into the previous commit
  • 3squash merges changes AND combines both commit messages (prompts you to edit the result)
  • 4Use edit to split one commit into multiple: reset HEAD~1, then stage/commit in pieces, rebase --continue
  • 5Never interactive rebase commits already pushed to a shared remote branch

Interview Questions

Sign in to ask Aria
1

How do you combine multiple commits into one using Git?

Medium
2

What is the difference between squash and fixup in interactive rebase?

Medium
3

How would you split a commit that contains two unrelated changes?

Hard

Ask Aria about Interactive Rebase — Rewrite History Like a Pro

Your personal AI tutor — ask anything about this concept

Revision Status

Personal Notes

Sign in to save personal notes for this topic.

Discussion

Sign in to join the discussion.

Loading discussion…