Git Rebase
Git rebase is a powerful command that allows you to integrate changes from one branch into another. Unlike `git merge`, which creates a new commit to combine the histories of two branches, `git rebase` moves or applies commits from one branch on top of another, effectively re-writing the commit history.
Basic Usage
The basic syntax for rebasing is:
git rebase <base-branch>
This command takes all the commits from your current branch that aren't in <base-branch>
and replays them on top of <base-branch>
.
Interactive Rebasing
Interactive rebasing gives you more control over how commits are applied. You can reorder, edit, squash, or drop commits during the process.
git rebase -i <base-branch>
When you run this command, Git will open your default text editor with a list of commits and instructions:
pick f7f3f6d Change feature A
pick 310154e Fix typo in feature A
pick a5f4a0d Add feature B
# 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
# x, exec = run command (the rest of the line) using shell
# d, drop = remove commit
When to Use Rebase
Rebasing is particularly useful in the following scenarios:
-
Before merging a feature branch: Rebase your feature branch onto the main branch to incorporate the latest changes and ensure your feature works with the most recent code.
-
Cleaning up local commits: Use interactive rebasing to clean up your local commits before sharing them with others.
-
Maintaining a linear history: If you prefer a clean, linear project history without merge commits.
Rebase vs. Merge
Aspect | Rebase | Merge |
---|---|---|
History | Rewrites commit history | Preserves commit history |
Structure | Creates a linear history | Creates a branched history with merge commits |
Best for | Local branches before sharing | Public/shared branches |
Conflicts | Can cause conflicts that need manual resolution | Can also cause conflicts but preserves the branch structure |
The Golden Rule of Rebasing
Never rebase branches that others are working on.
Rebasing changes commit history, which can cause problems for other developers who have based their work on the original commits. Only rebase your own local branches that haven't been pushed yet, or branches that you're certain no one else is using.
Handling Rebase Conflicts
During a rebase, conflicts might occur if the same part of a file was modified in both the current branch and the base branch. When this happens:
- Git will pause the rebase and show you which files have conflicts
- Edit the files to resolve the conflicts
- Add the resolved files with
git add <file>
- Continue the rebase with
git rebase --continue
- If you want to abort the rebase, use
git rebase --abort
Advanced Rebase Techniques
Squashing Commits
You can use interactive rebasing to combine multiple commits into one:
git rebase -i HEAD~3 # To work with the last 3 commits
Then change pick
to squash
or s
for the commits you want to combine.
Splitting Commits
To split a commit into multiple commits:
- Start an interactive rebase:
git rebase -i HEAD~n
- Change
pick
toedit
for the commit you want to split - When the rebase stops at that commit, reset it:
git reset HEAD^
- Stage and commit the changes in multiple commits
- Continue the rebase:
git rebase --continue
Examples
Rebasing a feature branch onto main
# From your feature branch
git checkout feature
git rebase main
Squashing the last 3 commits
git rebase -i HEAD~3
# Change the second and third commits from "pick" to "squash"
# Save and close the editor
# Edit the combined commit message
Best Practices
- Rebase frequently to minimize conflicts
- Only rebase unpublished commits to avoid disrupting collaboration
- Test after rebasing to ensure your changes still work
- Communicate with your team about your rebasing strategy