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 &&