Concepts

Git Rebase Deep Dive

Understand Git Rebase internals, interactive rebasing, conflict resolution strategies, and best practices.

Who This Is For
  • Readers who want the history model before advanced commands
Prerequisites
  • A basic sense that commits are not just a file list
Common Risks
  • Treating a concepts page like a command how-to

What you will learn

  • Understand the core purpose of Git Rebase Deep Dive
  • Master the basic usage and common options of Git Rebase Deep Dive
  • Understand Git Rebase internals, interactive rebasing, conflict resolution strategies, and best practices.
  • Understand key concepts: Overview
  • Know when to use this feature and when to avoid it

Start with a problem

You've encountered a conceptual question while using Git — you roughly know what it means, but you're not entirely sure about its precise definition and boundaries.

Overview

git rebase is one of Git's most powerful—and dangerous—commands. It rewrites history by replaying commits, commonly used to:

  • Linearize history
  • Edit commit messages, split/squash commits
  • Sync feature branches with latest upstream

Internal Mechanics

How It Works

flowchart LR
  A[Original branch] --> B[Compute diff]
  B --> C[Create temp area]
  C --> D[Apply patches one by one]
  D --> E[Generate new commits]
  E --> F[Update branch pointer]

Rebase actually:

  1. Finds the fork point (merge-base)
  2. Saves current branch commits as patch sequence
  3. Switches to target branch
  4. Applies patches one by one (via git am or internal sequencer)
  5. Updates branch ref to new commit chain

Sequencer (git-rebase--sequencer)

Git 2.30+ uses a C-rewritten sequencer with major performance gains:

  • Native merge conflict handling
  • Supports --autosquash, --fixup, --squash
  • Better progress reporting

Interactive Rebase

git rebase -i HEAD~5
# Or target a branch
git rebase -i main

Common Commands

CommandShortEffect
pickpKeep commit
rewordrEdit commit message
editePause, amend content
squashsMeld into previous commit
fixupfMeld, discard message
dropdDiscard commit
execxRun shell command
breakbPause here
labellLabel current position
reset-Reset to label
mergemCreate merge commit

Practical Patterns

# Auto-squash fixup!/squash! commits
git rebase -i --autosquash main

# Preserve merge commits (don't flatten)
git rebase -i --rebase-merges main

# Only rewrite commit messages
git rebase -i --rebase-merges --committer-date-is-author-date HEAD~3

Conflict Resolution

During Rebase

# Rebase pauses on conflict
# After resolving:
git add <resolved-files>
git rebase --continue

# Abort entirely
git rebase --abort

# Skip current commit (dangerous)
git rebase --skip

Strategies

# Use merge tool
git mergetool

# Keep our version
git checkout --ours <file>

# Keep their version
git checkout --theirs <file>

# Show conflict markers
git diff --check

Advanced Usage

--rebase-merges Preserves Topology

# Preserve merge commit topology
git rebase -i --rebase-merges main

The generated todo list uses label, reset, merge for precise merge topology control.

Rebasing Branches with Merges

# Default: flattens merges
git rebase main

# Preserve merge structure
git rebase --rebase-merges main

Signatures & Dates

# Keep author date, use now as committer date
git rebase --committer-date-is-author-date

# Re-sign all commits
git rebase --signoff main

Best Practices

  1. Only rebase local unpushed commits — rebasing pushed breaks others' history
  2. Use --autosquash with fixup!/squash! — mark at commit time, auto-squash on rebase
  3. Create backup branch before large rebasegit branch backup-before-rebase
  4. Use --rebase-merges to preserve merge topology — avoids flattening complex merges
  5. Small frequent rebases — easier conflict resolution than one big rebase

Common Pitfalls

PitfallConsequenceAvoidance
Rebase pushed branchTeam history divergenceOnly rebase local branches
git rebase --skip mid-rebaseLost commitsResolve conflicts carefully, don't skip
Forget --rebase-mergesLost merge topologyAdd flag for complex branch structures
Rebase with dirty worktreeFailure or pollutiongit stash or commit first

Try it yourself

  1. Practice the git-rebase-deep command in a test repository and observe state changes before and after
  2. Experiment with different options and compare the output differences
  3. Simulate a real scenario where you would need to use this, and walk through the full process

Continue Learning

  1. commands/git-rebase — git rebase command reference
  2. internals/rebase-internals-and-sequencer — Rebase internals
  3. concepts/git-merge-deep — Git Merge Deep Dive
  4. workflows/prepare-commits-before-pull-request — Pre-PR commit cleanup