Advanced Git Techniques: Rebasing
In previous lessons, you've learned how to merge branches to integrate changes. Now we'll explore rebasing, a powerful alternative to merging that creates a cleaner, linear project history. Rebasing allows you to replay your commits on top of another branch, giving you more control over your commit history.
Learning Goals:
- Understand when and why to use rebasing vs. merging
- Perform basic interactive rebasing
- Squash, edit, and reorder commits
- Resolve conflicts during rebase operations
- Follow rebasing best practices for collaborative workflows
What is Rebasing?
Rebasing is the process of moving or combining a sequence of commits to a new base commit. Think of it as "replaying" your changes on top of another branch's latest state.
# Current state: feature branch is behind main
git checkout feature-branch
git rebase main
This command takes all the commits from your current branch (feature-branch) that aren't in main and replays them on top of the latest main commit.
Rebasing vs. Merging
Let's compare the two approaches for integrating changes:
- Merging
- Rebasing
git checkout main
git merge feature-branch
Result: Creates a merge commit that joins the two branches, preserving the complete history.
git checkout feature-branch
git rebase main
git checkout main
git merge feature-branch
Result: Creates a linear history by replaying feature commits on top of main.
When to rebase:
- Cleaning up local commit history before sharing
- Keeping feature branches up-to-date with main
- Preparing for a clean merge
When to merge:
- Integrating completed features
- Collaborative branches with multiple contributors
- Preserving exact historical context
Interactive Rebasing
Interactive rebasing gives you fine-grained control over your commit history. You can squash commits, edit commit messages, reorder commits, and more.
git rebase -i HEAD~3
This opens your default editor with a list of commits and actions:
pick a1b2c3d Add user authentication
pick e4f5g6h Fix login bug
pick h7i8j9k Update documentation
# Rebase commands:
# p, pick = use commit
# r, reword = use commit, but edit the 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 this commit's log message
# d, drop = remove commit
Common Interactive Rebase Operations
Squashing commits:
pick a1b2c3d Add user authentication
squash e4f5g6h Fix login bug
squash h7i8j9k Update documentation
Rewording commit messages:
reword a1b2c3d Add user authentication
pick e4f5g6h Fix login bug
reword h7i8j9k Update documentation
Reordering commits:
pick e4f5g6h Fix login bug
pick a1b2c3d Add user authentication
pick h7i8j9k Update documentation
Handling Rebase Conflicts
Like merging, rebasing can encounter conflicts that need manual resolution.
git rebase main
# CONFLICT occurs...
# Resolve conflicts in your files, then:
git add resolved-file.js
git rebase --continue
# Or to abort the rebase:
git rebase --abort
Always communicate when rebasing shared branches! Rebasing rewrites history, which can cause issues for other developers who have based work on the old commits.
Practical Rebasing Scenarios
Keeping a Feature Branch Updated
# On your feature branch
git fetch origin
git rebase origin/main
# Or if you prefer merging for this case:
git merge origin/main
Cleaning Up Before Pull Request
# Squash all feature branch commits
git rebase -i main
# Force push (only for feature branches you own!)
git push --force-with-lease origin feature-branch
Common Pitfalls
- Rebasing published branches: Never rebase branches that others are working on
- Losing commits: Interactive rebasing with "drop" can permanently remove commits
- Force push dangers:
--force-with-leaseis safer than--forceas it checks if others have pushed - Complex conflict resolution: Rebasing multiple commits can require resolving the same conflict multiple times
- Timing issues: Rebasing while others are actively working on the same branch causes synchronization problems
Summary
Rebasing is a powerful tool for maintaining a clean, linear project history. Use it to:
- Keep feature branches up-to-date with main
- Clean up local commit history before sharing
- Create more readable project timelines
Remember the golden rule: Only rebase local commits, never rebase shared history unless you coordinate with your team.
Quiz
Git Rebase and History Rewriting – Quick Check
When should you avoid rebasing a branch?