t6036: criss-cross w/ rename/rename(1to2)/modify+rename/rename(2to1)/modify
This test is mostly just designed for testing optimality of the virtual merge base in the event of a rename/rename(1to2) conflict. The current choice for resolving this in git seems somewhat confusing and suboptimal. 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:19 UTC
a0d3311624638bf3043f2c442e698b14c5fb2d02
1 file changed
+88
t/t6036-recursive-corner-cases.sh
+88
@@ -556,4 +556,92 @@ test_expect_failure 'merge of E2 & D fails but has appropriate contents' '
556
test -f a~D^0
557
'
558
559
+#
560
+# criss-cross with rename/rename(1to2)/modify followed by
561
+# rename/rename(2to1)/modify:
562
+#
563
+# B D
564
+# o---o
565
+# / \ / \
566
+# A o X ? F
567
+# \ / \ /
568
+# o---o
569
+# C E
570
+#
571
+# Commit A: new file: a
572
+# Commit B: rename a->b, modifying by adding a line
573
+# Commit C: rename a->c
574
+# Commit D: merge B&C, resolving conflict by keeping contents in newname
575
+# Commit E: merge B&C, resolving conflict similar to D but adding another line
576
+#
577
+# There is a conflict merging B & C, but one of filename not of file
578
+# content. Whoever created D and E chose specific resolutions for that
579
+# conflict resolution. Now, since: (1) there is no content conflict
580
+# merging B & C, (2) D does not modify that merged content further, and (3)
581
+# both D & E resolve the name conflict in the same way, the modification to
582
+# newname in E should not cause any conflicts when it is merged with D.
583
+# (Note that this can be accomplished by having the virtual merge base have
584
+# the merged contents of b and c stored in a file named a, which seems like
585
+# the most logical choice anyway.)
586
+#
587
+# Comment from Junio: I do not necessarily agree with the choice "a", but
588
+# it feels sound to say "B and C do not agree what the final pathname
589
+# should be, but we know this content was derived from the common A:a so we
590
+# use one path whose name is arbitrary in the virtual merge base X between
591
+# D and E" and then further let the rename detection to notice that that
592
+# arbitrary path gets renamed between X-D to "newname" and X-E also to
593
+# "newname" to resolve it as both sides renaming it to the same new
594
+# name. It is akin to what we do at the content level, i.e. "B and C do not
595
+# agree what the final contents should be, so we leave the conflict marker
596
+# but that may cancel out at the final merge stage".
597
+
598
+test_expect_success 'setup rename/rename(1to2)/modify followed by what looks like rename/rename(2to1)/modify' '
599
+ git reset --hard &&
600
+ git rm -rf . &&
601
+ git clean -fdqx &&
602
+ rm -rf .git &&
603
+ git init &&
604
+
605
+ printf "1\n2\n3\n4\n5\n6\n" >a &&
606
+ git add a &&
607
+ git commit -m A &&
608
+ git tag A &&
609
+
610
+ git checkout -b B A &&
611
+ git mv a b &&
612
+ echo 7 >>b &&
613
+ git add -u &&
614
+ git commit -m B &&
615
+
616
+ git checkout -b C A &&
617
+ git mv a c &&
618
+ git commit -m C &&
619
+
620
+ git checkout -q B^0 &&
621
+ git merge --no-commit -s ours C^0 &&
622
+ git mv b newname &&
623
+ git commit -m "Merge commit C^0 into HEAD" &&
624
+ git tag D &&
625
+
626
+ git checkout -q C^0 &&
627
+ git merge --no-commit -s ours B^0 &&
628
+ git mv c newname &&
629
+ printf "7\n8\n" >>newname &&
630
+ git add -u &&
631
+ git commit -m "Merge commit B^0 into HEAD" &&
632
+ git tag E
633
+'
634
+
635
+test_expect_failure 'handle rename/rename(1to2)/modify followed by what looks like rename/rename(2to1)/modify' '
636
+ git checkout D^0 &&
637
+
638
+ git merge -s recursive E^0 &&
639
+
640
+ test 1 -eq $(git ls-files -s | wc -l) &&
641
+ test 0 -eq $(git ls-files -u | wc -l) &&
642
+ test 0 -eq $(git ls-files -o | wc -l) &&
643
+
644
+ test $(git rev-parse HEAD:newname) = $(git rev-parse E:newname)
645
+'
646
+
647
test_done