I\'m trying to produce a git merge conflict intentionally. Here is what I did
mkdir to-stack
cd to-stack
git init
vi a.txt
Added some text to first line of a.txt
A merge combines the changes from some common commit, to two different commits (whose relationship is that they both have that common commit in their histories).
That is, consider the following commit graph, where each o
or *
represents a commit, and every commit's parent is the commit that is found by following its connection leftwards (moving up or down if necessary):
o <-- branchA
/
...--o--*
\
o--o <-- branchB
The first commit that branchA
and branchB
share is the one marked *
. They also share every earlier commit (to the left of *
), but *
is the most interesting such commit. We call this commit the merge base of branchA
and branchB
.
When you run:
$ git checkout branchA
$ git merge branchB
the git merge
step sees that we are on branchA
(due to the git checkout
command), and that we are asking to merge the tip-most commit of branchB
. Git then locates this merge base commit, and runs two git diff
commands.
Let's say the hash of commit *
is ba5e...
, and the tip commit on branchA
is commit 1111...
with the tip commit of branchB
being 2222...
. The two git diff
commands are then essentially:
$ git diff ba5e 1111
and:
$ git diff ba5e 2222
The first diff tells Git "what we did": what we changed from *
to the tip of branchA
. The second diff tells Git "what they did": what they changed going from *
to the tip of branchB
.
A merge conflict occurs when some part of "what we did" changes the same line(s) of the same file(s) as some part of "what they did" changes, but the two changes are different. For instance, if we both change README.txt
to change the color of an apple, but we change it from purple to black, and they change it from purple to orange, Git doesn't know which one to take.
So, let's do just that:
mkdir mtest && cd mtest && git init
echo 'for testing' > README.txt
echo 'have a purple apple' >> README.txt
git add README.txt && git commit -m initial
This creates branch master
with one file, README.txt
. Now let's create two separate branches forking from this one commit, and change the color of the apple in each branch:
git checkout -b branchA master
sed -i '' s/purple/black/ README.txt
git add README.txt && git commit -m black
git checkout -b branchB master
sed -i '' s/purple/orange/ README.txt
git add README.txt && git commit -m black
Now we simply merge one branch with the other. We are currently on branchB
, so we can git merge branchA
now. Once we resolve the conflict and commit, we'll have a merge on branchB
. Or, we can git checkout branchA
first, then git merge branchB
. We will get the same conflict, but once we resolve it and commit, we'll have a merge on branchA
.