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 (*)
To rebase br2 into main, you should :
git checkout br2
git rebase main
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