I am new to git
and trying to get my hands dirty with it.
I cloned my testing repo with single text file at two different folders.
Then i created two branches B1
in folder1 and B2
in folder2
In B1
i added a line, now test.txt
has following content
It is line from dev branch.
It is line from B1.
Commited changes in B1
, merged with master
and pushed changes back to remote
Now in B2
also added a different line, it's test.txt
has following content
It is line from dev branch.
It is line from branch 'B2'.
When i tried to sync B2
with upstream master
, it got merge conflict
git pull --rebase origin master
First, rewinding head to replay your work on top of it...
Applying: Modified test.txt from B2
Using index info to reconstruct a base tree...
M test.txt
Falling back to patching base and 3-way merge...
Auto-merging test.txt
CONFLICT (content): Merge conflict in test.txt
error: Failed to merge in the changes.
I opened mergetool
git mergetool
It opens meld, but here Local
and Remote
files are interchanged.
Local is showing content from master
branch
Remote is showing content from local B2
branch. Here is snapshot
https://postimg.org/image/njtivi32d/
Am i looking it wrong or it is actually wrong ? Can anyone help with it?
Here is mergetool config from .gitconfig
[merge]
tool = meld
[mergetool "meld"]
cmd = meld "$LOCAL" "$BASE" "$REMOTE" --output "$MERGED"
The way a rebase works is by rolling back the target branch until reaching the most common ancestor commit between B2
and master
, then playing the commits from master
since that point. Then, the commits from B2
occurring after that common ancestor commit on the B2
branch are replayed on top of the master
commits.
This explains why the local version resembles master
. It resembles master
because this is what the local branch looks like at this point in the rebase. And the remote looks like B2
because these commits are being replayed.
It might be easier to understand this with a diagram. Consider a situation where both master
and B2
have diverged by one commit. This means that since the most recent common ancestor, one commit has been to each branch, respectively:
master: ... A -- B -- C
\
B2: D
The first step in a rebase is to rewind the B2
branch and apply the commits in master
since the commit B
. This leaves us with the following:
master: ... A -- B -- C
\
B2: C [D commit not yet reapplied]
The last step in the rebase is to reapply the D
commit to B2
:
master: ... A -- B -- C
\
B2: C -- D'
This is the point where the merge conflict you saw happened. At the point, the "local" code you already have is associated with the C
commit, from master
, and the "remote" code is actually coming from the original B2
branch, before the rebase.