Home > OS >  Git rebase a branch on another after parent branch is merged to master
Git rebase a branch on another after parent branch is merged to master

Time:02-07

If I have branch_1 forked out of master with let's say 2 commits.

Next, I made branch_2 forked out of branch_1.
On branch_2 I have made changes which are not in the area branch_1. I of course have changes from branch_1 included here but I have not touched those changes.

Now let's say branch_1 merges into master.

Next, on branch_2 I do git pull upstream master --rebase to rebase branch_2 on top of master so that commits from branch_1 disappear from commit history of branch_2. I should not get merge conflicts here. Right? But I do in the same lines of code which were changed on branch_1. This is strange! Is this expected?

CodePudding user response:

I have reproduced your situation like in the first image below.

Notice here I have the following naming :

master ==> main

branch_1 ==> br1

branch_2 ==> br2

And the br1 is merged into main

And the head is at the main branch (*)

enter image description here

To rebase br2 into main, you should :

git checkout br2
git rebase main

enter image description here

CodePudding user response:

Your assumption about what the rebase would do is valid, if git knows the relationship between branch_1 and branch_2. Your problem is that you threw away that relationship by rebasing or squashing branch_1.

With a true merge, your commit graph would look like this (where "M" is the merge commit when you merged branch_1 into branch_2):

            master
              |
              v
... <- A <--- M
        \    /
         <- B <- C
            ^    ^
            |    |
       branch_1 branch_2

Then, when you rebased branch_2 onto master, git would find that commit B is already reachable from master (as a parent of commit M), so wouldn't include it in the list of commits to replay.

However, when you squashed branch_1, you created this (where "BS" is the result of squashing branch_1):

            master
              |
              v
... <- A <--- BS
        \    
         <- B <- C
            ^    ^
            |    |
       branch_1 branch_2

Now when you ask to rebase branch_2 on master, it finds that commit B is not reachable from master (commit BS), so includes it in the list of commits to replay. If commit B was actually multiple commits, it will apply them one by one, and since the changes have already happened in BS, you'll get conflicts when it does so.

The solution (other than using true merges from now on

  •  Tags:  
  • Related