git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
git ls-files -s >out &&
test_line_count = 4 out &&
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 4 out &&
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
git ls-files -s >out &&
test_line_count = 3 out &&
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (rename/rename)" out &&
git ls-files -s >out &&
git ls-files -u >out &&
test_line_count = 2 out &&
git ls-files -o >out &&
- test_line_count = 3 out &&
+ test_line_count = 1 out &&
git rev-parse >actual \
:0:x/b :0:x/c :0:x/d :0:x/e :0:x/m :0:x/n &&
A:y/wham B:z/wham &&
test_cmp expect actual &&
- test_path_is_missing x/wham &&
- test_path_is_file x/wham~HEAD &&
- test_path_is_file x/wham~B^0 &&
-
- git hash-object >actual \
- x/wham~HEAD x/wham~B^0 &&
- git rev-parse >expect \
- A:y/wham B:z/wham &&
- test_cmp expect actual
+ # Test that the two-way merge in x/wham is as expected
+ git cat-file -p :2:x/wham >expect &&
+ git cat-file -p :3:x/wham >other &&
+ >empty &&
+ test_must_fail git merge-file \
+ -L "HEAD" \
+ -L "" \
+ -L "B^0" \
+ expect empty other &&
+ test_cmp expect x/wham
)
'
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 3 out &&
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 6 out &&
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT.*directory rename split" out &&
git ls-files -s >out &&
git checkout A^0 &&
- git merge -s recursive B^0 >out &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
git ls-files -s >out &&
test_line_count = 3 out &&
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 3 out &&
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep CONFLICT.*rename/rename.*z/d.*x/d.*w/d out &&
test_i18ngrep ! CONFLICT.*rename/rename.*y/d out &&
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 5 out &&
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT.*implicit dir rename" out &&
git ls-files -s >out &&
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (add/add).* y/d" out &&
git ls-files -s >out &&
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (rename/rename).*x/d.*w/d.*z/d" out &&
test_i18ngrep "CONFLICT (add/add).* y/d" out &&
git ls-files -u >out &&
test_line_count = 6 out &&
git ls-files -o >out &&
- test_line_count = 3 out &&
+ test_line_count = 1 out &&
git rev-parse >actual \
:0:y/b :0:y/c :0:y/e &&
test_cmp expect actual &&
git hash-object >actual \
- w/d~HEAD w/d~B^0 z/d &&
+ z/d &&
git rev-parse >expect \
- O:x/d B:w/d O:x/d &&
+ O:x/d &&
test_cmp expect actual &&
test_path_is_missing x/d &&
test_path_is_file y/d &&
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (file/directory).*y/d" out &&
git ls-files -s >out &&
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (rename/delete).*z/c.*y/c" out &&
git ls-files -s >out &&
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 3 out &&
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 3 out &&
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 3 out &&
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 4 out &&
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (rename/rename).*z/b.*y/b.*w/b" out &&
test_i18ngrep "CONFLICT (rename/rename).*z/c.*y/c.*x/c" out &&
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (rename/rename)" out &&
git ls-files -s >out &&
git ls-files -u >out &&
test_line_count = 2 out &&
git ls-files -o >out &&
- test_line_count = 3 out &&
+ test_line_count = 1 out &&
git rev-parse >actual \
:0:y/b :0:y/c :2:y/d :3:y/d &&
O:z/b O:z/c O:w/d O:x/d &&
test_cmp expect actual &&
- test_path_is_missing y/d &&
- test_path_is_file y/d~HEAD &&
- test_path_is_file y/d~B^0 &&
-
- git hash-object >actual \
- y/d~HEAD y/d~B^0 &&
- git rev-parse >expect \
- O:w/d O:x/d &&
- test_cmp expect actual
+ # Test that the two-way merge in y/d is as expected
+ git cat-file -p :2:y/d >expect &&
+ git cat-file -p :3:y/d >other &&
+ >empty &&
+ test_must_fail git merge-file \
+ -L "HEAD" \
+ -L "" \
+ -L "B^0" \
+ expect empty other &&
+ test_cmp expect y/d
)
'
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (rename/rename).*x/d.*w/d.*y/d" out &&
git ls-files -s >out &&
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (rename/delete).*x/d.*y/d" out &&
git ls-files -s >out &&
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (rename/delete).*x/d.*y/d" out &&
git ls-files -s >out &&
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 6 out &&
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 6 out &&
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (modify/delete).* z/d" out &&
git ls-files -s >out &&
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 3 out &&
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out 2>err &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
test_i18ngrep CONFLICT.*rename/rename.*z/c.*y/c.*w/c out &&
test_i18ngrep CONFLICT.*rename/rename.*z/b.*y/b.*w/b out &&
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 7 out &&
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 3 out &&
git checkout A^0 &&
- git merge -s recursive B^0 >out &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "WARNING: Avoiding applying x -> z rename to x/f" out &&
git ls-files -s >out &&
git checkout A^0 &&
- git merge -s recursive B^0 >out &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
test_i18ngrep "WARNING: Avoiding applying z -> y rename to z/t" out &&
test_i18ngrep "WARNING: Avoiding applying y -> x rename to y/a" out &&
test_i18ngrep "WARNING: Avoiding applying x -> w rename to x/b" out &&
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 >out &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&
grep "CONFLICT (implicit dir rename): Cannot map more than one path to combined/yo" out >error_line &&
grep -q dir1/yo error_line &&
grep -q dir2/yo error_line &&
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 4 out &&
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 4 out &&
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 3 out &&
echo very >z/c &&
echo important >z/d &&
- test_must_fail git merge -s recursive B^0 >out 2>err &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
test_i18ngrep "The following untracked working tree files would be overwritten by merge" err &&
git ls-files -s >out &&
echo important >y/d &&
echo contents >y/e &&
- test_must_fail git merge -s recursive B^0 >out 2>err &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
test_i18ngrep "CONFLICT (rename/delete).*Version B\^0 of y/d left in tree at y/d~B\^0" out &&
test_i18ngrep "Error: Refusing to lose untracked file at y/e; writing to y/e~B\^0 instead" out &&
git checkout A^0 &&
echo important >y/c &&
- test_must_fail git merge -s recursive B^0 >out 2>err &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
test_i18ngrep "CONFLICT (rename/rename)" out &&
test_i18ngrep "Refusing to lose untracked file at y/c; adding as y/c~B\^0 instead" out &&
)
'
+test_expect_success '10c-check: Overwrite untracked with dir rename/rename(1to2), other direction' '
+ (
+ cd 10c &&
+
+ git reset --hard &&
+ git clean -fdqx &&
+
+ git checkout B^0 &&
+ mkdir y &&
+ echo important >y/c &&
+
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive A^0 >out 2>err &&
+ test_i18ngrep "CONFLICT (rename/rename)" out &&
+ test_i18ngrep "Refusing to lose untracked file at y/c; adding as y/c~HEAD instead" out &&
+
+ git ls-files -s >out &&
+ test_line_count = 6 out &&
+ git ls-files -u >out &&
+ test_line_count = 3 out &&
+ git ls-files -o >out &&
+ test_line_count = 3 out &&
+
+ git rev-parse >actual \
+ :0:y/a :0:y/b :0:x/d :1:x/c :3:w/c :2:y/c &&
+ git rev-parse >expect \
+ O:z/a O:z/b O:x/d O:x/c O:x/c O:x/c &&
+ test_cmp expect actual &&
+
+ git hash-object y/c~HEAD >actual &&
+ git rev-parse O:x/c >expect &&
+ test_cmp expect actual &&
+
+ echo important >expect &&
+ test_cmp expect y/c
+ )
+'
+
# Testcase 10d, Delete untracked w/ dir rename/rename(2to1)
# Commit O: z/{a,b,c_1}, x/{d,e,f_2}
# Commit A: y/{a,b}, x/{d,e,f_2,wham_1} + untracked y/wham
# Commit B: z/{a,b,c_1,wham_2}, y/{d,e}
-# Expected: Failed Merge; y/{a,b,d,e} + untracked y/{wham,wham~B^0,wham~HEAD}+
+# Expected: Failed Merge; y/{a,b,d,e} + untracked y/{wham,wham~merged}+
# CONFLICT(rename/rename) z/c_1 vs x/f_2 -> y/wham
# ERROR_MSG(Refusing to lose untracked file at y/wham)
git checkout A^0 &&
echo important >y/wham &&
- test_must_fail git merge -s recursive B^0 >out 2>err &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
test_i18ngrep "CONFLICT (rename/rename)" out &&
test_i18ngrep "Refusing to lose untracked file at y/wham" out &&
git ls-files -u >out &&
test_line_count = 2 out &&
git ls-files -o >out &&
- test_line_count = 4 out &&
+ test_line_count = 3 out &&
git rev-parse >actual \
:0:y/a :0:y/b :0:y/d :0:y/e :2:y/wham :3:y/wham &&
echo important >expect &&
test_cmp expect y/wham &&
- git hash-object >actual \
- y/wham~B^0 y/wham~HEAD &&
- git rev-parse >expect \
- O:x/f O:z/c &&
- test_cmp expect actual
+ # Test that the two-way merge in y/wham~merged is as expected
+ git cat-file -p :2:y/wham >expect &&
+ git cat-file -p :3:y/wham >other &&
+ >empty &&
+ test_must_fail git merge-file \
+ -L "HEAD" \
+ -L "" \
+ -L "B^0" \
+ expect empty other &&
+ test_cmp expect y/wham~merged
)
'
mkdir z &&
echo random >z/c &&
- git merge -s recursive B^0 >out 2>err &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
test_i18ngrep ! "following untracked working tree files would be overwritten by merge" err &&
git ls-files -s >out &&
git checkout A^0 &&
echo stuff >>z/c &&
- test_must_fail git merge -s recursive B^0 >out 2>err &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
test_i18ngrep "Refusing to lose dirty file at z/c" out &&
test_seq 1 10 >expected &&
git checkout A^0 &&
echo stuff >>z/c &&
- git merge -s recursive B^0 >out 2>err &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
test_i18ngrep "Refusing to lose dirty file at z/c" out &&
grep -q stuff z/c &&
git checkout A^0 &&
echo stuff >>y/c &&
- test_must_fail git merge -s recursive B^0 >out 2>err &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
test_i18ngrep "following files would be overwritten by merge" err &&
grep -q stuff y/c &&
git checkout A^0 &&
echo stuff >>z/c &&
- test_must_fail git merge -s recursive B^0 >out 2>err &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
test_i18ngrep "Refusing to lose dirty file at z/c" out &&
grep -q stuff z/c &&
git checkout A^0 &&
echo mods >>y/c &&
- test_must_fail git merge -s recursive B^0 >out 2>err &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
test_i18ngrep "CONFLICT (rename/rename)" out &&
test_i18ngrep "Refusing to lose dirty file at y/c" out &&
git ls-files -u >out &&
test_line_count = 4 out &&
git ls-files -o >out &&
- test_line_count = 4 out &&
+ test_line_count = 3 out &&
echo different >expected &&
echo mods >>expected &&
O:z/a O:z/b O:x/d O:x/c O:x/c A:y/c O:x/c &&
test_cmp expect actual &&
- git hash-object >actual \
- y/c~B^0 y/c~HEAD &&
- git rev-parse >expect \
- O:x/c A:y/c &&
- test_cmp expect actual
+ # See if y/c~merged has expected contents; requires manually
+ # doing the expected file merge
+ git cat-file -p A:y/c >c1 &&
+ git cat-file -p B:z/c >c2 &&
+ >empty &&
+ test_must_fail git merge-file \
+ -L "HEAD" \
+ -L "" \
+ -L "B^0" \
+ c1 empty c2 &&
+ test_cmp c1 y/c~merged
)
'
# Commit O: z/{a,b}, x/{c_1,d_2}
# Commit A: y/{a,b,wham_1}, x/d_2, except y/wham has uncommitted mods
# Commit B: z/{a,b,wham_2}, x/c_1
-# Expected: Failed Merge; y/{a,b} + untracked y/{wham~B^0,wham~B^HEAD} +
+# Expected: Failed Merge; y/{a,b} + untracked y/{wham~merged} +
# y/wham with dirty changes from before merge +
# CONFLICT(rename/rename) x/c vs x/d -> y/wham
# ERROR_MSG(Refusing to lose dirty file at y/wham)
git checkout A^0 &&
echo important >>y/wham &&
- test_must_fail git merge -s recursive B^0 >out 2>err &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
test_i18ngrep "CONFLICT (rename/rename)" out &&
test_i18ngrep "Refusing to lose dirty file at y/wham" out &&
git ls-files -u >out &&
test_line_count = 2 out &&
git ls-files -o >out &&
- test_line_count = 4 out &&
+ test_line_count = 3 out &&
test_seq 1 10 >expected &&
echo important >>expected &&
test_cmp expected y/wham &&
test_must_fail git rev-parse :1:y/wham &&
- git hash-object >actual \
- y/wham~B^0 y/wham~HEAD &&
- git rev-parse >expect \
- O:x/d O:x/c &&
- test_cmp expect actual &&
git rev-parse >actual \
:0:y/a :0:y/b :2:y/wham :3:y/wham &&
git rev-parse >expect \
O:z/a O:z/b O:x/c O:x/d &&
- test_cmp expect actual
+ test_cmp expect actual &&
+
+ # Test that the two-way merge in y/wham~merged is as expected
+ git cat-file -p :2:y/wham >expect &&
+ git cat-file -p :3:y/wham >other &&
+ >empty &&
+ test_must_fail git merge-file \
+ -L "HEAD" \
+ -L "" \
+ -L "B^0" \
+ expect empty other &&
+ test_cmp expect y/wham~merged
)
'
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 6 out &&
# To which, I can do no more than shrug my shoulders and say that
# even simple rules give weird results when given weird inputs.
-test_expect_success '12b-setup: Moving one directory hierarchy into another' '
+test_expect_success '12b-setup: Moving two directory hierarchies into each other' '
test_create_repo 12b &&
(
cd 12b &&
)
'
-test_expect_success '12b-check: Moving one directory hierarchy into another' '
+test_expect_success '12b-check: Moving two directory hierarchies into each other' '
(
cd 12b &&
git checkout A^0 &&
- git merge -s recursive B^0 &&
+ git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 4 out &&
git checkout A^0 &&
- test_must_fail git merge -s recursive B^0 &&
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 &&
git ls-files -u >out &&
test_line_count = 12 out &&
)
'
+###########################################################################
+# SECTION 13: Checking informational and conflict messages
+#
+# A year after directory rename detection became the default, it was
+# instead decided to report conflicts on the pathname on the basis that
+# some users may expect the new files added or moved into a directory to
+# be unrelated to all the other files in that directory, and thus that
+# directory rename detection is unexpected. Test that the messages printed
+# match our expectation.
+###########################################################################
+
+# Testcase 13a, Basic directory rename with newly added files
+# Commit O: z/{b,c}
+# Commit A: y/{b,c}
+# Commit B: z/{b,c,d,e/f}
+# Expected: y/{b,c,d,e/f}, with notices/conflicts for both y/d and y/e/f
+
+test_expect_success '13a-setup: messages for newly added files' '
+ test_create_repo 13a &&
+ (
+ cd 13a &&
+
+ mkdir z &&
+ echo b >z/b &&
+ echo c >z/c &&
+ git add z &&
+ test_tick &&
+ git commit -m "O" &&
+
+ git branch O &&
+ git branch A &&
+ git branch B &&
+
+ git checkout A &&
+ git mv z y &&
+ test_tick &&
+ git commit -m "A" &&
+
+ git checkout B &&
+ echo d >z/d &&
+ mkdir z/e &&
+ echo f >z/e/f &&
+ git add z/d z/e/f &&
+ test_tick &&
+ git commit -m "B"
+ )
+'
+
+test_expect_success '13a-check(conflict): messages for newly added files' '
+ (
+ cd 13a &&
+
+ git checkout A^0 &&
+
+ test_must_fail git merge -s recursive B^0 >out 2>err &&
+
+ test_i18ngrep CONFLICT..file.location.*z/e/f.added.in.B^0.*y/e/f out &&
+ test_i18ngrep CONFLICT..file.location.*z/d.added.in.B^0.*y/d out &&
+
+ git ls-files >paths &&
+ ! grep z/ paths &&
+ grep "y/[de]" paths &&
+
+ test_path_is_missing z/d &&
+ test_path_is_file y/d &&
+ test_path_is_missing z/e/f &&
+ test_path_is_file y/e/f
+ )
+'
+
+test_expect_success '13a-check(info): messages for newly added files' '
+ (
+ cd 13a &&
+
+ git reset --hard &&
+ git checkout A^0 &&
+
+ git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
+
+ test_i18ngrep Path.updated:.*z/e/f.added.in.B^0.*y/e/f out &&
+ test_i18ngrep Path.updated:.*z/d.added.in.B^0.*y/d out &&
+
+ git ls-files >paths &&
+ ! grep z/ paths &&
+ grep "y/[de]" paths &&
+
+ test_path_is_missing z/d &&
+ test_path_is_file y/d &&
+ test_path_is_missing z/e/f &&
+ test_path_is_file y/e/f
+ )
+'
+
+# Testcase 13b, Transitive rename with conflicted content merge and default
+# "conflict" setting
+# (Related to testcase 1c, 9b)
+# Commit O: z/{b,c}, x/d_1
+# Commit A: y/{b,c}, x/d_2
+# Commit B: z/{b,c,d_3}
+# Expected: y/{b,c,d_merged}, with two conflict messages for y/d,
+# one about content, and one about file location
+
+test_expect_success '13b-setup: messages for transitive rename with conflicted content' '
+ test_create_repo 13b &&
+ (
+ cd 13b &&
+
+ mkdir x &&
+ mkdir z &&
+ test_seq 1 10 >x/d &&
+ echo b >z/b &&
+ echo c >z/c &&
+ git add x z &&
+ test_tick &&
+ git commit -m "O" &&
+
+ git branch O &&
+ git branch A &&
+ git branch B &&
+
+ git checkout A &&
+ git mv z y &&
+ echo 11 >>x/d &&
+ git add x/d &&
+ test_tick &&
+ git commit -m "A" &&
+
+ git checkout B &&
+ echo eleven >>x/d &&
+ git mv x/d z/d &&
+ git add z/d &&
+ test_tick &&
+ git commit -m "B"
+ )
+'
+
+test_expect_success '13b-check(conflict): messages for transitive rename with conflicted content' '
+ (
+ cd 13b &&
+
+ git checkout A^0 &&
+
+ test_must_fail git merge -s recursive B^0 >out 2>err &&
+
+ test_i18ngrep CONFLICT.*content.*Merge.conflict.in.y/d out &&
+ test_i18ngrep CONFLICT..file.location.*x/d.renamed.to.z/d.*moved.to.y/d out &&
+
+ git ls-files >paths &&
+ ! grep z/ paths &&
+ grep "y/d" paths &&
+
+ test_path_is_missing z/d &&
+ test_path_is_file y/d
+ )
+'
+
+test_expect_success '13b-check(info): messages for transitive rename with conflicted content' '
+ (
+ cd 13b &&
+
+ git reset --hard &&
+ git checkout A^0 &&
+
+ test_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
+
+ test_i18ngrep CONFLICT.*content.*Merge.conflict.in.y/d out &&
+ test_i18ngrep Path.updated:.*x/d.renamed.to.z/d.in.B^0.*moving.it.to.y/d out &&
+
+ git ls-files >paths &&
+ ! grep z/ paths &&
+ grep "y/d" paths &&
+
+ test_path_is_missing z/d &&
+ test_path_is_file y/d
+ )
+'
+
+# Testcase 13c, Rename/rename(1to1) due to directory rename
+# Commit O: z/{b,c}, x/{d,e}
+# Commit A: y/{b,c,d}, x/e
+# Commit B: z/{b,c,d}, x/e
+# Expected: y/{b,c,d}, with info or conflict messages for d (
+# A: renamed x/d -> z/d; B: renamed z/ -> y/ AND renamed x/d to y/d
+# One could argue A had partial knowledge of what was done with
+# d and B had full knowledge, but that's a slippery slope as
+# shown in testcase 13d.
+
+test_expect_success '13c-setup: messages for rename/rename(1to1) via transitive rename' '
+ test_create_repo 13c &&
+ (
+ cd 13c &&
+
+ mkdir x &&
+ mkdir z &&
+ test_seq 1 10 >x/d &&
+ echo e >x/e &&
+ echo b >z/b &&
+ echo c >z/c &&
+ git add x z &&
+ test_tick &&
+ git commit -m "O" &&
+
+ git branch O &&
+ git branch A &&
+ git branch B &&
+
+ git checkout A &&
+ git mv z y &&
+ git mv x/d y/ &&
+ test_tick &&
+ git commit -m "A" &&
+
+ git checkout B &&
+ git mv x/d z/d &&
+ git add z/d &&
+ test_tick &&
+ git commit -m "B"
+ )
+'
+
+test_expect_success '13c-check(conflict): messages for rename/rename(1to1) via transitive rename' '
+ (
+ cd 13c &&
+
+ git checkout A^0 &&
+
+ test_must_fail git merge -s recursive B^0 >out 2>err &&
+
+ test_i18ngrep CONFLICT..file.location.*x/d.renamed.to.z/d.*moved.to.y/d out &&
+
+ git ls-files >paths &&
+ ! grep z/ paths &&
+ grep "y/d" paths &&
+
+ test_path_is_missing z/d &&
+ test_path_is_file y/d
+ )
+'
+
+test_expect_success '13c-check(info): messages for rename/rename(1to1) via transitive rename' '
+ (
+ cd 13c &&
+
+ git reset --hard &&
+ git checkout A^0 &&
+
+ git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
+
+ test_i18ngrep Path.updated:.*x/d.renamed.to.z/d.in.B^0.*moving.it.to.y/d out &&
+
+ git ls-files >paths &&
+ ! grep z/ paths &&
+ grep "y/d" paths &&
+
+ test_path_is_missing z/d &&
+ test_path_is_file y/d
+ )
+'
+
+# Testcase 13d, Rename/rename(1to1) due to directory rename on both sides
+# Commit O: a/{z,y}, b/x, c/w
+# Commit A: a/z, b/{y,x}, d/w
+# Commit B: a/z, d/x, c/{y,w}
+# Expected: a/z, d/{y,x,w} with no file location conflict for x
+# Easy cases:
+# * z is always in a; so it stays in a.
+# * x starts in b, only modified on one side to move into d/
+# * w starts in c, only modified on one side to move into d/
+# Hard case:
+# * A renames a/y to b/y, and B renames b/->d/ => a/y -> d/y
+# * B renames a/y to c/y, and A renames c/->d/ => a/y -> d/y
+# No conflict in where a/y ends up, so put it in d/y.
+
+test_expect_success '13d-setup: messages for rename/rename(1to1) via dual transitive rename' '
+ test_create_repo 13d &&
+ (
+ cd 13d &&
+
+ mkdir a &&
+ mkdir b &&
+ mkdir c &&
+ echo z >a/z &&
+ echo y >a/y &&
+ echo x >b/x &&
+ echo w >c/w &&
+ git add a b c &&
+ test_tick &&
+ git commit -m "O" &&
+
+ git branch O &&
+ git branch A &&
+ git branch B &&
+
+ git checkout A &&
+ git mv a/y b/ &&
+ git mv c/ d/ &&
+ test_tick &&
+ git commit -m "A" &&
+
+ git checkout B &&
+ git mv a/y c/ &&
+ git mv b/ d/ &&
+ test_tick &&
+ git commit -m "B"
+ )
+'
+
+test_expect_success '13d-check(conflict): messages for rename/rename(1to1) via dual transitive rename' '
+ (
+ cd 13d &&
+
+ git checkout A^0 &&
+
+ test_must_fail git merge -s recursive B^0 >out 2>err &&
+
+ test_i18ngrep CONFLICT..file.location.*a/y.renamed.to.b/y.*moved.to.d/y out &&
+ test_i18ngrep CONFLICT..file.location.*a/y.renamed.to.c/y.*moved.to.d/y out &&
+
+ git ls-files >paths &&
+ ! grep b/ paths &&
+ ! grep c/ paths &&
+ grep "d/y" paths &&
+
+ test_path_is_missing b/y &&
+ test_path_is_missing c/y &&
+ test_path_is_file d/y
+ )
+'
+
+test_expect_success '13d-check(info): messages for rename/rename(1to1) via dual transitive rename' '
+ (
+ cd 13d &&
+
+ git reset --hard &&
+ git checkout A^0 &&
+
+ git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&
+
+ test_i18ngrep Path.updated.*a/y.renamed.to.b/y.*moving.it.to.d/y out &&
+ test_i18ngrep Path.updated.*a/y.renamed.to.c/y.*moving.it.to.d/y out &&
+
+ git ls-files >paths &&
+ ! grep b/ paths &&
+ ! grep c/ paths &&
+ grep "d/y" paths &&
+
+ test_path_is_missing b/y &&
+ test_path_is_missing c/y &&
+ test_path_is_file d/y
+ )
+'
+
test_done