Git rebase is a tool for simplifying and organizing commit history by replaying or moving commits onto a different base branch.
Below is a comprehensive guide to understanding and using Git Rebase effectively.
π What is Git Rebase?
Git rebase involves:
- Transferring or replaying commits from one branch to another.
- Rewriting commit history for a linear and streamlined commit sequence.
Unlike a merge, it applies your commits sequentially on top of the target branch without creating a new merge commit.
β Why Use Git Rebase?
| Benefit | Explanation |
|---|---|
| Clean History | Maintains a linear commit history, eliminating unnecessary merge commits. |
| Better Integration | Updates your branch with the latest changes from the target branch. |
| Improved Collaboration | Makes feature branch history more readable and easier to review. |
π οΈ How to Use Git Rebase
Syntax:
git rebase [options] [upstream]
| Option | Description |
|---|---|
git rebase <branch> |
Rebases the current branch onto <branch>. |
git rebase -i |
Interactive rebase to modify commit history. |
git rebase --onto |
Rebases commits onto a different branch, specifying a new base branch. |
git rebase --abort |
Aborts the rebase process, restoring the branch to its original state. |
git rebase --continue |
Resumes the rebase after resolving conflicts. |
git rebase --skip |
Skips the commit causing conflicts during rebase. |
π Examples
1. Rebase a Feature Branch onto Main
git checkout feature
git rebase main
-
Result: Applies
featurebranch commits on top of the latestmain.
2. Interactive Rebase
git rebase -i HEAD~3
- Purpose: Modify the last 3 commits interactively.
- Common Actions in Interactive Editor:
| Action | Description |
|--------------|----------------------------------------------------------|
| pick | Use the commit as is. |
| reword | Edit the commit message. |
| edit | Pause to amend the commit. |
| squash | Combine this commit with the previous one. |
| drop | Remove the commit entirely. |
3. Rebase with Conflict Resolution
git rebase main
# If conflicts occur:
git status
# Fix conflicts manually, then:
git add <fixed files>
git rebase --continue
- Result: Conflicts are resolved, and the rebase proceeds.
4. Rebase Onto a Different Branch
git rebase --onto main dev feature
-
Result: Moves commits from
feature(after it diverged fromdev) ontomain.
5. Abort a Rebase
git rebase --abort
- Purpose: Stops the rebase process and restores the branch to its pre-rebase state.
6. Skip a Conflicting Commit
git rebase --skip
- Purpose: Skips the conflicting commit and continues with the rebase.
π Understanding Upstream Commit in Rebase
An upstream commit is the shared ancestor or the base point between branches before divergence. It determines:
- Included Changes: Commits after the upstream commit are rebased.
- Excluded Changes: Commits up to the upstream commit remain unchanged.
π οΈ Advanced Usage: git rebase --onto
The git rebase --onto command helps reapply a range of commits from a branch onto a new base commit or branch. It is primarily used to:
- Move a branch to a new base while excluding unrelated commits.
- Filter out specific commits during a rebase operation.
Syntax and Explanation
Syntax 1: Rebasing by Commits
git rebase --onto <newBaseCommit> <excludeCommit> <lastCommit>
-
<newBaseCommit>: The new base commit onto which the selected commits will be rebased. -
<excludeCommit>: The commit after which the rebasing begins (excluded from the range). -
<lastCommit>: The last commit to include in the rebase.
Range Details: Commits between <excludeCommit> (exclusive) and <lastCommit> (inclusive) are rebased onto <newBaseCommit>.
Syntax 2: Rebasing by Branches
git rebase --onto <newBaseBranch> <oldBaseBranch> <targetBranch>
-
<newBaseBranch>: The branch to rebase onto (new base). -
<oldBaseBranch>: The branch serving as the previous base; commits unique to this branch are excluded. -
<targetBranch>: The branch whose commits will be rebased.
Range Details: Commits unique to <targetBranch> after <oldBaseBranch> are rebased onto <newBaseBranch>.
π οΈ Examples and Scenarios
Example 1: Rebasing with Commits
Command:
git rebase --onto F D I
Before:
A---B---C---F---G (main branch)
\
D---E---H---I (my-branch, HEAD)
After:
A---B---C---F---G (main branch)
\
E'---H'---I' (my-branch, HEAD)
- Commits
E,H, andIfrommy-branch(afterD) are reapplied ontoF. -
Dis excluded, and the rebased commits are represented asE',H', andI'.
Example 2: Rebasing with Branches
Scenario:
You have a feature branch (featureBranch) based on an outdated branch (oldBaseBranch). You want to rebase it onto the latest mainBranch.
Command:
git checkout featureBranch
git rebase --onto mainBranch oldBaseBranch featureBranch
Workflow:
- Commits unique to
featureBranchafteroldBaseBranchare identified. - These commits are replayed onto
mainBranch.
π οΈ Practical Example
Setup:
git checkout -b oldBaseBranch
# Create some initial commits
git commit --allow-empty -m "Base Commit A"
git commit --allow-empty -m "Base Commit B"
git checkout -b mainBranch oldBaseBranch
git commit --allow-empty -m "Commit C"
git commit --allow-empty -m "Commit D"
git checkout -b featureBranch oldBaseBranch
git commit --allow-empty -m "Feature Commit 1"
git commit --allow-empty -m "Feature Commit 2"
Rebase:
git checkout featureBranch
git rebase --onto mainBranch oldBaseBranch featureBranch
Result:
- The
featureBranchcommits (Feature Commit 1andFeature Commit 2) are moved ontomainBranch, excluding commits fromoldBaseBranch.
π Key Points to Remember
-
Excludes Commits: Commits from
<excludeCommit>or<oldBaseBranch>are skipped. -
Flexible Range: Use
<newBaseCommit>or<newBaseBranch>to restructure commit history without affecting unrelated commits. - Conflict Handling: Be prepared to resolve conflicts if rebased commits clash with the new base.
β οΈ Important Notes and Tips
| Tip | Explanation |
|---|---|
| Avoid Rebasing Shared Branches | Rebasing rewrites commit history, causing issues for collaborators. |
| Backup Before Rebasing | Create a backup branch to safeguard your work. |
| Merge vs. Rebase | Use merge for preserving history; rebase for linearizing it. |
| Interactive Rebase | Ideal for modifying commit history: squashing, rewording, or dropping commits. |
| Resolve Conflicts Carefully | Rebase pauses on conflicts; resolve them manually and use git rebase --continue to proceed. |
π When to Use Git Rebase
| Scenario | Use Rebase? |
|---|---|
| Simplifying commit history | β Yes |
| Updating a feature branch with main changes | β Yes |
| Shared branch development | β No (use merge) |
| Amending commit history | β Yes |
Conclusion:
- What: Git rebase replays commits onto a different base to clean up history
- Why: To maintain a linear, organized commit history and avoid unnecessary merge commits.
-
How: Use commands like
git rebase,git rebase -i, andgit rebase --ontofor various rebase operations. - When: Use it for feature branches, commit cleanup, or reapplying work onto a new base, but avoid rebasing shared branches.
Top comments (0)