DEV Community

Softden 2005
Softden 2005

Posted on

Git Rebase: Complete Documentation

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]
Enter fullscreen mode Exit fullscreen mode
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
Enter fullscreen mode Exit fullscreen mode
  • Result: Applies feature branch commits on top of the latest main.

2. Interactive Rebase

git rebase -i HEAD~3
Enter fullscreen mode Exit fullscreen mode
  • 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
Enter fullscreen mode Exit fullscreen mode
  • Result: Conflicts are resolved, and the rebase proceeds.

4. Rebase Onto a Different Branch

git rebase --onto main dev feature
Enter fullscreen mode Exit fullscreen mode
  • Result: Moves commits from feature (after it diverged from dev) onto main.

5. Abort a Rebase

git rebase --abort
Enter fullscreen mode Exit fullscreen mode
  • Purpose: Stops the rebase process and restores the branch to its pre-rebase state.

6. Skip a Conflicting Commit

git rebase --skip
Enter fullscreen mode Exit fullscreen mode
  • 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:

  1. Move a branch to a new base while excluding unrelated commits.
  2. Filter out specific commits during a rebase operation.

Syntax and Explanation

Syntax 1: Rebasing by Commits

git rebase --onto <newBaseCommit> <excludeCommit> <lastCommit>
Enter fullscreen mode Exit fullscreen mode
  • <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>
Enter fullscreen mode Exit fullscreen mode
  • <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
Enter fullscreen mode Exit fullscreen mode

Before:

A---B---C---F---G (main branch)
         \
          D---E---H---I (my-branch, HEAD)
Enter fullscreen mode Exit fullscreen mode

After:

A---B---C---F---G (main branch)
             \
              E'---H'---I' (my-branch, HEAD)
Enter fullscreen mode Exit fullscreen mode
  • Commits E, H, and I from my-branch (after D) are reapplied onto F.
  • D is excluded, and the rebased commits are represented as E', H', and I'.

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
Enter fullscreen mode Exit fullscreen mode

Workflow:

  1. Commits unique to featureBranch after oldBaseBranch are identified.
  2. 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"
Enter fullscreen mode Exit fullscreen mode

Rebase:

git checkout featureBranch
git rebase --onto mainBranch oldBaseBranch featureBranch
Enter fullscreen mode Exit fullscreen mode

Result:

  • The featureBranch commits (Feature Commit 1 and Feature Commit 2) are moved onto mainBranch, excluding commits from oldBaseBranch.

📝 Key Points to Remember

  1. Excludes Commits: Commits from <excludeCommit> or <oldBaseBranch> are skipped.
  2. Flexible Range: Use <newBaseCommit> or <newBaseBranch> to restructure commit history without affecting unrelated commits.
  3. 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, and git rebase --onto for 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)