Is this git-only behavior?
After discussion with a colleague, I just tried, and SVN handles it without problem: you get the 2 lines modified.
The merge capabilities of several VCS are tested here for bazaar, darcs, git and mercurial: https://github.com/mndrix/merge-this
It seems only darcs successfully merge the "adjacent lines" case.
Applying adjacent changes to files is not a difficult problem.
I really think this behavior has been chosen on-purpose.
Why would someone decide that modifying adjacent lines produces a conflict?
I would think this is to force you to look at it.
int max = MAX_ITEMS;
for(unsigned int i = 0; i < max; i++)
do_stuff(i);
Modif number 1, on master:
int max = MAX_ITEMS/2; // Do stuff only on the first half
for(unsigned int i = 0; i < max; i++)
do_stuff(i);
Modif number 2, merged from a branch:
int max = MAX_ITEMS;
for(unsigned int i = 0; i < max/2; i++) // max/2: only on 1st half
do_stuff(i);
After merge, you don't want that:
int max = MAX_ITEMS/2; // Do stuff only on the first half
for(unsigned int i = 0; i < max/2; i++) // max/2: only on 1st half
do_stuff(i);
Seeing this behavior as a feature
You can turn the git merging behavior to an advantage.
When you need to keep 2 lines consistent but you can't detect it (at compilation time, early in your tests or else), you can try to join them.
Rewrite this...:
for(unsigned int i = 0; i < max; i++)
r = do_stuff(i);
// Need to do something else
do_something_else(r);
...to this:
for(unsigned int i = 0; i < max; i++)
r = do_stuff(i);
do_something_else(r); // Need to do something else
So when you merge Modif 1...:
for(unsigned int i = 0; i < max; i++)
r = do_stuff(i)/2; // we need only the half
do_something_else(r); // Need to do something else
... with Modif 2...:
for(unsigned int i = 0; i < max; i++)
r = do_stuff(i);
if(r < 0) // do_stuff can return an error
handle_error(r);
do_something_else(r/2); // Need to do something else
..., git will produce a conflict, and you will force you to look at it.