From 35a74abff32c32c455a74974130ad2af7d81dfd9 Mon Sep 17 00:00:00 2001 From: Elijah Newren Date: Thu, 11 Aug 2011 23:20:27 -0600 Subject: [PATCH] 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 Signed-off-by: Junio C Hamano --- merge-recursive.c | 30 ++++++++++++++++++++++++------ t/t6022-merge-rename.sh | 6 +++--- 2 files changed, 27 insertions(+), 9 deletions(-) diff --git a/merge-recursive.c b/merge-recursive.c index 2bebc9721..71febe94a 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -1036,7 +1036,14 @@ static void handle_change_delete(struct merge_options *o, change_past, o->branch1, o->branch1, path, NULL == renamed ? "" : " at ", NULL == renamed ? "" : renamed); - update_file(o, 0, a_sha, a_mode, renamed ? renamed : path); + if (renamed) + update_file(o, 0, a_sha, a_mode, renamed); + /* + * No need to call update_file() on path when !renamed, since + * that would needlessly touch path. We could call + * update_file_flags() with update_cache=0 and update_wd=0, + * but that's a no-op. + */ } free(renamed); } @@ -1396,10 +1403,20 @@ static int process_renames(struct merge_options *o, NULL); } else if ((dst_other.mode == ren1->pair->two->mode) && sha_eq(dst_other.sha1, ren1->pair->two->sha1)) { - /* Added file on the other side - identical to the file being - renamed: clean merge */ - update_file(o, 1, ren1->pair->two->sha1, ren1->pair->two->mode, ren1_dst); + /* + * Added file on the other side identical to + * the file being renamed: clean merge. + * Also, there is no need to overwrite the + * file already in the working copy, so call + * update_file_flags() instead of + * update_file(). + */ + update_file_flags(o, + ren1->pair->two->sha1, + ren1->pair->two->mode, + ren1_dst, + 1, /* update_cache */ + 0 /* update_wd */); } else if (!sha_eq(dst_other.sha1, null_sha1)) { clean_merge = 0; try_merge = 1; @@ -1727,7 +1744,8 @@ static int process_entry(struct merge_options *o, free(new_path); } else { output(o, 2, "Adding %s", path); - update_file(o, 1, sha, mode, path); + /* do not overwrite file if already present */ + update_file_flags(o, sha, mode, path, 1, !a_sha); } } else if (a_sha && b_sha) { /* Case C: Added in both (check for same permissions) and */ diff --git a/t/t6022-merge-rename.sh b/t/t6022-merge-rename.sh index c2993fcaf..9d8584e95 100755 --- a/t/t6022-merge-rename.sh +++ b/t/t6022-merge-rename.sh @@ -696,7 +696,7 @@ test_expect_success 'setup avoid unnecessary update, dir->(file,nothing)' ' git commit -m "Add a newfile" ' -test_expect_failure 'avoid unnecessary update, dir->(file,nothing)' ' +test_expect_success 'avoid unnecessary update, dir->(file,nothing)' ' git checkout -q master^0 && test-chmtime =1000000000 df && test-chmtime -v +0 df >expect && @@ -726,7 +726,7 @@ test_expect_success 'setup avoid unnecessary update, modify/delete' ' git commit -m "Modify file" ' -test_expect_failure 'avoid unnecessary update, modify/delete' ' +test_expect_success 'avoid unnecessary update, modify/delete' ' git checkout -q master^0 && test-chmtime =1000000000 file && test-chmtime -v +0 file >expect && @@ -755,7 +755,7 @@ test_expect_success 'setup avoid unnecessary update, rename/add-dest' ' git commit -m "Rename file" ' -test_expect_failure 'avoid unnecessary update, rename/add-dest' ' +test_expect_success 'avoid unnecessary update, rename/add-dest' ' git checkout -q master^0 && test-chmtime =1000000000 newfile && test-chmtime -v +0 newfile >expect && -- 2.26.2