merge-recursive: Avoid unnecessary file rewrites
authorElijah Newren <newren@gmail.com>
Fri, 12 Aug 2011 05:20:27 +0000 (23:20 -0600)
committerJunio C Hamano <gitster@pobox.com>
Sun, 14 Aug 2011 21:19:40 +0000 (14:19 -0700)
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>
merge-recursive.c
t/t6022-merge-rename.sh
index 2bebc9721c3c494c888ef8fac12bed05094d0698..71febe94a3f6c6c35e1a1665f31b61d6c9fe3203 100644 (file)
@@ -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 */
index c2993fcafec657a63ccbc46c2b07f9bd57c2d652..9d8584e957a26cadda2f04d38d27fd0c4b97ae29 100755 (executable)
@@ -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 &&