Skip to content

Commit b28eeb3

Browse files
newrengitster
authored andcommitted
t6036, t6042: testcases for rename collision of already conflicting files
When a single file is renamed, it can also be modified, yielding the possibility of that renamed file having content conflicts. If two different such files are renamed into the same location, then two-way merging those files may result in nested conflicts. Add a testcase that makes sure we get this case correct, and uses different lengths of conflict markers to differentiate between the different nestings. Also add another case with an extra (i.e. third) level of conflict markers due to using merge.conflictstyle=diff3 and the virtual merge base also having conflicts present. Signed-off-by: Elijah Newren <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent bb05c9f commit b28eeb3

File tree

2 files changed

+312
-0
lines changed

2 files changed

+312
-0
lines changed

t/t6036-recursive-corner-cases.sh

Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,4 +1402,198 @@ test_expect_failure 'check conflicting modes for regular file' '
14021402
)
14031403
'
14041404

1405+
# Setup:
1406+
# L1---L2
1407+
# / \ / \
1408+
# master X ?
1409+
# \ / \ /
1410+
# R1---R2
1411+
#
1412+
# Where:
1413+
# master has two files, named 'b' and 'a'
1414+
# branches L1 and R1 both modify each of the two files in conflicting ways
1415+
#
1416+
# L2 is a merge of R1 into L1; more on it later.
1417+
# R2 is a merge of L1 into R1; more on it later.
1418+
#
1419+
# X is an auto-generated merge-base used when merging L2 and R2.
1420+
# since X is a merge of L1 and R1, it has conflicting versions of each file
1421+
#
1422+
# More about L2 and R2:
1423+
# - both resolve the conflicts in 'b' and 'a' differently
1424+
# - L2 renames 'b' to 'm'
1425+
# - R2 renames 'a' to 'm'
1426+
#
1427+
# In the end, in file 'm' we have four different conflicting files (from
1428+
# two versions of 'b' and two of 'a'). In addition, if
1429+
# merge.conflictstyle is diff3, then the base version also has
1430+
# conflict markers of its own, leading to a total of three levels of
1431+
# conflict markers. This is a pretty weird corner case, but we just want
1432+
# to ensure that we handle it as well as practical.
1433+
1434+
test_expect_success 'setup nested conflicts' '
1435+
test_create_repo nested_conflicts &&
1436+
(
1437+
cd nested_conflicts &&
1438+
1439+
# Create some related files now
1440+
for i in $(test_seq 1 10)
1441+
do
1442+
echo Random base content line $i
1443+
done >initial &&
1444+
1445+
cp initial b_L1 &&
1446+
cp initial b_R1 &&
1447+
cp initial b_L2 &&
1448+
cp initial b_R2 &&
1449+
cp initial a_L1 &&
1450+
cp initial a_R1 &&
1451+
cp initial a_L2 &&
1452+
cp initial a_R2 &&
1453+
1454+
test_write_lines b b_L1 >>b_L1 &&
1455+
test_write_lines b b_R1 >>b_R1 &&
1456+
test_write_lines b b_L2 >>b_L2 &&
1457+
test_write_lines b b_R2 >>b_R2 &&
1458+
test_write_lines a a_L1 >>a_L1 &&
1459+
test_write_lines a a_R1 >>a_R1 &&
1460+
test_write_lines a a_L2 >>a_L2 &&
1461+
test_write_lines a a_R2 >>a_R2 &&
1462+
1463+
# Setup original commit (or merge-base), consisting of
1464+
# files named "b" and "a"
1465+
cp initial b &&
1466+
cp initial a &&
1467+
echo b >>b &&
1468+
echo a >>a &&
1469+
git add b a &&
1470+
test_tick && git commit -m initial &&
1471+
1472+
git branch L &&
1473+
git branch R &&
1474+
1475+
# Handle the left side
1476+
git checkout L &&
1477+
mv -f b_L1 b &&
1478+
mv -f a_L1 a &&
1479+
git add b a &&
1480+
test_tick && git commit -m "version L1 of files" &&
1481+
git tag L1 &&
1482+
1483+
# Handle the right side
1484+
git checkout R &&
1485+
mv -f b_R1 b &&
1486+
mv -f a_R1 a &&
1487+
git add b a &&
1488+
test_tick && git commit -m "verson R1 of files" &&
1489+
git tag R1 &&
1490+
1491+
# Create first merge on left side
1492+
git checkout L &&
1493+
test_must_fail git merge R1 &&
1494+
mv -f b_L2 b &&
1495+
mv -f a_L2 a &&
1496+
git add b a &&
1497+
git mv b m &&
1498+
test_tick && git commit -m "left merge, rename b->m" &&
1499+
git tag L2 &&
1500+
1501+
# Create first merge on right side
1502+
git checkout R &&
1503+
test_must_fail git merge L1 &&
1504+
mv -f b_R2 b &&
1505+
mv -f a_R2 a &&
1506+
git add b a &&
1507+
git mv a m &&
1508+
test_tick && git commit -m "right merge, rename a->m" &&
1509+
git tag R2
1510+
)
1511+
'
1512+
1513+
test_expect_failure 'check nested conflicts' '
1514+
(
1515+
cd nested_conflicts &&
1516+
1517+
git clean -f &&
1518+
git checkout L2^0 &&
1519+
1520+
# Merge must fail; there is a conflict
1521+
test_must_fail git -c merge.conflictstyle=diff3 merge -s recursive R2^0 &&
1522+
1523+
# Make sure the index has the right number of entries
1524+
git ls-files -s >out &&
1525+
test_line_count = 2 out &&
1526+
git ls-files -u >out &&
1527+
test_line_count = 2 out &&
1528+
# Ensure we have the correct number of untracked files
1529+
git ls-files -o >out &&
1530+
test_line_count = 1 out &&
1531+
1532+
# Create a and b from virtual merge base X
1533+
git cat-file -p master:a >base &&
1534+
git cat-file -p L1:a >ours &&
1535+
git cat-file -p R1:a >theirs &&
1536+
test_must_fail git merge-file --diff3 \
1537+
-L "Temporary merge branch 1" \
1538+
-L "merged common ancestors" \
1539+
-L "Temporary merge branch 2" \
1540+
ours \
1541+
base \
1542+
theirs &&
1543+
sed -e "s/^\([<|=>]\)/\1\1/" ours >vmb_a &&
1544+
1545+
git cat-file -p master:b >base &&
1546+
git cat-file -p L1:b >ours &&
1547+
git cat-file -p R1:b >theirs &&
1548+
test_must_fail git merge-file --diff3 \
1549+
-L "Temporary merge branch 1" \
1550+
-L "merged common ancestors" \
1551+
-L "Temporary merge branch 2" \
1552+
ours \
1553+
base \
1554+
theirs &&
1555+
sed -e "s/^\([<|=>]\)/\1\1/" ours >vmb_b &&
1556+
1557+
# Compare :2:m to expected values
1558+
git cat-file -p L2:m >ours &&
1559+
git cat-file -p R2:b >theirs &&
1560+
test_must_fail git merge-file --diff3 \
1561+
-L "HEAD:m" \
1562+
-L "merged common ancestors:b" \
1563+
-L "R2^0:b" \
1564+
ours \
1565+
vmb_b \
1566+
theirs &&
1567+
sed -e "s/^\([<|=>]\)/\1\1/" ours >m_stage_2 &&
1568+
git cat-file -p :2:m >actual &&
1569+
test_cmp m_stage_2 actual &&
1570+
1571+
# Compare :3:m to expected values
1572+
git cat-file -p L2:a >ours &&
1573+
git cat-file -p R2:m >theirs &&
1574+
test_must_fail git merge-file --diff3 \
1575+
-L "HEAD:a" \
1576+
-L "merged common ancestors:a" \
1577+
-L "R2^0:m" \
1578+
ours \
1579+
vmb_a \
1580+
theirs &&
1581+
sed -e "s/^\([<|=>]\)/\1\1/" ours >m_stage_3 &&
1582+
git cat-file -p :3:m >actual &&
1583+
test_cmp m_stage_3 actual &&
1584+
1585+
# Compare m to expected contents
1586+
>empty &&
1587+
cp -a m_stage_2 expected_final_m &&
1588+
test_must_fail git merge-file --diff3 \
1589+
-L "HEAD" \
1590+
-L "merged common ancestors" \
1591+
-L "R2^0" \
1592+
expected_final_m \
1593+
empty \
1594+
m_stage_3 &&
1595+
test_cmp expected_final_m m
1596+
)
1597+
'
1598+
14051599
test_done

t/t6042-merge-rename-corner-cases.sh

Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1099,4 +1099,122 @@ test_conflicts_with_adds_and_renames rename add failure
10991099
test_conflicts_with_adds_and_renames add rename failure
11001100
test_conflicts_with_adds_and_renames add add success
11011101

1102+
# Setup:
1103+
# L
1104+
# / \
1105+
# master ?
1106+
# \ /
1107+
# R
1108+
#
1109+
# Where:
1110+
# master has two files, named 'one' and 'two'.
1111+
# branches L and R both modify 'one', in conflicting ways.
1112+
# branches L and R both modify 'two', in conflicting ways.
1113+
# branch L also renames 'one' to 'three'.
1114+
# branch R also renames 'two' to 'three'.
1115+
#
1116+
# So, we have four different conflicting files that all end up at path
1117+
# 'three'.
1118+
test_expect_success 'setup nested conflicts from rename/rename(2to1)' '
1119+
test_create_repo nested_conflicts_from_rename_rename &&
1120+
(
1121+
cd nested_conflicts_from_rename_rename &&
1122+
1123+
# Create some related files now
1124+
for i in $(test_seq 1 10)
1125+
do
1126+
echo Random base content line $i
1127+
done >file_v1 &&
1128+
1129+
cp file_v1 file_v2 &&
1130+
cp file_v1 file_v3 &&
1131+
cp file_v1 file_v4 &&
1132+
cp file_v1 file_v5 &&
1133+
cp file_v1 file_v6 &&
1134+
1135+
echo one >>file_v1 &&
1136+
echo uno >>file_v2 &&
1137+
echo eins >>file_v3 &&
1138+
1139+
echo two >>file_v4 &&
1140+
echo dos >>file_v5 &&
1141+
echo zwei >>file_v6 &&
1142+
1143+
# Setup original commit (or merge-base), consisting of
1144+
# files named "one" and "two".
1145+
mv file_v1 one &&
1146+
mv file_v4 two &&
1147+
git add one two &&
1148+
test_tick && git commit -m english &&
1149+
1150+
git branch L &&
1151+
git branch R &&
1152+
1153+
# Handle the left side
1154+
git checkout L &&
1155+
git mv one three &&
1156+
mv -f file_v2 three &&
1157+
mv -f file_v5 two &&
1158+
git add two three &&
1159+
test_tick && git commit -m spanish &&
1160+
1161+
# Handle the right side
1162+
git checkout R &&
1163+
git mv two three &&
1164+
mv -f file_v3 one &&
1165+
mv -f file_v6 three &&
1166+
git add one three &&
1167+
test_tick && git commit -m german
1168+
)
1169+
'
1170+
1171+
test_expect_failure 'check nested conflicts from rename/rename(2to1)' '
1172+
(
1173+
cd nested_conflicts_from_rename_rename &&
1174+
1175+
git checkout L^0 &&
1176+
1177+
# Merge must fail; there is a conflict
1178+
test_must_fail git merge -s recursive R^0 &&
1179+
1180+
# Make sure the index has the right number of entries
1181+
git ls-files -s >out &&
1182+
test_line_count = 2 out &&
1183+
git ls-files -u >out &&
1184+
test_line_count = 2 out &&
1185+
# Ensure we have the correct number of untracked files
1186+
git ls-files -o >out &&
1187+
test_line_count = 1 out &&
1188+
1189+
# Compare :2:three to expected values
1190+
git cat-file -p master:one >base &&
1191+
git cat-file -p L:three >ours &&
1192+
git cat-file -p R:one >theirs &&
1193+
test_must_fail git merge-file \
1194+
-L "HEAD:three" -L "" -L "R^0:one" \
1195+
ours base theirs &&
1196+
sed -e "s/^\([<=>]\)/\1\1/" ours >L-three &&
1197+
git cat-file -p :2:three >expect &&
1198+
test_cmp expect L-three &&
1199+
1200+
# Compare :2:three to expected values
1201+
git cat-file -p master:two >base &&
1202+
git cat-file -p L:two >ours &&
1203+
git cat-file -p R:three >theirs &&
1204+
test_must_fail git merge-file \
1205+
-L "HEAD:two" -L "" -L "R^0:three" \
1206+
ours base theirs &&
1207+
sed -e "s/^\([<=>]\)/\1\1/" ours >R-three &&
1208+
git cat-file -p :3:three >expect &&
1209+
test_cmp expect R-three &&
1210+
1211+
# Compare three to expected contents
1212+
>empty &&
1213+
test_must_fail git merge-file \
1214+
-L "HEAD" -L "" -L "R^0" \
1215+
L-three empty R-three &&
1216+
test_cmp three L-three
1217+
)
1218+
'
1219+
11021220
test_done

0 commit comments

Comments
 (0)