Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I recently learned that when merging two branches in git, if there are changes on two adjacent lines git declares this a conflict. For example, if file test.txt has this content:

Line 1: A
Line 2: B
Line 3: C
Line 4: D

and in branch master we change this to

Line 1: A
Line 2: B1
Line 3: C
Line 4: D

while in branch testing we change this to

Line 1: A
Line 2: B
Line 3: C1
Line 4: D

and then attempt to merge testing into master, git declares a merge conflict. My naive expectation was that the merge would happen without conflict and yield this:

Line 1: A
Line 2: B1
Line 3: C1
Line 4: D

I am sure there is a good reason why git doesn't merge this way. Can someone explain this reason?

share|improve this question
    
Hey I just noticed this last week too. Maybe we were doing the same tutorial. –  detly Apr 12 '13 at 22:56
1  
git's merging abilities are actually quite poor, IMO –  James Apr 13 '13 at 13:40
    
@James have you tried using the patience algorithm? I find I get better results with it, in particular when dealing with where hunks are split (e.g. grabbing one function body instead of two). If you don't like git's, you can also use your own (see blog.wuwon.id.au/2010/09/… for an example). –  deterb May 6 '13 at 18:58
    
The root cause is that git tries to do the merge itself, instead of factoring it out to a specialized tool. Entirely not the Unix philosophy. For source files, you can actually use the language grammar to reliably determine diffs. –  MSalters Sep 9 '13 at 13:30

2 Answers 2

Assuming that this snippet of code

x=0
x+=1 if foo
x+=1 if bar
return x

has been changed in one branch into this

x=0
x+=1 if foo && xyzzy
x+=1 if bar
return x

and in another branch into this

x=0
x+=1 if foo
x+=1 if bar && xyzzy
return x

then I would not want git to merge it into this

x=0
x+=1 if foo && xyzzy
x+=1 if bar && xyzzy
return x

without alarming me.

This example is trivial, but when merging huge branches the risk of similar "logical" conflicts is much bigger. Sometimes I would even love the context to be even bigger than it currently is.

share|improve this answer

I'm mostly guessing, but I think it has to do with line 2 being used as context for the line 3 change.

Git can't just say that "The line with C became a line with C1" because there could be another line with "C", so it says "The line with C, that's right after the start of the file, the line with A, and the line with B, is now C1"

If "the line with B" is no longer there, then some of the context is lost, and git can only tell roughly where the new line has to go.

share|improve this answer
2  
its also very likely that C depends on B, so a naive merge may be troublesome even if git "knows how" to do it –  Buttons Apr 13 '13 at 12:53

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.