Git Rebasing
Git rebase is a powerful tool for maintaining a clean, linear project history. Unlike merging, which creates merge commits, rebasing rewrites history by moving commits to a new base. This tutorial covers the fundamentals of rebasing, when to use it, and best practices to avoid common pitfalls.
What is Rebasing?
Rebasing is the process of moving or combining a sequence of commits to a new base commit. Instead of creating a merge commit like git merge does, git rebase rewrites the project history by creating new commits for each commit in the original branch.
Basic Rebasing
Rebase onto Another Branch
# Switch to the branch you want to rebase
git checkout feature-branch
# Rebase onto main branch
git rebase mainThis moves all commits from feature-branch that aren’t in main to the tip of main.
Interactive Rebasing
Interactive rebase allows you to modify commits during the rebase process.
# Start interactive rebase for the last 3 commits
git rebase -i HEAD~3This opens an editor with options like:
pick: Keep the commit as isreword: Change the commit messageedit: Amend the commitsquash: Combine with previous commitfixup: Combine without keeping the messagedrop: Remove the commit
When to Use Rebase
Keeping Feature Branches Updated
# On your feature branch
git checkout feature/login
git rebase main
# Resolve any conflicts, then
git push --force-with-leaseCleaning Up Commit History
# Squash multiple small commits into one
git rebase -i HEAD~5
# In editor: change 'pick' to 'squash' for commits 2-5Incorporating Upstream Changes
# Update your local main branch
git checkout main
git pull origin main
# Rebase your feature branch
git checkout feature/new-feature
git rebase mainRebasing vs Merging
| Aspect | Merge | Rebase |
|---|---|---|
| History | Preserves all history | Creates linear history |
| Commits | Creates merge commit | Rewrites commits |
| Conflicts | Resolved once | May resolve multiple times |
| Safety | Safer for shared branches | Riskier for shared branches |
Handling Conflicts
Conflicts during rebase are resolved similarly to merge conflicts, but for each commit.
# After conflict occurs
git status # See conflicted files
# Edit files to resolve conflicts
git add <resolved-files>
git rebase --continue
# Or abort if too messy
git rebase --abortAdvanced Rebasing
Rebasing onto a Specific Commit
# Rebase feature branch onto a specific commit
git rebase abc123 feature-branchAutosquash for Fixup Commits
# Create a fixup commit
git commit --fixup HEAD~2
# Apply it automatically
git rebase -i --autosquash HEAD~3Preserving Merge Commits
# Rebase while keeping merge commits
git rebase --preserve-merges mainBest Practices
1. Don’t Rebase Public History
Never rebase commits that have been pushed to a shared repository.
# ✅ Good: Rebase local commits
git checkout feature/my-work
git rebase main
git push --force-with-lease origin feature/my-work
# ❌ Bad: Rebase shared branch
git checkout main
git rebase feature/some-branch # Don't do this!2. Use Force with Lease
When force pushing after rebase, use --force-with-lease instead of --force.
git push --force-with-lease origin feature-branch3. Rebase Frequently
Keep your branches up to date by rebasing regularly.
# Daily workflow
git checkout feature/my-feature
git fetch origin
git rebase origin/main4. Clean Commit History
Use interactive rebase to create meaningful commits.
# Before pushing, clean up your commits
git rebase -i origin/mainCommon Scenarios
Fixing a Mistake in Recent Commits
# Amend the last commit
git commit --amend
# Or rebase to fix older commits
git rebase -i HEAD~3
# Change 'pick' to 'edit' for the commit to fixSplitting a Large Commit
git rebase -i HEAD~2
# Change 'pick' to 'edit' for the large commit
git reset HEAD~1 # Uncommit but keep changes
git add -p # Stage changes in parts
git commit -m "First part"
git commit -m "Second part"
git rebase --continueReordering Commits
git rebase -i HEAD~4
# Reorder the lines in the editorWorking with Remote Branches
Pulling with Rebase
# Instead of merge, rebase when pulling
git pull --rebase origin mainRebasing a Branch with Remote Tracking
# Set up branch for rebase by default
git config branch.feature-branch.rebase true
# Or globally
git config pull.rebase trueTroubleshooting
Recovering from a Botched Rebase
# If rebase goes wrong, abort
git rebase --abort
# Or if you need to recover lost commits
git reflog
git reset --hard HEAD@{2} # Go back 2 stepsDealing with Empty Commits
# Sometimes rebase creates empty commits
git rebase -i HEAD~5
# Change empty commits to 'drop'Complete Workflow Example
# Start a feature
git checkout -b feature/user-auth
# Make some commits...
git commit -m "Add login form"
git commit -m "Add validation"
git commit -m "Fix typo"
# Keep branch updated
git fetch origin
git rebase origin/main
# Clean up commits before PR
git rebase -i origin/main
# Squash related commits, fix messages
# Force push (since history changed)
git push --force-with-lease origin feature/user-authSummary
Rebasing is a powerful tool for maintaining clean Git history:
- Use rebase for local branches and feature development
- Use merge for integrating completed features into main branches
- Never rebase commits that exist in shared repositories
- Always use
--force-with-leasewhen force pushing - Regular rebasing keeps branches current and reduces conflicts
Mastering rebase will help you maintain professional, clean Git repositories and collaborate more effectively with your team.
External Resources:
Related Tutorials: