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