@@ -4403,4 +4403,115 @@ test_expect_success '13d-check(info): messages for rename/rename(1to1) via dual
4403
4403
)
4404
4404
'
4405
4405
4406
+ # Testcase 13e, directory rename in virtual merge base
4407
+ #
4408
+ # This testcase has a slightly different setup than all the above cases, in
4409
+ # order to include a recursive case:
4410
+ #
4411
+ # A C
4412
+ # o - o
4413
+ # / \ / \
4414
+ # O o X ?
4415
+ # \ / \ /
4416
+ # o o
4417
+ # B D
4418
+ #
4419
+ # Commit O: a/{z,y}
4420
+ # Commit A: b/{z,y}
4421
+ # Commit B: a/{z,y,x}
4422
+ # Commit C: b/{z,y,x}
4423
+ # Commit D: b/{z,y}, a/x
4424
+ # Expected: b/{z,y,x} (sort of; see below for why this might not be expected)
4425
+ #
4426
+ # NOTES: 'X' represents a virtual merge base. With the default of
4427
+ # directory rename detection yielding conflicts, merging A and B
4428
+ # results in a conflict complaining about whether 'x' should be
4429
+ # under 'a/' or 'b/'. However, when creating the virtual merge
4430
+ # base 'X', since virtual merge bases need to be written out as a
4431
+ # tree, we cannot have a conflict, so some resolution has to be
4432
+ # picked.
4433
+ #
4434
+ # In choosing the right resolution, it's worth noting here that
4435
+ # commits C & D are merges of A & B that choose different
4436
+ # locations for 'x' (i.e. they resolve the conflict differently),
4437
+ # and so it would be nice when merging C & D if git could detect
4438
+ # this difference of opinion and report a conflict. But the only
4439
+ # way to do so that I can think of would be to have the virtual
4440
+ # merge base place 'x' in some directory other than either 'a/' or
4441
+ # 'b/', which seems a little weird -- especially since it'd result
4442
+ # in a rename/rename(1to2) conflict with a source path that never
4443
+ # existed in any version.
4444
+ #
4445
+ # So, for now, when directory rename detection is set to
4446
+ # 'conflict' just avoid doing directory rename detection at all in
4447
+ # the recursive case. This will not allow us to detect a conflict
4448
+ # in the outer merge for this special kind of setup, but it at
4449
+ # least avoids hitting a BUG().
4450
+ #
4451
+ test_expect_success ' 13e-setup: directory rename detection in recursive case' '
4452
+ test_create_repo 13e &&
4453
+ (
4454
+ cd 13e &&
4455
+
4456
+ mkdir a &&
4457
+ echo z >a/z &&
4458
+ echo y >a/y &&
4459
+ git add a &&
4460
+ test_tick &&
4461
+ git commit -m "O" &&
4462
+
4463
+ git branch O &&
4464
+ git branch A &&
4465
+ git branch B &&
4466
+
4467
+ git checkout A &&
4468
+ git mv a/ b/ &&
4469
+ test_tick &&
4470
+ git commit -m "A" &&
4471
+
4472
+ git checkout B &&
4473
+ echo x >a/x &&
4474
+ git add a &&
4475
+ test_tick &&
4476
+ git commit -m "B" &&
4477
+
4478
+ git branch C A &&
4479
+ git branch D B &&
4480
+
4481
+ git checkout C &&
4482
+ test_must_fail git -c merge.directoryRenames=conflict merge B &&
4483
+ git add b/x &&
4484
+ test_tick &&
4485
+ git commit -m "C" &&
4486
+
4487
+
4488
+ git checkout D &&
4489
+ test_must_fail git -c merge.directoryRenames=conflict merge A &&
4490
+ git add b/x &&
4491
+ mkdir a &&
4492
+ git mv b/x a/x &&
4493
+ test_tick &&
4494
+ git commit -m "D"
4495
+ )
4496
+ '
4497
+
4498
+ test_expect_success ' 13e-check: directory rename detection in recursive case' '
4499
+ (
4500
+ cd 13e &&
4501
+
4502
+ git checkout --quiet D^0 &&
4503
+
4504
+ git -c merge.directoryRenames=conflict merge -s recursive C^0 >out 2>err &&
4505
+
4506
+ test_i18ngrep ! CONFLICT out &&
4507
+ test_i18ngrep ! BUG: err &&
4508
+ test_i18ngrep ! core.dumped err &&
4509
+ test_must_be_empty err &&
4510
+
4511
+ git ls-files >paths &&
4512
+ ! grep a/x paths &&
4513
+ grep b/x paths
4514
+ )
4515
+ '
4516
+
4406
4517
test_done
0 commit comments