merge-recursive: Avoid unnecessary file rewrites
Often times, a potential conflict at a path is resolved by merge-recursive by using the content that was already present at that location. In such cases, we do not want to overwrite the content that is already present, as that could trigger unnecessary recompilations. One of the patches earlier in this series ("merge-recursive: When we detect we can skip an update, actually skip it") fixed the cases that involved content merges, but there were a few other cases as well. 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
35a74abff32c32c455a74974130ad2af7d81dfd9
2 files changed
+27
-9
merge-recursive.c
+24
-6
@@ -1036,7 +1036,14 @@ static void handle_change_delete(struct merge_options *o,
1036
change_past, o->branch1, o->branch1, path,
1037
NULL == renamed ? "" : " at ",
1038
NULL == renamed ? "" : renamed);
1039
- update_file(o, 0, a_sha, a_mode, renamed ? renamed : path);
1039
+ if (renamed)
1040
+ update_file(o, 0, a_sha, a_mode, renamed);
1041
+ /*
1042
+ * No need to call update_file() on path when !renamed, since
1043
+ * that would needlessly touch path. We could call
1044
+ * update_file_flags() with update_cache=0 and update_wd=0,
1045
+ * but that's a no-op.
1046
+ */
1047
}
1048
free(renamed);
1049
}
@@ -1396,10 +1403,20 @@ static int process_renames(struct merge_options *o,
1403
NULL);
1404
} else if ((dst_other.mode == ren1->pair->two->mode) &&
1405
sha_eq(dst_other.sha1, ren1->pair->two->sha1)) {
1399
- /* Added file on the other side
1400
- identical to the file being
1401
- renamed: clean merge */
1402
- update_file(o, 1, ren1->pair->two->sha1, ren1->pair->two->mode, ren1_dst);
1406
+ /*
1407
+ * Added file on the other side identical to
1408
+ * the file being renamed: clean merge.
1409
+ * Also, there is no need to overwrite the
1410
+ * file already in the working copy, so call
1411
+ * update_file_flags() instead of
1412
+ * update_file().
1413
+ */
1414
+ update_file_flags(o,
1415
+ ren1->pair->two->sha1,
1416
+ ren1->pair->two->mode,
1417
+ ren1_dst,
1418
+ 1, /* update_cache */
1419
+ 0 /* update_wd */);
1420
} else if (!sha_eq(dst_other.sha1, null_sha1)) {
1421
clean_merge = 0;
1422
try_merge = 1;
@@ -1727,7 +1744,8 @@ static int process_entry(struct merge_options *o,
1744
free(new_path);
1745
} else {
1746
output(o, 2, "Adding %s", path);
1730
- update_file(o, 1, sha, mode, path);
1747
+ /* do not overwrite file if already present */
1748
+ update_file_flags(o, sha, mode, path, 1, !a_sha);
1749
}
1750
} else if (a_sha && b_sha) {
1751
/* Case C: Added in both (check for same permissions) and */
t/t6022-merge-rename.sh
+3
-3
@@ -696,7 +696,7 @@ test_expect_success 'setup avoid unnecessary update, dir->(file,nothing)' '
696
git commit -m "Add a newfile"
697
'
698
699
-test_expect_failure 'avoid unnecessary update, dir->(file,nothing)' '
699
+test_expect_success 'avoid unnecessary update, dir->(file,nothing)' '
700
git checkout -q master^0 &&
701
test-chmtime =1000000000 df &&
702
test-chmtime -v +0 df >expect &&
@@ -726,7 +726,7 @@ test_expect_success 'setup avoid unnecessary update, modify/delete' '
726
git commit -m "Modify file"
727
'
728
729
-test_expect_failure 'avoid unnecessary update, modify/delete' '
729
+test_expect_success 'avoid unnecessary update, modify/delete' '
730
git checkout -q master^0 &&
731
test-chmtime =1000000000 file &&
732
test-chmtime -v +0 file >expect &&
@@ -755,7 +755,7 @@ test_expect_success 'setup avoid unnecessary update, rename/add-dest' '
755
git commit -m "Rename file"
756
'
757
758
-test_expect_failure 'avoid unnecessary update, rename/add-dest' '
758
+test_expect_success 'avoid unnecessary update, rename/add-dest' '
759
git checkout -q master^0 &&
760
test-chmtime =1000000000 newfile &&
761
test-chmtime -v +0 newfile >expect &&