0

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 git add a.txt git commit -m "Added a line to a.txt" git checkout -b other vi a.txt Updated the text on first line of a.txt to something else git add a.txt git commit -m "Updated line 1" git checkout master git merge other 

Merge happened and the content a.txt in master branch got overwritten to that of from other branch

I was expecting a Merge conflict to happen when doing the merge. Since I had changed the same line in other branch

Can you tell me why Merge conflict didn't happen in above case?

1
  • 3
    Why would that cause a problem? Version control isn't to make sure the same line isn't changed ever again. You're changing the line after the first change, which is just fine. You have to produce two separate changes with a common parent. Commented Jan 20, 2017 at 6:13

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.