yaobin.wen

Yaobin's Blog

View on GitHub
19 December 2024

git-rebase: A case study

by yaobin.wen

rebase is probably one of the most difficult operation in git because it requires a lot of carefulness and patience to do it right. Recently, I dealt with a complicated git rebase case so I wanted to write down my learning.

In this git rebase case, I needed to rebase a feature branch on top of the latest main branch origin/main. However, the latest main branch evolved in the following way:

git-rebase-state-01
git-rebase-state-02
git-rebase-state-03
git-rebase-state-04

What I needed to do was rebase the branch topic2 against the latest branch main. The biggest challenge was handling the commits inside the yellow box: Those commits from the two branches were either identical or quite similar. Identical commits were easy to handle. In fact, git rebase will automatically skip them. The similar commits needed more attention, because we need to decide whether we need to keep them or skip them.

The commits outside the yellow box were much easier to handle: For the commits 3, 4, and 5, they were topic1-specific commits so they must be kept; for the commits 6 and 7, they were topic2-specific commits, so they must be kept too.

Now let’s think about what can cause the commits inside the yellow box to be similar but not identical.

The first case is that the branch main already has some changes that also appear in the topic branches. In the following illustration, the branch topic1 had the changes A=1 and B=2. However, the change A=1 was already merged into main. This may happen for two reasons:

git-rebase-state-05

As a result, when topic1 was rebased against main, the change A=1 was no longer needed because it was already done in main. The branch topic1 only needed to keep the change B=2, as illustrated below:

git-rebase-state-06

The second case is that the branch main introduced some condition that required the code in the branch topic1 be changed. For example, topic1 wanted to assign the value zero to A. However, a change in main used A as the divider in the expression C=B/A. See the following illustration:

git-rebase-state-07

As a result, A could no longer be zero. When topic1 was rebased against main, it must update A to be a non-zero value, such as 1. But the commit that was referred in the old topic1 commit still had the change A=0. See the following illustration:

git-rebase-state-08

In both cases, we need to keep the commits during rebase, so the conflicting changes can be kept for further resolution.

Tags: Tech - git