t6042: add tests for consistency in file collision conflict handling

Add testcases dealing with file collisions for the following types of conflicts: * add/add * rename/add * rename/rename(2to1) All these conflict types simplify down to two files "colliding" and should thus be handled similarly. This means that rename/add and rename/rename(2to1) conflicts need to be modified to behave the same as add/add conflicts currently do: the colliding files should be two-way merged (instead of the current behavior of writing the two colliding files out to separate temporary unique pathnames). Add testcases which check this; subsequent commits will fix the conflict handling to make these tests pass. Signed-off-by: Elijah Newren <newren@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Elijah Newren committed Nov 7, 2018 at 20:40 UTC bb05c9f7595274bcfabf775ea51b4765c503b055
1 file changed +162
t/t6042-merge-rename-corner-cases.sh
+162
@@ -937,4 +937,166 @@ test_expect_failure 'mod6-check: chains of rename/rename(1to2) and rename/rename
937 )
938 '
939
940 +test_conflicts_with_adds_and_renames() {
941 + sideL=$1
942 + sideR=$2
943 + expect=$3
944 +
945 + # Setup:
946 + # L
947 + # / \
948 + # master ?
949 + # \ /
950 + # R
951 + #
952 + # Where:
953 + # Both L and R have files named 'three' which collide. Each of
954 + # the colliding files could have been involved in a rename, in
955 + # which case there was a file named 'one' or 'two' that was
956 + # modified on the opposite side of history and renamed into the
957 + # collision on this side of history.
958 + #
959 + # Questions:
960 + # 1) The index should contain both a stage 2 and stage 3 entry
961 + # for the colliding file. Does it?
962 + # 2) When renames are involved, the content merges are clean, so
963 + # the index should reflect the content merges, not merely the
964 + # version of the colliding file from the prior commit. Does
965 + # it?
966 + # 3) There should be a file in the worktree named 'three'
967 + # containing the two-way merged contents of the content-merged
968 + # versions of 'three' from each of the two colliding
969 + # files. Is it present?
970 + # 4) There should not be any three~* files in the working
971 + # tree
972 + test_expect_success "setup simple $sideL/$sideR conflict" '
973 + test_create_repo simple_${sideL}_${sideR} &&
974 + (
975 + cd simple_${sideL}_${sideR} &&
976 +
977 + # Create some related files now
978 + for i in $(test_seq 1 10)
979 + do
980 + echo Random base content line $i
981 + done >file_v1 &&
982 + cp file_v1 file_v2 &&
983 + echo modification >>file_v2 &&
984 +
985 + cp file_v1 file_v3 &&
986 + echo more stuff >>file_v3 &&
987 + cp file_v3 file_v4 &&
988 + echo yet more stuff >>file_v4 &&
989 +
990 + # Use a tag to record both these files for simple
991 + # access, and clean out these untracked files
992 + git tag file_v1 $(git hash-object -w file_v1) &&
993 + git tag file_v2 $(git hash-object -w file_v2) &&
994 + git tag file_v3 $(git hash-object -w file_v3) &&
995 + git tag file_v4 $(git hash-object -w file_v4) &&
996 + git clean -f &&
997 +
998 + # Setup original commit (or merge-base), consisting of
999 + # files named "one" and "two" if renames were involved.
1000 + touch irrelevant_file &&
1001 + git add irrelevant_file &&
1002 + if [ $sideL = "rename" ]
1003 + then
1004 + git show file_v1 >one &&
1005 + git add one
1006 + fi &&
1007 + if [ $sideR = "rename" ]
1008 + then
1009 + git show file_v3 >two &&
1010 + git add two
1011 + fi &&
1012 + test_tick && git commit -m initial &&
1013 +
1014 + git branch L &&
1015 + git branch R &&
1016 +
1017 + # Handle the left side
1018 + git checkout L &&
1019 + if [ $sideL = "rename" ]
1020 + then
1021 + git mv one three
1022 + else
1023 + git show file_v2 >three &&
1024 + git add three
1025 + fi &&
1026 + if [ $sideR = "rename" ]
1027 + then
1028 + git show file_v4 >two &&
1029 + git add two
1030 + fi &&
1031 + test_tick && git commit -m L &&
1032 +
1033 + # Handle the right side
1034 + git checkout R &&
1035 + if [ $sideL = "rename" ]
1036 + then
1037 + git show file_v2 >one &&
1038 + git add one
1039 + fi &&
1040 + if [ $sideR = "rename" ]
1041 + then
1042 + git mv two three
1043 + else
1044 + git show file_v4 >three &&
1045 + git add three
1046 + fi &&
1047 + test_tick && git commit -m R
1048 + )
1049 + '
1050 +
1051 + test_expect_$expect "check simple $sideL/$sideR conflict" '
1052 + (
1053 + cd simple_${sideL}_${sideR} &&
1054 +
1055 + git checkout L^0 &&
1056 +
1057 + # Merge must fail; there is a conflict
1058 + test_must_fail git merge -s recursive R^0 &&
1059 +
1060 + # Make sure the index has the right number of entries
1061 + git ls-files -s >out &&
1062 + test_line_count = 3 out &&
1063 + git ls-files -u >out &&
1064 + test_line_count = 2 out &&
1065 + # Ensure we have the correct number of untracked files
1066 + git ls-files -o >out &&
1067 + test_line_count = 1 out &&
1068 +
1069 + # Nothing should have touched irrelevant_file
1070 + git rev-parse >actual \
1071 + :0:irrelevant_file \
1072 + :2:three \
1073 + :3:three &&
1074 + git rev-parse >expected \
1075 + master:irrelevant_file \
1076 + file_v2 \
1077 + file_v4 &&
1078 + test_cmp expected actual &&
1079 +
1080 + # Make sure we have the correct merged contents for
1081 + # three
1082 + git show file_v1 >expected &&
1083 + cat <<-\EOF >>expected &&
1084 + <<<<<<< HEAD
1085 + modification
1086 + =======
1087 + more stuff
1088 + yet more stuff
1089 + >>>>>>> R^0
1090 + EOF
1091 +
1092 + test_cmp expected three
1093 + )
1094 + '
1095 +}
1096 +
1097 +test_conflicts_with_adds_and_renames rename rename failure
1098 +test_conflicts_with_adds_and_renames rename add failure
1099 +test_conflicts_with_adds_and_renames add rename failure
1100 +test_conflicts_with_adds_and_renames add add success
1101 +
1102 test_done