Scenario

A colleague has a review:

main
 └─ Co

My stacked reviews are based on main:

main
 └─ X
     └─ Y

I want X (and therefore Y) to depend on Co.

Desired result:

main
 └─ Co
     └─ X
         └─ Y

Step 1: Fetch Colleague’s Review

Fetch the Gerrit patch set:

git fetch origin refs/changes/NN/CHANGE_NUMBER/PATCHSET

Git stores the fetched commit in:

FETCH_HEAD

Step 2: Create a Temporary Branch (Optional)

Instead of using FETCH_HEAD directly:

git checkout -b co-base FETCH_HEAD

Result:

main
 └─ Co  (co-base)

This makes later commands easier to read.


Step 3: Rebase the Stack onto Co

Suppose:

main
 └─ X
     └─ Y   <-- current branch

Run:

git checkout feature
git rebase --onto co-base main

Meaning:

Take all commits after main
(X and Y)
 
Replay them on top of co-base
(Co)

Result:

main
 └─ Co
     └─ X'
         └─ Y'

Understanding --onto

Syntax:

git rebase --onto <new-base> <old-base>

Example:

git rebase --onto co-base main

Read as:

Take commits after main and move them onto co-base.


Do I Need -i?

Usually:

No

A normal rebase is sufficient.

Use interactive rebase only when you want to:

  • Edit commits

  • Reword commit messages

  • Squash commits

  • Split commits

  • Reorder commits

Examples:

git rebase -i main
git rebase -i co-base

Resolving Conflicts

If conflicts occur:

# fix files
 
git add <fixed-files>
git rebase --continue

Abort if necessary:

git rebase --abort

Push Updated Reviews to Gerrit

After rebase:

git push origin HEAD:refs/for/main

As long as the commits keep their original Change-Id lines:

X -> updates existing review X
Y -> updates existing review Y

No new reviews will be created.


Mental Model

Before:

main
 ├─ Co
 └─ X
     └─ Y

After:

main
 └─ Co
     └─ X
         └─ Y

Think of rebase as:

Lift commits X and Y off their old floor (main) and place them on a new floor (Co).

One review per branch

git checkout X
git rebase co-base
 
git checkout Y
git rebase X