Git - Rebasing Advanced
Advanced
Advanced rebasing techniques allow you to rewrite Git history, clean up commits, and create professional-quality commit sequences. Master these powerful tools to maintain pristine project history.
Interactive Rebase Fundamentals
Interactive rebase lets you modify commits during the rebase process:
# Start interactive rebase for last 5 commits
git rebase -i HEAD~5
# Interactive rebase from specific commit
git rebase -i abc1234^
# Interactive rebase onto branch
git rebase -i main
Interactive Rebase Commands
# Interactive rebase editor shows:
pick f7f3f6d Change my name a bit
pick 310154e Update README formatting
pick a5f4a0d Add support for new feature
# Available commands:
# p, pick = use commit as-is
# r, reword = use commit, but edit commit message
# e, edit = use commit, but stop for amending
# s, squash = use commit, but meld into previous commit
# f, fixup = like squash, but discard commit message
# x, exec = run command (the rest of the line) using shell
# b, break = stop here (continue rebase later with 'git rebase --continue')
# d, drop = remove commit
# l, label = label current HEAD with a name
# t, reset = reset HEAD to a label
# m, merge = create a merge commit using the original merge commit's message
Common Interactive Rebase Operations
Squashing Commits
# Original commits:
pick f7f3f6d Add user authentication
pick 310154e Fix typo in auth function
pick a5f4a0d Update auth tests
pick b8c2f1e Fix auth test failures
# Squash into single commit:
pick f7f3f6d Add user authentication
squash 310154e Fix typo in auth function
squash a5f4a0d Update auth tests
squash b8c2f1e Fix auth test failures
# Result: One clean commit with combined changes
Fixup Commits
# Create fixup commit
git commit --fixup=abc1234
# Automatically squash fixups during rebase
git rebase -i --autosquash HEAD~10
# Original sequence becomes:
pick abc1234 Original commit
fixup def5678 fixup! Original commit
Rewording Commit Messages
# Reword commit messages
pick f7f3f6d Add user authentication
reword 310154e Fix typo in auth function
pick a5f4a0d Update auth tests
# Git will open editor for each 'reword' commit
Advanced Rebase Strategies
Onto Different Branches
# Rebase onto different branch
git rebase main feature-branch
# Rebase with specific upstream and branch
git rebase --onto main develop feature-branch
# Complex rebase: move commits from one base to another
git rebase --onto new-base old-base branch-to-move
# Example: Extract commits from feature to new branch
# Original: main---A---B---C (develop)
# \---D---E---F (feature)
# Goal: main---A---B---C (develop)
# \---D---E---F (feature, rebased onto main)
git rebase --onto main develop feature
Preserving Merges
# Preserve merge commits during rebase
git rebase --preserve-merges main
# Rebase with merge commit recreation
git rebase --rebase-merges main
# Interactive rebase preserving merge structure
git rebase -i --rebase-merges HEAD~10
Commit Splitting and Editing
Splitting Large Commits
# Mark commit for editing
edit f7f3f6d Large commit with multiple changes
# During rebase, Git stops at the commit
# Reset the commit but keep changes staged
git reset HEAD^
# Selectively add and commit parts
git add file1.js
git commit -m "Add user validation"
git add file2.js
git commit -m "Add password hashing"
git add file3.js
git commit -m "Add session management"
# Continue rebase
git rebase --continue
Editing Commit Content
# Stop at commit for editing
edit abc1234 Commit to modify
# Make changes to files
vim src/auth.js
# Amend the commit
git add src/auth.js
git commit --amend
# Continue rebase
git rebase --continue
Complex History Rewriting
Reordering Commits
# Original order:
pick f7f3f6d Add feature A
pick 310154e Add feature B
pick a5f4a0d Fix feature A bug
pick b8c2f1e Add feature C
# Reorder to group related commits:
pick f7f3f6d Add feature A
pick a5f4a0d Fix feature A bug
pick 310154e Add feature B
pick b8c2f1e Add feature C
Removing Commits
# Drop unwanted commits
pick f7f3f6d Add user authentication
drop 310154e Temporary debug code
pick a5f4a0d Update auth tests
drop b8c2f1e More debug code
# Or delete the line entirely (same as drop)
Adding New Commits Mid-History
# Stop for adding new commit
edit f7f3f6d Add user authentication
# Create new commit at this point
echo "New file" > newfile.txt
git add newfile.txt
git commit -m "Add configuration file"
# Continue with original sequence
git rebase --continue
Automated Rebase Workflows
Autosquash Workflow
# Create commits with automatic squash markers
git commit -m "Add user authentication"
# ... later, find issue in previous commit
git add fix.js
git commit --fixup=HEAD~2
# Auto-squash during rebase
git rebase -i --autosquash HEAD~10
# Configure automatic autosquash
git config rebase.autosquash true
Exec Commands in Rebase
# Run commands during rebase
pick f7f3f6d Add user authentication
exec npm test
pick 310154e Add password validation
exec npm run lint
pick a5f4a0d Update documentation
exec npm run build
# Rebase will run each command and stop if any fail
Advanced Conflict Resolution
Handling Rebase Conflicts
# During rebase conflict
git status # See conflicted files
git mergetool # Use merge tool
# Or edit manually
vim conflicted-file.js
# Mark as resolved and continue
git add conflicted-file.js
git rebase --continue
# Skip problematic commit
git rebase --skip
# Abort entire rebase
git rebase --abort
Rebase with Strategy Options
# Rebase with merge strategy
git rebase -X ours main
git rebase -X theirs main
# Rebase ignoring whitespace
git rebase -X ignore-space-change main
# Use patience algorithm
git rebase -X patience main
Branch Surgery Techniques
Moving Commit Ranges
# Move commits D, E, F from develop to main
# Before: main---A---B---C
# develop---D---E---F---G
git rebase --onto main develop~3 develop
# Result: main---A---B---C---D---E---F
# develop---G
Cherry-Pick Range with Rebase
# Pick specific commit range and rebase
git rebase --onto target-branch start-commit end-commit
# Example: Move commits 3-7 from feature to main
git rebase --onto main feature~5 feature~1
Rebase Transplanting
# Transplant branch from old base to new base
# Before: old-base---A---B (branch)
# new-base---C---D
git checkout branch
git rebase --onto new-base old-base
# Result: new-base---C---D---A---B (branch)
Interactive Rebase Scripting
Custom Rebase Scripts
#!/bin/bash
# auto-rebase.sh - Automated interactive rebase
# Generate rebase script
cat > /tmp/rebase-script << 'EOF'
pick HEAD~4
squash HEAD~3
reword HEAD~2
edit HEAD~1
EOF
# Set custom editor
export GIT_SEQUENCE_EDITOR="cp /tmp/rebase-script"
git rebase -i HEAD~5
Rebase with Hooks
# Pre-rebase hook (.git/hooks/pre-rebase)
#!/bin/bash
echo "Starting rebase of $1 onto $2"
# Check if rebase is safe
if [ "$1" = "main" ]; then
echo "Cannot rebase main branch"
exit 1
fi
# Post-rewrite hook (.git/hooks/post-rewrite)
#!/bin/bash
if [ "$1" = "rebase" ]; then
echo "Rebase completed successfully"
# Update documentation, run tests, etc.
fi
Performance and Large Repository Rebase
Optimizing Large Rebases
# Speed up rebase with better algorithms
git config rebase.stat false
git config rebase.autoSquash true
# Use faster merge strategy
git rebase -X histogram main
# Rebase with limited context
git rebase --committer-date-is-author-date main
Shallow Repository Rebase
# Unshallow before rebase
git fetch --unshallow
# Rebase with limited history
git rebase --root main # Rebase from initial commit
Advanced Rebase Patterns
Feature Branch Cleanup
#!/bin/bash
# cleanup-feature.sh - Clean up feature branch before merge
FEATURE_BRANCH=$(git branch --show-current)
# Squash all commits into logical chunks
git rebase -i $(git merge-base main $FEATURE_BRANCH)
# Rebase onto latest main
git fetch origin main
git rebase origin/main
echo "Feature branch $FEATURE_BRANCH cleaned up"
Release Preparation Rebase
# Prepare clean release history
git checkout release/v2.0
# Interactive rebase to clean up commits
git rebase -i --autosquash develop
# Ensure linear history
git rebase main
# Final cleanup
git rebase -i HEAD~20 # Review last 20 commits
Collaborative Rebase Strategies
Safe Collaborative Rebase
# Check if branch has been pushed
if git merge-base --is-ancestor HEAD origin/feature-branch; then
echo "Branch already pushed, rebase may be dangerous"
exit 1
fi
# Safe rebase workflow
git fetch origin
git rebase origin/main
git push --force-with-lease origin feature-branch
Team Rebase Policies
# Team rebase guidelines script
#!/bin/bash
# team-rebase-policy.sh
BRANCH=$1
BASE_BRANCH=${2:-main}
# Only allow rebase on feature branches
if [[ ! $BRANCH =~ ^feature/ ]]; then
echo "Rebase only allowed on feature branches"
exit 1
fi
# Check if branch is up to date with base
git fetch origin $BASE_BRANCH
if ! git merge-base --is-ancestor origin/$BASE_BRANCH $BRANCH; then
echo "Please rebase onto latest $BASE_BRANCH first"
exit 1
fi
git rebase -i origin/$BASE_BRANCH
Troubleshooting Advanced Rebase
Recovery from Failed Rebase
# Find rebase state
ls -la .git/rebase*
# Check reflog for recovery
git reflog HEAD
# Reset to before rebase
git reset --hard HEAD@{5} # Adjust index as needed
# Alternative: use ORIG_HEAD
git reset --hard ORIG_HEAD
Debugging Rebase Issues
# Enable rebase debugging
export GIT_TRACE=1
git rebase -i HEAD~5
# Check rebase todo file
cat .git/rebase-merge/git-rebase-todo
# Check current rebase state
cat .git/rebase-merge/head-name
cat .git/rebase-merge/onto
Best Practices
Advanced Rebase Best Practices:
- Never rebase public/shared branches
- Use --force-with-lease for safer force pushes
- Test thoroughly after complex rebases
- Keep rebase operations focused and small
- Document complex rebase procedures
- Use interactive rebase to create logical commit progression
Professional Rebase Workflow
# Professional feature development workflow
git checkout -b feature/user-auth
# ... development work ...
# Before merging: clean up history
git rebase -i $(git merge-base main HEAD)
git rebase main # Update to latest
# Final check
git log --oneline main..HEAD # Review commits
npm test # Ensure tests pass
# Safe push
git push --force-with-lease origin feature/user-auth
Integration with Development Tools
IDE Integration
# VS Code rebase tasks
{
"version": "2.0.0",
"tasks": [
{
"label": "Interactive Rebase",
"type": "shell",
"command": "git",
"args": ["rebase", "-i", "HEAD~${input:commitCount}"],
"group": "build"
}
]
}
Automated Quality Gates
# Pre-push hook with rebase validation
#!/bin/bash
# .git/hooks/pre-push
protected_branch='main'
current_branch=$(git symbolic-ref HEAD | sed -e 's,.*/\(.*\),\1,')
if [ $protected_branch = $current_branch ]; then
echo "Direct push to main not allowed"
exit 1
fi
# Ensure branch is rebased on main
if ! git merge-base --is-ancestor main HEAD; then
echo "Please rebase on main before pushing"
exit 1
fi
Key Takeaways
- History Perfection: Interactive rebase creates clean, logical commit sequences
- Flexibility: Advanced rebase operations handle complex history rewriting
- Collaboration: Use rebase safely in team environments with proper protocols
- Quality: Clean commits improve code review and project maintenance
- Professionalism: Master rebasing for professional-grade Git workflows
Advanced rebasing transforms messy development history into clean, professional commit sequences. Master these techniques to maintain high-quality project history and improve collaboration in complex development environments.