@@ -1402,4 +1402,198 @@ test_expect_failure 'check conflicting modes for regular file' '
1402
1402
)
1403
1403
'
1404
1404
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
+
1405
1599
test_done
0 commit comments