Skip to content
Go back

Git Rebase FTW!

TL;DR: Use git rebase.

When developing a feature that is dependent on an unmerged branch, it is recommended to create your branch from that unmerged branch as the base branch while waiting for peer review. Once the dependent branch is merged, you can rebase your feature branch onto main. This workflow strategy is known as Stacked Branches.

For the first time, it might feel overwhelm. But trust me you will feel very happy after some reps and work seamlessly after.

Prerequisites

The first thing you need to get familiar is git rebase. Rebase is your friend to help you manage the branches.

You need to update your git config to use rebase instead of merge when pulling changes:

git config pull.rebase true

If you want to enable rebase for all repositories:

git config --global pull.rebase true

Git Rebase

I usually use git rebase with 2 cases. The first one is to rebase my branch onto main after the parent branch is merged. The second one is to update my branch with the latest changes from the parent branch.

Rebase child branch onto main after the parent branch is merged

The case:

  1. You have a branch branch-a that is based on main branch.
  2. Then you need to develop feature-b that is dependent on some feature in branch-a. So you create branch-b based on branch-a.
  3. After peer review, branch-a is merged to main.
  4. Now you need to rebase branch-b onto main.

Branch before rebase

(main) ─── [OldCommit]
                 \
                  \
              (branch-a) ─── [Method-1]
                                   \
                                    \
                                (branch-b) ─── [Method-2]

Expected branch commit after rebase

(main) ─── [OldCommit] ─── [Method-1]
                                   \
                                    \
                                (branch-b) ─── [Method-2]

Here’s how you can do it:

  1. First, make sure you have the latest changes from main:
git switch main
git pull
  1. Switch to branch-b
  2. Run the following command:
git rebase --onto main branch-a branch-b

The above command basically saying: “Rebase branch-b onto main by removing the commits that are in branch-a but not in main.”

Update branch with the latest changes from the parent branch

The case:

  1. You have a branch branch-a that is based on main branch.
  2. Then you need to develop feature-b that is dependent on some feature in branch-a. So you create branch-b based on branch-a.
  3. After peer review, you have to adjust and update the branch-a.
  4. Now you need to update branch-b with the latest changes from branch-a.

Branch before rebase

(main) ─── [OldCommit]
                 \
                  \
              (branch-a) ─── [Method-1] ─── [Method-1-updated]
                                   \
                                    \
                                (branch-b) ─── [Method-2]

Expected branch commit after rebase

(main) ─── [OldCommit]
                 \
                  \
              (branch-a) ─── [Method-1] ─── [Method-1-updated]
                                                    \
                                                      \
                                                  (branch-b) ─── [Method-2]

In this case you can do following:

  1. Switch to branch-b
  2. Run the following command:
git rebase branch-a --update-refs

Push The Changes (after rebase)

If you have pushed the branch to origin, you will need to run push with --force-with-lease flag to force the change to the origin:

git push --force-with-lease origin branch-b

Why need to use --force-with-lease flag? Because the commit id will be different after rebase, and --force-with-lease flag will only overwrite the remote branch if there are no new commits on the remote branch that are not in your local branch. This can prevent data loss.


Share this post on:

Next Post
Fix WSL SSL certificate problem