Skip to content

Commit ac9666f

Browse files
committed
Merge branch 'en/merge-recursive'
* en/merge-recursive: merge-recursive: tweak magic band-aid merge-recursive: When we detect we can skip an update, actually skip it t6022: New test checking for unnecessary updates of files in D/F conflicts t6022: New test checking for unnecessary updates of renamed+modified files
2 parents d98a509 + b9b3eef commit ac9666f

File tree

2 files changed

+81
-6
lines changed

2 files changed

+81
-6
lines changed

merge-recursive.c

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -344,10 +344,11 @@ static void make_room_for_directories_of_df_conflicts(struct merge_options *o,
344344
* make room for the corresponding directory. Such paths will
345345
* later be processed in process_df_entry() at the end. If
346346
* the corresponding directory ends up being removed by the
347-
* merge, then the file will be reinstated at that time;
348-
* otherwise, if the file is not supposed to be removed by the
349-
* merge, the contents of the file will be placed in another
350-
* unique filename.
347+
* merge, then the file will be reinstated at that time
348+
* (albeit with a different timestamp!); otherwise, if the
349+
* file is not supposed to be removed by the merge, the
350+
* contents of the file will be placed in another unique
351+
* filename.
351352
*
352353
* NOTE: This function relies on the fact that entries for a
353354
* D/F conflict will appear adjacent in the index, with the
@@ -358,6 +359,13 @@ static void make_room_for_directories_of_df_conflicts(struct merge_options *o,
358359
int last_len = 0;
359360
int i;
360361

362+
/*
363+
* Do not do any of this crazyness during the recursive; we don't
364+
* even write anything to the working tree!
365+
*/
366+
if (o->call_depth)
367+
return;
368+
361369
for (i = 0; i < entries->nr; i++) {
362370
const char *path = entries->items[i].string;
363371
int len = strlen(path);
@@ -1260,9 +1268,13 @@ static int merge_content(struct merge_options *o,
12601268
}
12611269

12621270
if (mfi.clean && !df_conflict_remains &&
1263-
sha_eq(mfi.sha, a_sha) && mfi.mode == a.mode)
1271+
sha_eq(mfi.sha, a_sha) && mfi.mode == a.mode &&
1272+
!o->call_depth && !lstat(path, &st)) {
12641273
output(o, 3, "Skipped %s (merged same as existing)", path);
1265-
else
1274+
add_cacheinfo(mfi.mode, mfi.sha, path,
1275+
0 /*stage*/, 1 /*refresh*/, 0 /*options*/);
1276+
return mfi.clean;
1277+
} else
12661278
output(o, 2, "Auto-merging %s", path);
12671279

12681280
if (!mfi.clean) {

t/t6022-merge-rename.sh

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -609,4 +609,67 @@ test_expect_success 'check handling of differently renamed file with D/F conflic
609609
! test -f original
610610
'
611611

612+
test_expect_success 'setup avoid unnecessary update, normal rename' '
613+
git reset --hard &&
614+
git checkout --orphan avoid-unnecessary-update-1 &&
615+
git rm -rf . &&
616+
git clean -fdqx &&
617+
618+
printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" >original &&
619+
git add -A &&
620+
git commit -m "Common commmit" &&
621+
622+
git mv original rename &&
623+
echo 11 >>rename &&
624+
git add -u &&
625+
git commit -m "Renamed and modified" &&
626+
627+
git checkout -b merge-branch-1 HEAD~1 &&
628+
echo "random content" >random-file &&
629+
git add -A &&
630+
git commit -m "Random, unrelated changes"
631+
'
632+
633+
test_expect_success 'avoid unnecessary update, normal rename' '
634+
git checkout -q avoid-unnecessary-update-1^0 &&
635+
test-chmtime =1000000000 rename &&
636+
test-chmtime -v +0 rename >expect &&
637+
git merge merge-branch-1 &&
638+
test-chmtime -v +0 rename >actual &&
639+
test_cmp expect actual # "rename" should have stayed intact
640+
'
641+
642+
test_expect_success 'setup to test avoiding unnecessary update, with D/F conflict' '
643+
git reset --hard &&
644+
git checkout --orphan avoid-unnecessary-update-2 &&
645+
git rm -rf . &&
646+
git clean -fdqx &&
647+
648+
mkdir df &&
649+
printf "1\n2\n3\n4\n5\n6\n7\n8\n9\n10\n" >df/file &&
650+
git add -A &&
651+
git commit -m "Common commmit" &&
652+
653+
git mv df/file temp &&
654+
rm -rf df &&
655+
git mv temp df &&
656+
echo 11 >>df &&
657+
git add -u &&
658+
git commit -m "Renamed and modified" &&
659+
660+
git checkout -b merge-branch-2 HEAD~1 &&
661+
>unrelated-change &&
662+
git add unrelated-change &&
663+
git commit -m "Only unrelated changes"
664+
'
665+
666+
test_expect_failure 'avoid unnecessary update, with D/F conflict' '
667+
git checkout -q avoid-unnecessary-update-2^0 &&
668+
test-chmtime =1000000000 df &&
669+
test-chmtime -v +0 df >expect &&
670+
git merge merge-branch-2 &&
671+
test-chmtime -v +0 df >actual &&
672+
test_cmp expect actual # "df" should have stayed intact
673+
'
674+
612675
test_done

0 commit comments

Comments
 (0)