Subject: Re: git merge error question: The following untracked working tree files would be overwritten by merge

From: Carsten Fuchs <[email-masked]>
Date: Sat, 26 Jan 2013 11:46:27 +0100

Am 2013-01-25 19:07, schrieb Junio C Hamano:
> Carsten Fuchs <[email-masked]> writes:
>>>  [...]
>>> $ git merge origin/master --ff-only
>>> Updating f419d57..2da6052
>>> error: The following untracked working tree files would be overwritten by merge:
>>>          obsolete/e107/Readme.txt
>>>          obsolete/e107/article.php
>>>          obsolete/e107/backend.php
>>>          [...]
>> ...
>> Compare with what Subversion did in an analogous case: When I ran "svn
>> update" and the update brought new files for which there already was
>> an untracked copy in the working directory, Subversion:
>>      - started to consider the file as tracked,
>>      - but left the file in the working-copy alone.
>>
>> As a result, a subsequent "svn status" might
>>      a) no longer show the file at all, if the foreign copy in the
>> working directory happened to be the same as the one brought by the
>> "svn update", or
>>      b) flag the file as modified, if different from the one that "svn
>> update" would have created in its place.
>
> Interesting.  So before running "status", the merge is recorded (in this
> particular case you are doing ff-only so there is nothing new to
> record, but if the rest of the tree merges cleanly, the new tree
> that contains "obsolete" from the other branch you just merged will
> be the contents you record in the merge commit), and working tree is
> immediately dirty?

Yes. But I don't think it's the (svn) "status" command that does anything special.

In Git, if I understand it correctly, the final step of a "merge", "checkout", "reset", 
etc. is a move of the HEAD to the resulting or specified commit. I imagine that it is 
here where the diff of the dirty working tree is re-applied to the newly checked out 
commit (and if this is not possible cleanly, probably [a] the whole operation must 
abort, or [b] leave files in the working tree with conflict markers), and where a 
decision must be made about "obstructing paths" (svn lingo): [c] abort the whole 
operation, or [d] "version" them (but don't modify them in any way).

I'm not sure if Subversion does [a] and [c] ("abort") without the --force option, and 
[b] and [d] with --force, or any other combination, but at least TortoiseSVN seems to 
use [d] by default (which seems safe enough).

Despite a thorough search, I've not been able to find much reference about this behaviour:
http://svnbook.red-bean.com/en/1.6/svn.ref.svn.c.switch.html
http://markphip.blogspot.de/2007/01/subversion-15-tolerate-obstructions.html

However, as the blog article mentions, I too have found this treatment of obstructing 
paths very natural and helpful in several occasions.

(Because without it, we must manually rename the obstructing paths, re-start the 
previously aborted operation, and then take diffs or somehow else compare the renamed 
obstructing and newly added paths manually, and possible merge them manually; or at 
least copy the renamed edition over the newly added edition to get back into Git for the 
job.)

>> So my real question is, why does Git not do something analogous?
>
> The answer to that question is "because nobody thought that doing so
> would help users very much and bothered to implement it"; it is not
> "people thought about doing so and found reasons why that would not
> help users".

Thanks, it's very good to hear this!
:-)

Best regards,
Carsten