Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

git merge fails with "Untracked working tree file" on case change

On Mac OS X, I have two branches - say A and B - and I want to merge A into B. When I try to do git merge A on B, I get:

error: Untracked working tree file 'path/file.php' would be overwritten by merge.  Aborting

This is caused by the fact that some change in A renamed the file - i.e. B has file path/File.php while A has it renamed to path/file.php. Since Mac OS X filesystem is case insensitive, this probably confuses git. Is there a way to make git do the merge properly?

Update: for clarification, branch B does not have any uncommitted changes and the file in question is tracked in both branches (under different names, of course).

like image 663
StasM Avatar asked Jul 18 '11 22:07

StasM


2 Answers

OK, after digging around all day, here's the solution I found:

========== The Situation ==========

I am developing on my branch "Hotdog"

My co-worker pushed his work to our master branch, including a file named "Hamburgersrule"

I merge master into my Hotdog branch.

My co-worker changes "Hamburgersrule" to "HamburgersRule", and pushes it to master.

========== The Problem ==========

When I try switching between Hotdog and Master, Git thinks some changes have occured. The case of HamburgersRule looks different to Git, but windows thinks it's just fine. Every time I try to merge, or checkout another branch, Git warns me that I will lose my unstaged files.

I can suppress the message by setting git config core.ignorecase true, but the underlying problem is still there, and ignoring case differences is what got us into this mess in the first place.

========== The Solution ==========

1: Do a Triple Rename on Master (to make sure the new file name is correct) HamburgersRule -> HamburgersRule_Rename -> HamburgersRule

2: Merge that change into Hotdog Branch. To get the merge to work, you will need to delete your version of "Hamburgersrule" (using your OS, not git)

3: Clean up the remaining files on Hotdog. Check to see if the merge worked as expected. You might have to checkout HamburgersRule from the Master branch:

git checkout master HamburgersRule

EDIT: Important note. If you don't want to keep fixing this problem over and over again, make sure your coworkers all have ignorecase set to false

git config core.ignorecase false

If anyone is ignoring case sensitivity, their git client will ignore the changes, and keep checking in the bad name.

like image 141
Andy Michael Avatar answered Oct 22 '22 05:10

Andy Michael


Starting git 2.0.1 (June 25, 2014), that merge won't fail anymore.

See commit ae352c7f37ef2098e03ee86bc7fd75b210b17683 by David Turner (dturner-tw)

merge-recursive.c: fix case-changing merge bug

On a case-insensitive filesystem, when merging, a file would be wrongly deleted from the working tree if an incoming commit had renamed it changing only its case.
When merging a rename, the file with the old name would be deleted -- but since the filesystem considers the old name to be the same as the new name, the new file would in fact be deleted.

We avoid this by not deleting files that have a case-clone in the index at stage 0.

like image 22
VonC Avatar answered Oct 22 '22 06:10

VonC