@@ -159,6 +159,7 @@ test_expect_success '1b-check: Merge a directory with another' '
159159# Testcase 1c, Transitive renaming
160160# (Related to testcases 3a and 6d -- when should a transitive rename apply?)
161161# (Related to testcases 9c and 9d -- can transitivity repeat?)
162+ # (Related to testcase 12b -- joint-transitivity?)
162163# Commit O: z/{b,c}, x/d
163164# Commit A: y/{b,c}, x/d
164165# Commit B: z/{b,c,d}
@@ -2871,6 +2872,68 @@ test_expect_failure '9g-check: Renamed directory that only contained immediate s
28712872 )
28722873'
28732874
2875+ # Testcase 9h, Avoid implicit rename if involved as source on other side
2876+ # (Extremely closely related to testcase 3a)
2877+ # Commit O: z/{b,c,d_1}
2878+ # Commit A: z/{b,c,d_2}
2879+ # Commit B: y/{b,c}, x/d_1
2880+ # Expected: y/{b,c}, x/d_2
2881+ # NOTE: If we applied the z/ -> y/ rename to z/d, then we'd end up with
2882+ # a rename/rename(1to2) conflict (z/d -> y/d vs. x/d)
2883+ test_expect_success ' 9h-setup: Avoid dir rename on merely modified path' '
2884+ test_create_repo 9h &&
2885+ (
2886+ cd 9h &&
2887+
2888+ mkdir z &&
2889+ echo b >z/b &&
2890+ echo c >z/c &&
2891+ printf "1\n2\n3\n4\n5\n6\n7\n8\nd\n" >z/d &&
2892+ git add z &&
2893+ test_tick &&
2894+ git commit -m "O" &&
2895+
2896+ git branch O &&
2897+ git branch A &&
2898+ git branch B &&
2899+
2900+ git checkout A &&
2901+ test_tick &&
2902+ echo more >>z/d &&
2903+ git add z/d &&
2904+ git commit -m "A" &&
2905+
2906+ git checkout B &&
2907+ mkdir y &&
2908+ mkdir x &&
2909+ git mv z/b y/ &&
2910+ git mv z/c y/ &&
2911+ git mv z/d x/ &&
2912+ rmdir z &&
2913+ test_tick &&
2914+ git commit -m "B"
2915+ )
2916+ '
2917+
2918+ test_expect_failure ' 9h-check: Avoid dir rename on merely modified path' '
2919+ (
2920+ cd 9h &&
2921+
2922+ git checkout A^0 &&
2923+
2924+ git merge -s recursive B^0 &&
2925+
2926+ git ls-files -s >out &&
2927+ test_line_count = 3 out &&
2928+
2929+ git rev-parse >actual \
2930+ HEAD:y/b HEAD:y/c HEAD:x/d &&
2931+ git rev-parse >expect \
2932+ O:z/b O:z/c A:z/d &&
2933+ test_cmp expect actual
2934+ )
2935+ '
2936+
28742937# ##########################################################################
28752938# Rules suggested by section 9:
28762939#
@@ -3704,4 +3767,237 @@ test_expect_success '11f-check: Avoid deleting not-uptodate with dir rename/rena
37043767 )
37053768'
37063769
3770+ # ##########################################################################
3771+ # SECTION 12: Everything else
3772+ #
3773+ # Tests suggested by others. Tests added after implementation completed
3774+ # and submitted. Grab bag.
3775+ # ##########################################################################
3776+
3777+ # Testcase 12a, Moving one directory hierarchy into another
3778+ # (Related to testcase 9a)
3779+ # Commit O: node1/{leaf1,leaf2}, node2/{leaf3,leaf4}
3780+ # Commit A: node1/{leaf1,leaf2,node2/{leaf3,leaf4}}
3781+ # Commit B: node1/{leaf1,leaf2,leaf5}, node2/{leaf3,leaf4,leaf6}
3782+ # Expected: node1/{leaf1,leaf2,leaf5,node2/{leaf3,leaf4,leaf6}}
3783+
3784+ test_expect_success ' 12a-setup: Moving one directory hierarchy into another' '
3785+ test_create_repo 12a &&
3786+ (
3787+ cd 12a &&
3788+
3789+ mkdir -p node1 node2 &&
3790+ echo leaf1 >node1/leaf1 &&
3791+ echo leaf2 >node1/leaf2 &&
3792+ echo leaf3 >node2/leaf3 &&
3793+ echo leaf4 >node2/leaf4 &&
3794+ git add node1 node2 &&
3795+ test_tick &&
3796+ git commit -m "O" &&
3797+
3798+ git branch O &&
3799+ git branch A &&
3800+ git branch B &&
3801+
3802+ git checkout A &&
3803+ git mv node2/ node1/ &&
3804+ test_tick &&
3805+ git commit -m "A" &&
3806+
3807+ git checkout B &&
3808+ echo leaf5 >node1/leaf5 &&
3809+ echo leaf6 >node2/leaf6 &&
3810+ git add node1 node2 &&
3811+ test_tick &&
3812+ git commit -m "B"
3813+ )
3814+ '
3815+
3816+ test_expect_success ' 12a-check: Moving one directory hierarchy into another' '
3817+ (
3818+ cd 12a &&
3819+
3820+ git checkout A^0 &&
3821+
3822+ git merge -s recursive B^0 &&
3823+
3824+ git ls-files -s >out &&
3825+ test_line_count = 6 out &&
3826+
3827+ git rev-parse >actual \
3828+ HEAD:node1/leaf1 HEAD:node1/leaf2 HEAD:node1/leaf5 \
3829+ HEAD:node1/node2/leaf3 \
3830+ HEAD:node1/node2/leaf4 \
3831+ HEAD:node1/node2/leaf6 &&
3832+ git rev-parse >expect \
3833+ O:node1/leaf1 O:node1/leaf2 B:node1/leaf5 \
3834+ O:node2/leaf3 \
3835+ O:node2/leaf4 \
3836+ B:node2/leaf6 &&
3837+ test_cmp expect actual
3838+ )
3839+ '
3840+
3841+ # Testcase 12b, Moving two directory hierarchies into each other
3842+ # (Related to testcases 1c and 12c)
3843+ # Commit O: node1/{leaf1, leaf2}, node2/{leaf3, leaf4}
3844+ # Commit A: node1/{leaf1, leaf2, node2/{leaf3, leaf4}}
3845+ # Commit B: node2/{leaf3, leaf4, node1/{leaf1, leaf2}}
3846+ # Expected: node1/node2/node1/{leaf1, leaf2},
3847+ # node2/node1/node2/{leaf3, leaf4}
3848+ # NOTE: Without directory renames, we would expect
3849+ # node2/node1/{leaf1, leaf2},
3850+ # node1/node2/{leaf3, leaf4}
3851+ # with directory rename detection, we note that
3852+ # commit A renames node2/ -> node1/node2/
3853+ # commit B renames node1/ -> node2/node1/
3854+ # therefore, applying those directory renames to the initial result
3855+ # (making all four paths experience a transitive renaming), yields
3856+ # the expected result.
3857+ #
3858+ # You may ask, is it weird to have two directories rename each other?
3859+ # To which, I can do no more than shrug my shoulders and say that
3860+ # even simple rules give weird results when given weird inputs.
3861+
3862+ test_expect_success ' 12b-setup: Moving one directory hierarchy into another' '
3863+ test_create_repo 12b &&
3864+ (
3865+ cd 12b &&
3866+
3867+ mkdir -p node1 node2 &&
3868+ echo leaf1 >node1/leaf1 &&
3869+ echo leaf2 >node1/leaf2 &&
3870+ echo leaf3 >node2/leaf3 &&
3871+ echo leaf4 >node2/leaf4 &&
3872+ git add node1 node2 &&
3873+ test_tick &&
3874+ git commit -m "O" &&
3875+
3876+ git branch O &&
3877+ git branch A &&
3878+ git branch B &&
3879+
3880+ git checkout A &&
3881+ git mv node2/ node1/ &&
3882+ test_tick &&
3883+ git commit -m "A" &&
3884+
3885+ git checkout B &&
3886+ git mv node1/ node2/ &&
3887+ test_tick &&
3888+ git commit -m "B"
3889+ )
3890+ '
3891+
3892+ test_expect_failure ' 12b-check: Moving one directory hierarchy into another' '
3893+ (
3894+ cd 12b &&
3895+
3896+ git checkout A^0 &&
3897+
3898+ git merge -s recursive B^0 &&
3899+
3900+ git ls-files -s >out &&
3901+ test_line_count = 4 out &&
3902+
3903+ git rev-parse >actual \
3904+ HEAD:node1/node2/node1/leaf1 \
3905+ HEAD:node1/node2/node1/leaf2 \
3906+ HEAD:node2/node1/node2/leaf3 \
3907+ HEAD:node2/node1/node2/leaf4 &&
3908+ git rev-parse >expect \
3909+ O:node1/leaf1 \
3910+ O:node1/leaf2 \
3911+ O:node2/leaf3 \
3912+ O:node2/leaf4 &&
3913+ test_cmp expect actual
3914+ )
3915+ '
3916+
3917+ # Testcase 12c, Moving two directory hierarchies into each other w/ content merge
3918+ # (Related to testcase 12b)
3919+ # Commit O: node1/{ leaf1_1, leaf2_1}, node2/{leaf3_1, leaf4_1}
3920+ # Commit A: node1/{ leaf1_2, leaf2_2, node2/{leaf3_2, leaf4_2}}
3921+ # Commit B: node2/{node1/{leaf1_3, leaf2_3}, leaf3_3, leaf4_3}
3922+ # Expected: Content merge conflicts for each of:
3923+ # node1/node2/node1/{leaf1, leaf2},
3924+ # node2/node1/node2/{leaf3, leaf4}
3925+ # NOTE: This is *exactly* like 12c, except that every path is modified on
3926+ # each side of the merge.
3927+
3928+ test_expect_success ' 12c-setup: Moving one directory hierarchy into another w/ content merge' '
3929+ test_create_repo 12c &&
3930+ (
3931+ cd 12c &&
3932+
3933+ mkdir -p node1 node2 &&
3934+ printf "1\n2\n3\n4\n5\n6\n7\n8\nleaf1\n" >node1/leaf1 &&
3935+ printf "1\n2\n3\n4\n5\n6\n7\n8\nleaf2\n" >node1/leaf2 &&
3936+ printf "1\n2\n3\n4\n5\n6\n7\n8\nleaf3\n" >node2/leaf3 &&
3937+ printf "1\n2\n3\n4\n5\n6\n7\n8\nleaf4\n" >node2/leaf4 &&
3938+ git add node1 node2 &&
3939+ test_tick &&
3940+ git commit -m "O" &&
3941+
3942+ git branch O &&
3943+ git branch A &&
3944+ git branch B &&
3945+
3946+ git checkout A &&
3947+ git mv node2/ node1/ &&
3948+ for i in `git ls-files`; do echo side A >>$i; done &&
3949+ git add -u &&
3950+ test_tick &&
3951+ git commit -m "A" &&
3952+
3953+ git checkout B &&
3954+ git mv node1/ node2/ &&
3955+ for i in `git ls-files`; do echo side B >>$i; done &&
3956+ git add -u &&
3957+ test_tick &&
3958+ git commit -m "B"
3959+ )
3960+ '
3961+
3962+ test_expect_failure ' 12c-check: Moving one directory hierarchy into another w/ content merge' '
3963+ (
3964+ cd 12c &&
3965+
3966+ git checkout A^0 &&
3967+
3968+ test_must_fail git merge -s recursive B^0 &&
3969+
3970+ git ls-files -u >out &&
3971+ test_line_count = 12 out &&
3972+
3973+ git rev-parse >actual \
3974+ :1:node1/node2/node1/leaf1 \
3975+ :1:node1/node2/node1/leaf2 \
3976+ :1:node2/node1/node2/leaf3 \
3977+ :1:node2/node1/node2/leaf4 \
3978+ :2:node1/node2/node1/leaf1 \
3979+ :2:node1/node2/node1/leaf2 \
3980+ :2:node2/node1/node2/leaf3 \
3981+ :2:node2/node1/node2/leaf4 \
3982+ :3:node1/node2/node1/leaf1 \
3983+ :3:node1/node2/node1/leaf2 \
3984+ :3:node2/node1/node2/leaf3 \
3985+ :3:node2/node1/node2/leaf4 &&
3986+ git rev-parse >expect \
3987+ O:node1/leaf1 \
3988+ O:node1/leaf2 \
3989+ O:node2/leaf3 \
3990+ O:node2/leaf4 \
3991+ A:node1/leaf1 \
3992+ A:node1/leaf2 \
3993+ A:node1/node2/leaf3 \
3994+ A:node1/node2/leaf4 \
3995+ B:node2/node1/leaf1 \
3996+ B:node2/node1/leaf2 \
3997+ B:node2/leaf3 \
3998+ B:node2/leaf4 &&
3999+ test_cmp expect actual
4000+ )
4001+ '
4002+
37074003test_done
0 commit comments