Junio C Hamano <junkio@xxxxxxx> writes: > However. > > I usually have "[apply] whitespace = strip" in my ~/.gitconfig, > but during this verification run, I disabled it to keep rebase > from falling back to 3-way merge using merge-recursive. If I > turn it on, rebase still fails and I strongly suspect "rebase > -m" would fail the same way, although I haven't tried it (it > takes too much time). > > I'll be somewhat busy this weekend, so I would welcome anybody > else beating me to fixing the problem in merge-recursive. Yuck. merge-recursive does seem to have problem with D/F conflict in general; I suspect this is not limited to cases that involve symbolic links. First, the setup. $ git clone git://git.kernel.org/pub/scm/linux/kernel/git/hpa/linux-2.6-newsetup.git/ $ cd linux-2.6-newsetup.git $ git fetch git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6.git/ $ git branch other b2ad90f4969226fe8cf3edc5330711ed5fc20105 $ git branch ancestor other^1 $ git reset --hard ancestor $ echo >>Makefile ; git add Makefile ; git commit -m 'change one' $ git branch try To see that the underlying read-tree is working as expected (and do not have to be debugged), we can first try the usual three-way read tree: $ git read-tree -m -u ancestor HEAD other $ git ls-files -u --abbrev arch/x86-64 This would show... 120000 ad3f146 3 arch/x86_64/boot 100644 495f20c 1 arch/x86_64/boot/.gitignore 100644 495f20c 2 arch/x86_64/boot/.gitignore 100644 ee6f650 1 arch/x86_64/boot/Makefile 100644 ee6f650 2 arch/x86_64/boot/Makefile ... The current HEAD (the one that we tagged as 'try') has the directory arch/x86_64/boot/, but all of its files are unchanged from the "common ancestor", so they all have identical stages 1 and 2, with stage 3 missing. The other tree has boot/ as a symlink. These "One-side removes other side does not touch" and "one-side adds" cases are left unmerged by "read-tree -m -u", as that is how merge-recursive can find renames to begin with. Now we've seen what the read-tree (which is the same machinery used as git_merge_trees() in mege-recursive) does with these three trees, let's see how merge-recursive finishes this off: $ git reset --hard try $ git merge-recursive ancestor -- HEAD other CONFLICT (directory/file): There is a directory with name arch/x86_64/boot in HEAD. Added arch/x86_64/boot as arch/x86_64/boot~other Removed arch/x86_64/boot/.gitignore Removed arch/x86_64/boot/Makefile Removed arch/x86_64/boot/bootsect.S Removed arch/x86_64/boot/compressed/Makefile Removed arch/x86_64/boot/compressed/head.S Removed arch/x86_64/boot/compressed/misc.c Removed arch/x86_64/boot/compressed/vmlinux.lds Removed arch/x86_64/boot/compressed/vmlinux.scr Removed arch/x86_64/boot/install.sh Removed arch/x86_64/boot/mtools.conf.in Removed arch/x86_64/boot/setup.S Removed arch/x86_64/boot/tools/.gitignore Removed arch/x86_64/boot/tools/build.c There is no rename, so rename detection does not interfere, but the D/F conflict detection code in merge-recursive thinks that arch/x86_64/boot is a directory in one tree (yes, it is true in the original tree, but it goes away as all files under it), and a non-directory in another. And instead of replacing the boot/ directory that becomes empty with a new symlink boot/, it creates the boot~funny-name symlink and fails the operation. When it actually is checking out arch/x86_64/boot out of the resolved index, it should notice that (1) arch/x86_64/boot directory is unnecessary to house anything in the resulting index anymore, and that (2) there is no locally created untracked file that is 'precious' [*1*]. Then it can rmdir() and create the boot/ symlink in its place. To fix this, it may be necessary to update its checkout code to perform the "remove first then create" two-pass process git-apply does. It is unfortunate that for merge-recursive it is probably too cumbersome to always do the right thing, but I think it should at least notice that arch/x86_64/boot whose files all disappear does not conflict with creation of the new symlink. - To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html