TechLead
Lesson 3 of 9
5 min read
Advanced Git

Interactive Rebase Mastery

Learn to rewrite history, squash commits, reorder changes, and clean up your commit history.

Interactive Rebase

Interactive rebase is one of Git's most powerful features for crafting a clean, logical commit history.

Basic Interactive Rebase

# Rebase last 5 commits
git rebase -i HEAD~5

# Rebase from a specific commit
git rebase -i abc123

# Rebase onto main
git rebase -i main

Rebase Commands

# In the editor, you'll see:
pick abc1234 First commit
pick def5678 Second commit
pick ghi9012 Third commit

# Available commands:
# p, pick   = use commit as-is
# r, reword = use commit, but edit message
# e, edit   = use commit, but stop for amending
# s, squash = meld into previous commit
# f, fixup  = like squash, but discard message
# x, exec   = run shell command
# b, break  = stop here (continue with 'git rebase --continue')
# d, drop   = remove commit
# l, label  = label current HEAD
# t, reset  = reset HEAD to a label

Squashing Commits

# Start interactive rebase
git rebase -i HEAD~4

# In editor, change:
pick abc1234 Add feature
pick def5678 Fix typo
pick ghi9012 More fixes
pick jkl3456 Final polish

# To:
pick abc1234 Add feature
squash def5678 Fix typo
squash ghi9012 More fixes
squash jkl3456 Final polish

# Then edit the combined commit message

Reordering Commits

# Simply reorder lines in the editor
git rebase -i HEAD~4

# Change from:
pick abc1234 Add CSS
pick def5678 Add HTML
pick ghi9012 Add JavaScript

# To (reorder):
pick def5678 Add HTML
pick abc1234 Add CSS
pick ghi9012 Add JavaScript

Editing a Commit

# Mark commit for editing
git rebase -i HEAD~3

# Change 'pick' to 'edit':
edit abc1234 Commit to modify
pick def5678 Next commit

# Git stops at that commit
# Make changes...
git add .
git commit --amend

# Continue rebase
git rebase --continue

Splitting a Commit

# Mark commit for editing
git rebase -i HEAD~2

# Change to 'edit'
edit abc1234 Big commit to split

# Reset to before the commit
git reset HEAD^

# Create multiple commits
git add file1.js
git commit -m "Add file1"

git add file2.js
git commit -m "Add file2"

git rebase --continue

Autosquash

# Create fixup commits
git commit --fixup=abc1234
git commit --squash=def5678

# Rebase with autosquash
git rebase -i --autosquash HEAD~5

# Or enable globally
git config --global rebase.autosquash true

Using exec

# Run tests after each commit
git rebase -i HEAD~5

# Add exec commands:
pick abc1234 First commit
exec npm test
pick def5678 Second commit
exec npm test

# Or add exec after every pick
git rebase -i HEAD~5 --exec "npm test"

Handling Conflicts

# When conflicts occur
git status  # See conflicting files
# Edit files to resolve conflicts

git add resolved-file.js
git rebase --continue

# Or abort if needed
git rebase --abort

# Skip problematic commit
git rebase --skip

Rebase Preserving Merges

# Preserve merge commits during rebase
git rebase -i --rebase-merges main

# In editor, you'll see labels:
label onto
reset onto
pick abc1234 Commit 1
label branch-a
reset onto
pick def5678 Commit 2
merge -C merge123 branch-a # Merge branch-a

Best Practices

# Never rebase shared/pushed commits!
# Only rebase local, unpushed work

# Create backup branch before complex rebase
git branch backup-branch

# Use reflog to recover if things go wrong
git reflog
git reset --hard HEAD@{2}

# Preview what will be rebased
git log --oneline main..HEAD

Rebase vs Merge

Rebase Merge
Linear history Preserves branch history
Cleaner log Shows when branches merged
Rewrites history Non-destructive
Use for local branches Use for shared branches

Continue Learning