Context
git merge
considers the setting merge.conflictStyle
in case of merge conflicts.
Possible values are merge
(default) and diff3
.
I noticed that diff3
sometimes produces much bigger conflicts (see example below).
I found this paper, which describes the diff3
algorithm in great detail, but I couldn't find much about the default merge
algorithm.
Question
What are the exact differences between the merge
and diff3
algorithm?
How does the default merge
algorithm work exactly?
Example
I have these files:
- Base:
1
2
3
- Yours:
1
change1
change2
input1OnlyChange1
change3
change4
change5
change6
input1OnlyChange2
change7
change8
change9
2
3
- Theirs:
1
change1
change2
input2OnlyChange1
change3
change4
change5
change6
input2OnlyChange2
change7
change8
change9
2
3
With merge
I get 2 conflict markers:
1
change1
change2
<<<<<<< HEAD
input1OnlyChange1
=======
input2OnlyChange1
>>>>>>> input2
change3
change4
change5
change6
<<<<<<< HEAD
input1OnlyChange2
=======
input2OnlyChange2
>>>>>>> input2
change7
change8
change9
2
3
However, with diff3
I only get 1 conflict marker:
1
<<<<<<< HEAD
change1
change2
input1OnlyChange1
change3
change4
change5
change6
input1OnlyChange2
change7
change8
change9
||||||| 0fcee2c
=======
change1
change2
input2OnlyChange1
change3
change4
change5
change6
input2OnlyChange2
change7
change8
change9
>>>>>>> input2
2
3
This is my test script (powershell):
rm -Force -r ./repo -ErrorAction Ignore
mkdir ./repo
cd ./repo
git init
# git config merge.conflictStyle diff3
cp ../../base.txt content.txt
git add *; git commit -m first
git branch base
git checkout -b input2
cp ../../input2.txt content.txt
git add *; git commit -m input2
git checkout base
cp ../../input1.txt content.txt
git add *; git commit -m input1
git merge input2
Does the merge
algorithm diff the diffs again to split up the bigger conflict?
Clearly the merge
algorithm also performs some kind of 3 way diff, as you don't get a conflict when you update base
to match yours
.
Official documentation
The docs say this:
Specify the style in which conflicted hunks are written out to working tree files upon merge. The default is "merge", which shows a
<<<<<<<
conflict marker, changes made by one side, a=======
marker, changes made by the other side, and then a>>>>>>>
marker. An alternate style, "diff3", adds a|||||||
marker and the original text before the=======
marker.
Clearly this does not explain the observed difference in the example.