merge-recursive: Fix rename/rename(1to2) resolution for virtual merge base

When renaming one file to two files, we really should be doing a content merge. Also, in the recursive case, undoing the renames and recording the merged file in the index with the source of the rename (while deleting both destinations) allows the renames to be re-detected in the non-recursive merge and will result in fewer spurious conflicts. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Elijah Newren committed Aug 11, 2011 at 23:20 UTC c52ff85d97c698c902870305a010e2303e297b87
2 files changed +14 -18
merge-recursive.c
+13 -17
@@ -984,17 +984,6 @@ static void conflict_rename_rename_1to2(struct merge_options *o,
984 src, pair1->two->path, branch1,
985 src, pair2->two->path, branch2,
986 o->call_depth ? " (left unresolved)" : "");
987 - if (o->call_depth) {
988 - /*
989 - * FIXME: Why remove file from cache, and then
990 - * immediately readd it? Why not just overwrite using
991 - * update_file only? Also...this is buggy for
992 - * rename/add-source situations...
993 - */
994 - remove_file_from_cache(src);
995 - update_file(o, 0, pair1->one->sha1, pair1->one->mode, src);
996 - }
997 -
987 if (dir_in_way(ren1_dst, !o->call_depth)) {
988 dst_name1 = del[delp++] = unique_path(o, ren1_dst, branch1);
989 output(o, 1, "%s is a directory in %s adding as %s instead",
@@ -1006,14 +995,21 @@ static void conflict_rename_rename_1to2(struct merge_options *o,
995 ren2_dst, branch1, dst_name2);
996 }
997 if (o->call_depth) {
1009 - remove_file_from_cache(dst_name1);
1010 - remove_file_from_cache(dst_name2);
998 + struct merge_file_info mfi;
999 + mfi = merge_file(o, src,
1000 + pair1->one->sha1, pair1->one->mode,
1001 + pair1->two->sha1, pair1->two->mode,
1002 + pair2->two->sha1, pair2->two->mode,
1003 + branch1, branch2);
1004 /*
1012 - * Uncomment to leave the conflicting names in the resulting tree
1013 - *
1014 - * update_file(o, 0, pair1->two->sha1, pair1->two->mode, dst_name1);
1015 - * update_file(o, 0, pair2->two->sha1, pair2->two->mode, dst_name2);
1005 + * FIXME: For rename/add-source conflicts (if we could detect
1006 + * such), this is wrong. We should instead find a unique
1007 + * pathname and then either rename the add-source file to that
1008 + * unique path, or use that unique path instead of src here.
1009 */
1010 + update_file(o, 0, mfi.sha, mfi.mode, src);
1011 + remove_file_from_cache(ren1_dst);
1012 + remove_file_from_cache(ren2_dst);
1013 } else {
1014 update_stages(ren1_dst, NULL, pair1->two, NULL);
1015 update_stages(ren2_dst, NULL, NULL, pair2->two);
t/t6036-recursive-corner-cases.sh
+1 -1
@@ -633,7 +633,7 @@ test_expect_success 'setup rename/rename(1to2)/modify followed by what looks lik
633 git tag E
634 '
635
636 -test_expect_failure 'handle rename/rename(1to2)/modify followed by what looks like rename/rename(2to1)/modify' '
636 +test_expect_success 'handle rename/rename(1to2)/modify followed by what looks like rename/rename(2to1)/modify' '
637 git checkout D^0 &&
638
639 git merge -s recursive E^0 &&