t6043-merge-rename-directories.sh [plain text]
#!/bin/sh
test_description="recursive merge with directory renames"
. ./test-lib.sh
test_expect_success '1a-setup: Simple directory rename detection' '
test_create_repo 1a &&
(
cd 1a &&
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 '1a-check: Simple directory rename detection' '
(
cd 1a &&
git checkout A^0 &&
git merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 4 out &&
git rev-parse >actual \
HEAD:y/b HEAD:y/c HEAD:y/d HEAD:y/e/f &&
git rev-parse >expect \
O:z/b O:z/c B:z/d B:z/e/f &&
test_cmp expect actual &&
git hash-object y/d >actual &&
git rev-parse B:z/d >expect &&
test_cmp expect actual &&
test_must_fail git rev-parse HEAD:z/d &&
test_must_fail git rev-parse HEAD:z/e/f &&
test_path_is_missing z/d &&
test_path_is_missing z/e/f
)
'
test_expect_success '1b-setup: Merge a directory with another' '
test_create_repo 1b &&
(
cd 1b &&
mkdir z &&
echo b >z/b &&
echo c >z/c &&
mkdir y &&
echo d >y/d &&
git add z y &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
echo e >z/e &&
git add z/e &&
test_tick &&
git commit -m "A" &&
git checkout B &&
git mv z/b y &&
git mv z/c y &&
rmdir z &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '1b-check: Merge a directory with another' '
(
cd 1b &&
git checkout A^0 &&
git merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 4 out &&
git rev-parse >actual \
HEAD:y/b HEAD:y/c HEAD:y/d HEAD:y/e &&
git rev-parse >expect \
O:z/b O:z/c O:y/d A:z/e &&
test_cmp expect actual &&
test_must_fail git rev-parse HEAD:z/e
)
'
test_expect_success '1c-setup: Transitive renaming' '
test_create_repo 1c &&
(
cd 1c &&
mkdir z &&
echo b >z/b &&
echo c >z/c &&
mkdir x &&
echo d >x/d &&
git add z x &&
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 &&
git mv x/d z/d &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '1c-check: Transitive renaming' '
(
cd 1c &&
git checkout A^0 &&
git merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 3 out &&
git rev-parse >actual \
HEAD:y/b HEAD:y/c HEAD:y/d &&
git rev-parse >expect \
O:z/b O:z/c O:x/d &&
test_cmp expect actual &&
test_must_fail git rev-parse HEAD:x/d &&
test_must_fail git rev-parse HEAD:z/d &&
test_path_is_missing z/d
)
'
test_expect_success '1d-setup: Directory renames cause a rename/rename(2to1) conflict' '
test_create_repo 1d &&
(
cd 1d &&
mkdir z &&
echo b >z/b &&
echo c >z/c &&
mkdir y &&
echo d >y/d &&
echo e >y/e &&
git add z y &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
git mv z x &&
echo m >y/m &&
echo wham1 >y/wham &&
git add y &&
test_tick &&
git commit -m "A" &&
git checkout B &&
git mv y x &&
echo n >z/n &&
echo wham2 >z/wham &&
git add z &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '1d-check: Directory renames cause a rename/rename(2to1) conflict' '
(
cd 1d &&
git checkout A^0 &&
test_must_fail git merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (rename/rename)" out &&
git ls-files -s >out &&
test_line_count = 8 out &&
git ls-files -u >out &&
test_line_count = 2 out &&
git ls-files -o >out &&
test_line_count = 3 out &&
git rev-parse >actual \
:0:x/b :0:x/c :0:x/d :0:x/e :0:x/m :0:x/n &&
git rev-parse >expect \
O:z/b O:z/c O:y/d O:y/e A:y/m B:z/n &&
test_cmp expect actual &&
test_must_fail git rev-parse :0:x/wham &&
git rev-parse >actual \
:2:x/wham :3:x/wham &&
git rev-parse >expect \
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_expect_success '1e-setup: Renamed directory, with all files being renamed too' '
test_create_repo 1e &&
(
cd 1e &&
mkdir z &&
echo b >z/oldb &&
echo c >z/oldc &&
git add z &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
mkdir y &&
git mv z/oldb y/newb &&
git mv z/oldc y/newc &&
test_tick &&
git commit -m "A" &&
git checkout B &&
echo d >z/d &&
git add z/d &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '1e-check: Renamed directory, with all files being renamed too' '
(
cd 1e &&
git checkout A^0 &&
git merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 3 out &&
git rev-parse >actual \
HEAD:y/newb HEAD:y/newc HEAD:y/d &&
git rev-parse >expect \
O:z/oldb O:z/oldc B:z/d &&
test_cmp expect actual &&
test_must_fail git rev-parse HEAD:z/d
)
'
test_expect_success '1f-setup: Split a directory into two other directories' '
test_create_repo 1f &&
(
cd 1f &&
mkdir z &&
echo b >z/b &&
echo c >z/c &&
echo d >z/d &&
echo e >z/e &&
echo f >z/f &&
git add z &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
echo g >z/g &&
git add z/g &&
test_tick &&
git commit -m "A" &&
git checkout B &&
mkdir y &&
mkdir x &&
git mv z/b y/ &&
git mv z/c y/ &&
git mv z/d x/ &&
git mv z/e x/ &&
git mv z/f x/ &&
rmdir z &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '1f-check: Split a directory into two other directories' '
(
cd 1f &&
git checkout A^0 &&
git merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 6 out &&
git rev-parse >actual \
HEAD:y/b HEAD:y/c HEAD:x/d HEAD:x/e HEAD:x/f HEAD:x/g &&
git rev-parse >expect \
O:z/b O:z/c O:z/d O:z/e O:z/f A:z/g &&
test_cmp expect actual &&
test_path_is_missing z/g &&
test_must_fail git rev-parse HEAD:z/g
)
'
test_expect_success '2a-setup: Directory split into two on one side, with equal numbers of paths' '
test_create_repo 2a &&
(
cd 2a &&
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 &&
mkdir y &&
mkdir w &&
git mv z/b y/ &&
git mv z/c w/ &&
test_tick &&
git commit -m "A" &&
git checkout B &&
echo d >z/d &&
git add z/d &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '2a-check: Directory split into two on one side, with equal numbers of paths' '
(
cd 2a &&
git checkout A^0 &&
test_must_fail git merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT.*directory rename split" out &&
git ls-files -s >out &&
test_line_count = 3 out &&
git ls-files -u >out &&
test_line_count = 0 out &&
git ls-files -o >out &&
test_line_count = 1 out &&
git rev-parse >actual \
:0:y/b :0:w/c :0:z/d &&
git rev-parse >expect \
O:z/b O:z/c B:z/d &&
test_cmp expect actual
)
'
test_expect_success '2b-setup: Directory split into two on one side, with equal numbers of paths' '
test_create_repo 2b &&
(
cd 2b &&
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 &&
mkdir y &&
mkdir w &&
git mv z/b y/ &&
git mv z/c w/ &&
test_tick &&
git commit -m "A" &&
git checkout B &&
mkdir x &&
echo d >x/d &&
git add x/d &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '2b-check: Directory split into two on one side, with equal numbers of paths' '
(
cd 2b &&
git checkout A^0 &&
git merge -s recursive B^0 >out &&
git ls-files -s >out &&
test_line_count = 3 out &&
git ls-files -u >out &&
test_line_count = 0 out &&
git ls-files -o >out &&
test_line_count = 1 out &&
git rev-parse >actual \
:0:y/b :0:w/c :0:x/d &&
git rev-parse >expect \
O:z/b O:z/c B:x/d &&
test_cmp expect actual &&
test_i18ngrep ! "CONFLICT.*directory rename split" out
)
'
test_expect_success '3a-setup: Avoid implicit rename if involved as source on other side' '
test_create_repo 3a &&
(
cd 3a &&
mkdir z &&
echo b >z/b &&
echo c >z/c &&
echo d >z/d &&
git add z &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
test_tick &&
git commit --allow-empty -m "A" &&
git checkout B &&
mkdir y &&
mkdir x &&
git mv z/b y/ &&
git mv z/c y/ &&
git mv z/d x/ &&
rmdir z &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '3a-check: Avoid implicit rename if involved as source on other side' '
(
cd 3a &&
git checkout A^0 &&
git merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 3 out &&
git rev-parse >actual \
HEAD:y/b HEAD:y/c HEAD:x/d &&
git rev-parse >expect \
O:z/b O:z/c O:z/d &&
test_cmp expect actual
)
'
test_expect_success '3b-setup: Avoid implicit rename if involved as source on current side' '
test_create_repo 3b &&
(
cd 3b &&
mkdir z &&
echo b >z/b &&
echo c >z/c &&
echo d >z/d &&
git add z &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
mkdir y &&
mkdir x &&
git mv z/b y/ &&
git mv z/c y/ &&
git mv z/d x/ &&
rmdir z &&
test_tick &&
git commit -m "A" &&
git checkout B &&
mkdir w &&
git mv z/d w/ &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '3b-check: Avoid implicit rename if involved as source on current side' '
(
cd 3b &&
git checkout A^0 &&
test_must_fail git 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 ls-files -s >out &&
test_line_count = 5 out &&
git ls-files -u >out &&
test_line_count = 3 out &&
git ls-files -o >out &&
test_line_count = 1 out &&
git rev-parse >actual \
:0:y/b :0:y/c :1:z/d :2:x/d :3:w/d &&
git rev-parse >expect \
O:z/b O:z/c O:z/d O:z/d O:z/d &&
test_cmp expect actual &&
test_path_is_missing z/d &&
git hash-object >actual \
x/d w/d &&
git rev-parse >expect \
O:z/d O:z/d &&
test_cmp expect actual
)
'
test_expect_success '4a-setup: Directory split, with original directory still present' '
test_create_repo 4a &&
(
cd 4a &&
mkdir z &&
echo b >z/b &&
echo c >z/c &&
echo d >z/d &&
echo e >z/e &&
git add z &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
mkdir y &&
git mv z/b y/ &&
git mv z/c y/ &&
git mv z/d y/ &&
test_tick &&
git commit -m "A" &&
git checkout B &&
echo f >z/f &&
git add z/f &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '4a-check: Directory split, with original directory still present' '
(
cd 4a &&
git checkout A^0 &&
git merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 5 out &&
git ls-files -u >out &&
test_line_count = 0 out &&
git ls-files -o >out &&
test_line_count = 1 out &&
git rev-parse >actual \
HEAD:y/b HEAD:y/c HEAD:y/d HEAD:z/e HEAD:z/f &&
git rev-parse >expect \
O:z/b O:z/c O:z/d O:z/e B:z/f &&
test_cmp expect actual
)
'
test_expect_success '5a-setup: Merge directories, other side adds files to original and target' '
test_create_repo 5a &&
(
cd 5a &&
mkdir z &&
echo b >z/b &&
echo c >z/c &&
mkdir y &&
echo d >y/d &&
git add z y &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
echo e1 >z/e &&
echo f >z/f &&
echo e2 >y/e &&
git add z/e z/f y/e &&
test_tick &&
git commit -m "A" &&
git checkout B &&
git mv z/b y/ &&
git mv z/c y/ &&
rmdir z &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '5a-check: Merge directories, other side adds files to original and target' '
(
cd 5a &&
git checkout A^0 &&
test_must_fail git merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT.*implicit dir rename" out &&
git ls-files -s >out &&
test_line_count = 6 out &&
git ls-files -u >out &&
test_line_count = 0 out &&
git ls-files -o >out &&
test_line_count = 1 out &&
git rev-parse >actual \
:0:y/b :0:y/c :0:y/d :0:y/e :0:z/e :0:y/f &&
git rev-parse >expect \
O:z/b O:z/c O:y/d A:y/e A:z/e A:z/f &&
test_cmp expect actual
)
'
test_expect_success '5b-setup: Rename/delete in order to get add/add/add conflict' '
test_create_repo 5b &&
(
cd 5b &&
mkdir z &&
echo b >z/b &&
echo c >z/c &&
echo d1 >z/d &&
git add z &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
git rm z/d &&
git mv z y &&
echo d2 >y/d &&
git add y/d &&
test_tick &&
git commit -m "A" &&
git checkout B &&
mkdir y &&
echo d3 >y/d &&
echo e >z/e &&
git add y/d z/e &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '5b-check: Rename/delete in order to get add/add/add conflict' '
(
cd 5b &&
git checkout A^0 &&
test_must_fail git merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (add/add).* y/d" out &&
git ls-files -s >out &&
test_line_count = 5 out &&
git ls-files -u >out &&
test_line_count = 2 out &&
git ls-files -o >out &&
test_line_count = 1 out &&
git rev-parse >actual \
:0:y/b :0:y/c :0:y/e :2:y/d :3:y/d &&
git rev-parse >expect \
O:z/b O:z/c B:z/e A:y/d B:y/d &&
test_cmp expect actual &&
test_must_fail git rev-parse :1:y/d &&
test_path_is_file y/d
)
'
test_expect_success '5c-setup: Transitive rename would cause rename/rename/rename/add/add/add' '
test_create_repo 5c &&
(
cd 5c &&
mkdir z &&
echo b >z/b &&
echo c >z/c &&
mkdir x &&
echo d1 >x/d &&
git add z x &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
git mv z y &&
echo d2 >y/d &&
git add y/d &&
git mv x w &&
test_tick &&
git commit -m "A" &&
git checkout B &&
git mv x/d z/ &&
mkdir w &&
mkdir y &&
echo d3 >w/d &&
echo d4 >y/d &&
echo e >z/e &&
git add w/ y/ z/e &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '5c-check: Transitive rename would cause rename/rename/rename/add/add/add' '
(
cd 5c &&
git checkout A^0 &&
test_must_fail git 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 -s >out &&
test_line_count = 9 out &&
git ls-files -u >out &&
test_line_count = 6 out &&
git ls-files -o >out &&
test_line_count = 3 out &&
git rev-parse >actual \
:0:y/b :0:y/c :0:y/e &&
git rev-parse >expect \
O:z/b O:z/c B:z/e &&
test_cmp expect actual &&
test_must_fail git rev-parse :1:y/d &&
git rev-parse >actual \
:2:w/d :3:w/d :1:x/d :2:y/d :3:y/d :3:z/d &&
git rev-parse >expect \
O:x/d B:w/d O:x/d A:y/d B:y/d O:x/d &&
test_cmp expect actual &&
git hash-object >actual \
w/d~HEAD w/d~B^0 z/d &&
git rev-parse >expect \
O:x/d B:w/d O:x/d &&
test_cmp expect actual &&
test_path_is_missing x/d &&
test_path_is_file y/d &&
grep -q "<<<<" y/d )
'
test_expect_success '5d-setup: Directory/file/file conflict due to directory rename' '
test_create_repo 5d &&
(
cd 5d &&
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 &&
echo d1 >y/d &&
git add y/d &&
test_tick &&
git commit -m "A" &&
git checkout B &&
mkdir -p y/d &&
echo e >y/d/e &&
echo d2 >z/d &&
echo f >z/f &&
git add y/d/e z/d z/f &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '5d-check: Directory/file/file conflict due to directory rename' '
(
cd 5d &&
git checkout A^0 &&
test_must_fail git merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (file/directory).*y/d" out &&
git ls-files -s >out &&
test_line_count = 6 out &&
git ls-files -u >out &&
test_line_count = 1 out &&
git ls-files -o >out &&
test_line_count = 2 out &&
git rev-parse >actual \
:0:y/b :0:y/c :0:z/d :0:y/f :2:y/d :0:y/d/e &&
git rev-parse >expect \
O:z/b O:z/c B:z/d B:z/f A:y/d B:y/d/e &&
test_cmp expect actual &&
git hash-object y/d~HEAD >actual &&
git rev-parse A:y/d >expect &&
test_cmp expect actual
)
'
test_expect_success '6a-setup: Tricky rename/delete' '
test_create_repo 6a &&
(
cd 6a &&
mkdir z &&
echo b >z/b &&
echo c >z/c &&
echo d >z/d &&
git add z &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
git rm z/c &&
git rm z/d &&
test_tick &&
git commit -m "A" &&
git checkout B &&
mkdir y &&
git mv z/b y/ &&
git mv z/c y/ &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '6a-check: Tricky rename/delete' '
(
cd 6a &&
git checkout A^0 &&
test_must_fail git merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (rename/delete).*z/c.*y/c" out &&
git ls-files -s >out &&
test_line_count = 2 out &&
git ls-files -u >out &&
test_line_count = 1 out &&
git ls-files -o >out &&
test_line_count = 1 out &&
git rev-parse >actual \
:0:y/b :3:y/c &&
git rev-parse >expect \
O:z/b O:z/c &&
test_cmp expect actual
)
'
test_expect_success '6b-setup: Same rename done on both sides' '
test_create_repo 6b &&
(
cd 6b &&
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 &&
git mv z y &&
mkdir z &&
echo d >z/d &&
git add z/d &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '6b-check: Same rename done on both sides' '
(
cd 6b &&
git checkout A^0 &&
git merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 3 out &&
git ls-files -u >out &&
test_line_count = 0 out &&
git ls-files -o >out &&
test_line_count = 1 out &&
git rev-parse >actual \
HEAD:y/b HEAD:y/c HEAD:z/d &&
git rev-parse >expect \
O:z/b O:z/c B:z/d &&
test_cmp expect actual
)
'
test_expect_success '6c-setup: Rename only done on same side' '
test_create_repo 6c &&
(
cd 6c &&
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 &&
test_tick &&
git commit --allow-empty -m "A" &&
git checkout B &&
git mv z y &&
mkdir z &&
echo d >z/d &&
git add z/d &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '6c-check: Rename only done on same side' '
(
cd 6c &&
git checkout A^0 &&
git merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 3 out &&
git ls-files -u >out &&
test_line_count = 0 out &&
git ls-files -o >out &&
test_line_count = 1 out &&
git rev-parse >actual \
HEAD:y/b HEAD:y/c HEAD:z/d &&
git rev-parse >expect \
O:z/b O:z/c B:z/d &&
test_cmp expect actual
)
'
test_expect_success '6d-setup: We do not always want transitive renaming' '
test_create_repo 6d &&
(
cd 6d &&
mkdir z &&
echo b >z/b &&
echo c >z/c &&
mkdir x &&
echo d >x/d &&
git add z x &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
test_tick &&
git commit --allow-empty -m "A" &&
git checkout B &&
git mv z y &&
git mv x z &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '6d-check: We do not always want transitive renaming' '
(
cd 6d &&
git checkout A^0 &&
git merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 3 out &&
git ls-files -u >out &&
test_line_count = 0 out &&
git ls-files -o >out &&
test_line_count = 1 out &&
git rev-parse >actual \
HEAD:y/b HEAD:y/c HEAD:z/d &&
git rev-parse >expect \
O:z/b O:z/c O:x/d &&
test_cmp expect actual
)
'
test_expect_success '6e-setup: Add/add from one side' '
test_create_repo 6e &&
(
cd 6e &&
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 &&
test_tick &&
git commit --allow-empty -m "A" &&
git checkout B &&
git mv z y &&
echo d1 > y/d &&
mkdir z &&
echo d2 > z/d &&
git add y/d z/d &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '6e-check: Add/add from one side' '
(
cd 6e &&
git checkout A^0 &&
git merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 4 out &&
git ls-files -u >out &&
test_line_count = 0 out &&
git ls-files -o >out &&
test_line_count = 1 out &&
git rev-parse >actual \
HEAD:y/b HEAD:y/c HEAD:y/d HEAD:z/d &&
git rev-parse >expect \
O:z/b O:z/c B:y/d B:z/d &&
test_cmp expect actual
)
'
test_expect_success '7a-setup: rename-dir vs. rename-dir (NOT split evenly) PLUS add-other-file' '
test_create_repo 7a &&
(
cd 7a &&
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 &&
mkdir w &&
mkdir x &&
git mv z/b w/ &&
git mv z/c x/ &&
echo d > z/d &&
git add z/d &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '7a-check: rename-dir vs. rename-dir (NOT split evenly) PLUS add-other-file' '
(
cd 7a &&
git checkout A^0 &&
test_must_fail git 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 ls-files -s >out &&
test_line_count = 7 out &&
git ls-files -u >out &&
test_line_count = 6 out &&
git ls-files -o >out &&
test_line_count = 1 out &&
git rev-parse >actual \
:1:z/b :2:y/b :3:w/b :1:z/c :2:y/c :3:x/c :0:y/d &&
git rev-parse >expect \
O:z/b O:z/b O:z/b O:z/c O:z/c O:z/c B:z/d &&
test_cmp expect actual &&
git hash-object >actual \
y/b w/b y/c x/c &&
git rev-parse >expect \
O:z/b O:z/b O:z/c O:z/c &&
test_cmp expect actual
)
'
test_expect_success '7b-setup: rename/rename(2to1), but only due to transitive rename' '
test_create_repo 7b &&
(
cd 7b &&
mkdir z &&
mkdir x &&
mkdir w &&
echo b >z/b &&
echo c >z/c &&
echo d1 > x/d &&
echo d2 > w/d &&
git add z x w &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
git mv z y &&
git mv w/d y/ &&
test_tick &&
git commit -m "A" &&
git checkout B &&
git mv x/d z/ &&
rmdir x &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '7b-check: rename/rename(2to1), but only due to transitive rename' '
(
cd 7b &&
git checkout A^0 &&
test_must_fail git merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (rename/rename)" out &&
git ls-files -s >out &&
test_line_count = 4 out &&
git ls-files -u >out &&
test_line_count = 2 out &&
git ls-files -o >out &&
test_line_count = 3 out &&
git rev-parse >actual \
:0:y/b :0:y/c :2:y/d :3:y/d &&
git rev-parse >expect \
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_expect_success '7c-setup: rename/rename(1to...2or3); transitive rename may add complexity' '
test_create_repo 7c &&
(
cd 7c &&
mkdir z &&
echo b >z/b &&
echo c >z/c &&
mkdir x &&
echo d >x/d &&
git add z x &&
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 w &&
test_tick &&
git commit -m "A" &&
git checkout B &&
git mv x/d z/ &&
rmdir x &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '7c-check: rename/rename(1to...2or3); transitive rename may add complexity' '
(
cd 7c &&
git checkout A^0 &&
test_must_fail git merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (rename/rename).*x/d.*w/d.*y/d" out &&
git ls-files -s >out &&
test_line_count = 5 out &&
git ls-files -u >out &&
test_line_count = 3 out &&
git ls-files -o >out &&
test_line_count = 1 out &&
git rev-parse >actual \
:0:y/b :0:y/c :1:x/d :2:w/d :3:y/d &&
git rev-parse >expect \
O:z/b O:z/c O:x/d O:x/d O:x/d &&
test_cmp expect actual
)
'
test_expect_success '7d-setup: transitive rename involved in rename/delete; how is it reported?' '
test_create_repo 7d &&
(
cd 7d &&
mkdir z &&
echo b >z/b &&
echo c >z/c &&
mkdir x &&
echo d >x/d &&
git add z x &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
git mv z y &&
git rm -rf x &&
test_tick &&
git commit -m "A" &&
git checkout B &&
git mv x/d z/ &&
rmdir x &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '7d-check: transitive rename involved in rename/delete; how is it reported?' '
(
cd 7d &&
git checkout A^0 &&
test_must_fail git merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (rename/delete).*x/d.*y/d" out &&
git ls-files -s >out &&
test_line_count = 3 out &&
git ls-files -u >out &&
test_line_count = 1 out &&
git ls-files -o >out &&
test_line_count = 1 out &&
git rev-parse >actual \
:0:y/b :0:y/c :3:y/d &&
git rev-parse >expect \
O:z/b O:z/c O:x/d &&
test_cmp expect actual
)
'
test_expect_success '7e-setup: transitive rename in rename/delete AND dirs in the way' '
test_create_repo 7e &&
(
cd 7e &&
mkdir z &&
echo b >z/b &&
echo c >z/c &&
mkdir x &&
echo d1 >x/d &&
git add z x &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
git mv z y &&
git rm x/d &&
mkdir -p x/d &&
mkdir -p y/d &&
echo f >x/d/f &&
echo g >y/d/g &&
git add x/d/f y/d/g &&
test_tick &&
git commit -m "A" &&
git checkout B &&
git mv x/d z/ &&
rmdir x &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '7e-check: transitive rename in rename/delete AND dirs in the way' '
(
cd 7e &&
git checkout A^0 &&
test_must_fail git merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (rename/delete).*x/d.*y/d" out &&
git ls-files -s >out &&
test_line_count = 5 out &&
git ls-files -u >out &&
test_line_count = 1 out &&
git ls-files -o >out &&
test_line_count = 2 out &&
git rev-parse >actual \
:0:x/d/f :0:y/d/g :0:y/b :0:y/c :3:y/d &&
git rev-parse >expect \
A:x/d/f A:y/d/g O:z/b O:z/c O:x/d &&
test_cmp expect actual &&
git hash-object y/d~B^0 >actual &&
git rev-parse O:x/d >expect &&
test_cmp expect actual
)
'
test_expect_success '8a-setup: Dual-directory rename, one into the others way' '
test_create_repo 8a &&
(
cd 8a &&
mkdir x &&
mkdir y &&
echo a >x/a &&
echo b >x/b &&
echo c >y/c &&
echo d >y/d &&
git add x y &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
echo e >x/e &&
echo f >y/f &&
git add x/e y/f &&
test_tick &&
git commit -m "A" &&
git checkout B &&
git mv y z &&
git mv x y &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '8a-check: Dual-directory rename, one into the others way' '
(
cd 8a &&
git checkout A^0 &&
git merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 6 out &&
git ls-files -u >out &&
test_line_count = 0 out &&
git ls-files -o >out &&
test_line_count = 1 out &&
git rev-parse >actual \
HEAD:y/a HEAD:y/b HEAD:y/e HEAD:y/f HEAD:z/c HEAD:z/d &&
git rev-parse >expect \
O:x/a O:x/b A:x/e A:y/f O:y/c O:y/d &&
test_cmp expect actual
)
'
test_expect_success '8b-setup: Dual-directory rename, one into the others way, with conflicting filenames' '
test_create_repo 8b &&
(
cd 8b &&
mkdir x &&
mkdir y &&
echo a1 >x/a &&
echo b1 >x/b &&
echo a2 >y/a &&
echo b2 >y/b &&
git add x y &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
echo e1 >x/e &&
echo e2 >y/e &&
git add x/e y/e &&
test_tick &&
git commit -m "A" &&
git checkout B &&
git mv y z &&
git mv x y &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '8b-check: Dual-directory rename, one into the others way, with conflicting filenames' '
(
cd 8b &&
git checkout A^0 &&
git merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 6 out &&
git ls-files -u >out &&
test_line_count = 0 out &&
git ls-files -o >out &&
test_line_count = 1 out &&
git rev-parse >actual \
HEAD:y/a HEAD:y/b HEAD:z/a HEAD:z/b HEAD:x/e HEAD:y/e &&
git rev-parse >expect \
O:x/a O:x/b O:y/a O:y/b A:x/e A:y/e &&
test_cmp expect actual
)
'
test_expect_success '8c-setup: modify/delete or rename+modify/delete?' '
test_create_repo 8c &&
(
cd 8c &&
mkdir z &&
echo b >z/b &&
echo c >z/c &&
test_seq 1 10 >z/d &&
git add z &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
git rm z/d &&
git mv z y &&
test_tick &&
git commit -m "A" &&
git checkout B &&
echo 11 >z/d &&
test_chmod +x z/d &&
echo e >z/e &&
git add z/d z/e &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '8c-check: modify/delete or rename+modify/delete' '
(
cd 8c &&
git checkout A^0 &&
test_must_fail git merge -s recursive B^0 >out &&
test_i18ngrep "CONFLICT (modify/delete).* z/d" out &&
git ls-files -s >out &&
test_line_count = 5 out &&
git ls-files -u >out &&
test_line_count = 2 out &&
git ls-files -o >out &&
test_line_count = 1 out &&
git rev-parse >actual \
:0:y/b :0:y/c :0:y/e :1:z/d :3:z/d &&
git rev-parse >expect \
O:z/b O:z/c B:z/e O:z/d B:z/d &&
test_cmp expect actual &&
test_must_fail git rev-parse :2:z/d &&
git ls-files -s z/d | grep ^100755 &&
test_path_is_file z/d &&
test_path_is_missing y/d
)
'
test_expect_success '8d-setup: rename/delete...or not?' '
test_create_repo 8d &&
(
cd 8d &&
mkdir z &&
echo b >z/b &&
echo c >z/c &&
test_seq 1 10 >z/d &&
git add z &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
git rm z/d &&
git mv z y &&
test_tick &&
git commit -m "A" &&
git checkout B &&
echo e >z/e &&
git add z/e &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '8d-check: rename/delete...or not?' '
(
cd 8d &&
git checkout A^0 &&
git merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 3 out &&
git rev-parse >actual \
HEAD:y/b HEAD:y/c HEAD:y/e &&
git rev-parse >expect \
O:z/b O:z/c B:z/e &&
test_cmp expect actual
)
'
test_expect_success '8e-setup: Both sides rename, one side adds to original directory' '
test_create_repo 8e &&
(
cd 8e &&
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 &&
git mv z w &&
mkdir z &&
echo d >z/d &&
git add z/d &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '8e-check: Both sides rename, one side adds to original directory' '
(
cd 8e &&
git checkout A^0 &&
test_must_fail git 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 ls-files -s >out &&
test_line_count = 7 out &&
git ls-files -u >out &&
test_line_count = 6 out &&
git ls-files -o >out &&
test_line_count = 2 out &&
git rev-parse >actual \
:1:z/b :2:y/b :3:w/b :1:z/c :2:y/c :3:w/c :0:y/d &&
git rev-parse >expect \
O:z/b O:z/b O:z/b O:z/c O:z/c O:z/c B:z/d &&
test_cmp expect actual &&
git hash-object >actual \
y/b w/b y/c w/c &&
git rev-parse >expect \
O:z/b O:z/b O:z/c O:z/c &&
test_cmp expect actual &&
test_path_is_missing z/b &&
test_path_is_missing z/c
)
'
test_expect_success '9a-setup: Inner renamed directory within outer renamed directory' '
test_create_repo 9a &&
(
cd 9a &&
mkdir -p z/d &&
echo b >z/b &&
echo c >z/c &&
echo e >z/d/e &&
echo f >z/d/f &&
echo g >z/d/g &&
git add z &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
mkdir x &&
git mv z/d x/w &&
git mv z y &&
test_tick &&
git commit -m "A" &&
git checkout B &&
echo h >z/d/h &&
echo i >z/i &&
git add z &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '9a-check: Inner renamed directory within outer renamed directory' '
(
cd 9a &&
git checkout A^0 &&
git merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 7 out &&
git ls-files -u >out &&
test_line_count = 0 out &&
git ls-files -o >out &&
test_line_count = 1 out &&
git rev-parse >actual \
HEAD:y/b HEAD:y/c HEAD:y/i &&
git rev-parse >expect \
O:z/b O:z/c B:z/i &&
test_cmp expect actual &&
git rev-parse >actual \
HEAD:x/w/e HEAD:x/w/f HEAD:x/w/g HEAD:x/w/h &&
git rev-parse >expect \
O:z/d/e O:z/d/f O:z/d/g B:z/d/h &&
test_cmp expect actual
)
'
test_expect_success '9b-setup: Transitive rename with content merge' '
test_create_repo 9b &&
(
cd 9b &&
mkdir z &&
echo b >z/b &&
echo c >z/c &&
mkdir x &&
test_seq 1 10 >x/d &&
git add z x &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
git mv z y &&
test_seq 1 11 >x/d &&
git add x/d &&
test_tick &&
git commit -m "A" &&
git checkout B &&
test_seq 0 10 >x/d &&
git mv x/d z/d &&
git add z/d &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '9b-check: Transitive rename with content merge' '
(
cd 9b &&
git checkout A^0 &&
git merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 3 out &&
test_seq 0 11 >expected &&
test_cmp expected y/d &&
git add expected &&
git rev-parse >actual \
HEAD:y/b HEAD:y/c HEAD:y/d &&
git rev-parse >expect \
O:z/b O:z/c :0:expected &&
test_cmp expect actual &&
test_must_fail git rev-parse HEAD:x/d &&
test_must_fail git rev-parse HEAD:z/d &&
test_path_is_missing z/d &&
test $(git rev-parse HEAD:y/d) != $(git rev-parse O:x/d) &&
test $(git rev-parse HEAD:y/d) != $(git rev-parse A:x/d) &&
test $(git rev-parse HEAD:y/d) != $(git rev-parse B:z/d)
)
'
test_expect_success '9c-setup: Doubly transitive rename?' '
test_create_repo 9c &&
(
cd 9c &&
mkdir z &&
echo b >z/b &&
echo c >z/c &&
mkdir x &&
echo d >x/d &&
echo e >x/e &&
mkdir w &&
echo f >w/f &&
git add z x w &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
git mv z y &&
git mv w/f x/ &&
echo g >x/g &&
git add x/g &&
test_tick &&
git commit -m "A" &&
git checkout B &&
git mv x/d z/d &&
git mv x/e z/e &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '9c-check: Doubly transitive rename?' '
(
cd 9c &&
git checkout A^0 &&
git merge -s recursive B^0 >out &&
test_i18ngrep "WARNING: Avoiding applying x -> z rename to x/f" out &&
git ls-files -s >out &&
test_line_count = 6 out &&
git ls-files -o >out &&
test_line_count = 1 out &&
git rev-parse >actual \
HEAD:y/b HEAD:y/c HEAD:y/d HEAD:y/e HEAD:x/f HEAD:x/g &&
git rev-parse >expect \
O:z/b O:z/c O:x/d O:x/e O:w/f A:x/g &&
test_cmp expect actual
)
'
test_expect_success '9d-setup: N-way transitive rename?' '
test_create_repo 9d &&
(
cd 9d &&
mkdir z y x w v u &&
echo a >z/a &&
echo b >y/b &&
echo c >x/c &&
echo d >w/d &&
echo e >v/e &&
echo f >u/f &&
git add z y x w v u &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
git mv z/a y/ &&
git mv x/c w/ &&
git mv v/e u/ &&
test_tick &&
git commit -m "A" &&
git checkout B &&
echo t >z/t &&
git mv y/b x/ &&
git mv w/d v/ &&
git add z/t &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '9d-check: N-way transitive rename?' '
(
cd 9d &&
git checkout A^0 &&
git 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 &&
test_i18ngrep "WARNING: Avoiding applying w -> v rename to w/c" out &&
git ls-files -s >out &&
test_line_count = 7 out &&
git ls-files -o >out &&
test_line_count = 1 out &&
git rev-parse >actual \
HEAD:z/t \
HEAD:y/a HEAD:x/b HEAD:w/c \
HEAD:u/d HEAD:u/e HEAD:u/f &&
git rev-parse >expect \
B:z/t \
O:z/a O:y/b O:x/c \
O:w/d O:v/e A:u/f &&
test_cmp expect actual
)
'
test_expect_success '9e-setup: N-to-1 whammo' '
test_create_repo 9e &&
(
cd 9e &&
mkdir dir1 dir2 dir3 dirN &&
echo a >dir1/a &&
echo b >dir1/b &&
echo d >dir2/d &&
echo e >dir2/e &&
echo g >dir3/g &&
echo h >dir3/h &&
echo j >dirN/j &&
echo k >dirN/k &&
git add dir* &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
echo c >dir1/c &&
echo yo >dir1/yo &&
echo f >dir2/f &&
echo yo >dir2/yo &&
echo i >dir3/i &&
echo yo >dir3/yo &&
echo l >dirN/l &&
echo yo >dirN/yo &&
git add dir* &&
test_tick &&
git commit -m "A" &&
git checkout B &&
git mv dir1 combined &&
git mv dir2/* combined/ &&
git mv dir3/* combined/ &&
git mv dirN/* combined/ &&
test_tick &&
git commit -m "B"
)
'
test_expect_success C_LOCALE_OUTPUT '9e-check: N-to-1 whammo' '
(
cd 9e &&
git checkout A^0 &&
test_must_fail git 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 &&
grep -q dir3/yo error_line &&
grep -q dirN/yo error_line &&
git ls-files -s >out &&
test_line_count = 16 out &&
git ls-files -u >out &&
test_line_count = 0 out &&
git ls-files -o >out &&
test_line_count = 2 out &&
git rev-parse >actual \
:0:combined/a :0:combined/b :0:combined/c \
:0:combined/d :0:combined/e :0:combined/f \
:0:combined/g :0:combined/h :0:combined/i \
:0:combined/j :0:combined/k :0:combined/l &&
git rev-parse >expect \
O:dir1/a O:dir1/b A:dir1/c \
O:dir2/d O:dir2/e A:dir2/f \
O:dir3/g O:dir3/h A:dir3/i \
O:dirN/j O:dirN/k A:dirN/l &&
test_cmp expect actual &&
git rev-parse >actual \
:0:dir1/yo :0:dir2/yo :0:dir3/yo :0:dirN/yo &&
git rev-parse >expect \
A:dir1/yo A:dir2/yo A:dir3/yo A:dirN/yo &&
test_cmp expect actual
)
'
test_expect_success '9f-setup: Renamed directory that only contained immediate subdirs' '
test_create_repo 9f &&
(
cd 9f &&
mkdir -p goal/a &&
mkdir -p goal/b &&
echo foo >goal/a/foo &&
echo bar >goal/b/bar &&
echo baz >goal/b/baz &&
git add goal &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
git mv goal/ priority &&
test_tick &&
git commit -m "A" &&
git checkout B &&
echo c >goal/c &&
git add goal/c &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '9f-check: Renamed directory that only contained immediate subdirs' '
(
cd 9f &&
git checkout A^0 &&
git merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 4 out &&
git rev-parse >actual \
HEAD:priority/a/foo \
HEAD:priority/b/bar \
HEAD:priority/b/baz \
HEAD:priority/c &&
git rev-parse >expect \
O:goal/a/foo \
O:goal/b/bar \
O:goal/b/baz \
B:goal/c &&
test_cmp expect actual &&
test_must_fail git rev-parse HEAD:goal/c
)
'
test_expect_success '9g-setup: Renamed directory that only contained immediate subdirs, immediate subdirs renamed' '
test_create_repo 9g &&
(
cd 9g &&
mkdir -p goal/a &&
mkdir -p goal/b &&
echo foo >goal/a/foo &&
echo bar >goal/b/bar &&
echo baz >goal/b/baz &&
git add goal &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
mkdir priority &&
git mv goal/a/ priority/alpha &&
git mv goal/b/ priority/beta &&
rmdir goal/ &&
test_tick &&
git commit -m "A" &&
git checkout B &&
echo c >goal/c &&
git add goal/c &&
test_tick &&
git commit -m "B"
)
'
test_expect_failure '9g-check: Renamed directory that only contained immediate subdirs, immediate subdirs renamed' '
(
cd 9g &&
git checkout A^0 &&
git merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 4 out &&
git rev-parse >actual \
HEAD:priority/alpha/foo \
HEAD:priority/beta/bar \
HEAD:priority/beta/baz \
HEAD:priority/c &&
git rev-parse >expect \
O:goal/a/foo \
O:goal/b/bar \
O:goal/b/baz \
B:goal/c &&
test_cmp expect actual &&
test_must_fail git rev-parse HEAD:goal/c
)
'
test_expect_success '9h-setup: Avoid dir rename on merely modified path' '
test_create_repo 9h &&
(
cd 9h &&
mkdir z &&
echo b >z/b &&
echo c >z/c &&
printf "1\n2\n3\n4\n5\n6\n7\n8\nd\n" >z/d &&
git add z &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
test_tick &&
echo more >>z/d &&
git add z/d &&
git commit -m "A" &&
git checkout B &&
mkdir y &&
mkdir x &&
git mv z/b y/ &&
git mv z/c y/ &&
git mv z/d x/ &&
rmdir z &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '9h-check: Avoid dir rename on merely modified path' '
(
cd 9h &&
git checkout A^0 &&
git merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 3 out &&
git rev-parse >actual \
HEAD:y/b HEAD:y/c HEAD:x/d &&
git rev-parse >expect \
O:z/b O:z/c A:z/d &&
test_cmp expect actual
)
'
test_expect_success '10a-setup: Overwrite untracked with normal rename/delete' '
test_create_repo 10a &&
(
cd 10a &&
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 rm z/c &&
test_tick &&
git commit -m "A" &&
git checkout B &&
git mv z/c z/d &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '10a-check: Overwrite untracked with normal rename/delete' '
(
cd 10a &&
git checkout A^0 &&
echo very >z/c &&
echo important >z/d &&
test_must_fail git 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 &&
test_line_count = 1 out &&
git ls-files -o >out &&
test_line_count = 4 out &&
echo very >expect &&
test_cmp expect z/c &&
echo important >expect &&
test_cmp expect z/d &&
git rev-parse HEAD:z/b >actual &&
git rev-parse O:z/b >expect &&
test_cmp expect actual
)
'
test_expect_success '10b-setup: Overwrite untracked with dir rename + delete' '
test_create_repo 10b &&
(
cd 10b &&
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 rm z/c &&
git mv z/ y/ &&
test_tick &&
git commit -m "A" &&
git checkout B &&
git mv z/c z/d &&
echo e >z/e &&
git add z/e &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '10b-check: Overwrite untracked with dir rename + delete' '
(
cd 10b &&
git checkout A^0 &&
echo very >y/c &&
echo important >y/d &&
echo contents >y/e &&
test_must_fail git 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 ls-files -s >out &&
test_line_count = 3 out &&
git ls-files -u >out &&
test_line_count = 2 out &&
git ls-files -o >out &&
test_line_count = 5 out &&
git rev-parse >actual \
:0:y/b :3:y/d :3:y/e &&
git rev-parse >expect \
O:z/b O:z/c B:z/e &&
test_cmp expect actual &&
echo very >expect &&
test_cmp expect y/c &&
echo important >expect &&
test_cmp expect y/d &&
echo contents >expect &&
test_cmp expect y/e
)
'
test_expect_success '10c-setup: Overwrite untracked with dir rename/rename(1to2)' '
test_create_repo 10c &&
(
cd 10c &&
mkdir z x &&
echo a >z/a &&
echo b >z/b &&
echo c >x/c &&
echo d >x/d &&
git add z x &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
mkdir w &&
git mv x/c w/c &&
git mv z/ y/ &&
test_tick &&
git commit -m "A" &&
git checkout B &&
git mv x/c z/ &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '10c-check: Overwrite untracked with dir rename/rename(1to2)' '
(
cd 10c &&
git checkout A^0 &&
echo important >y/c &&
test_must_fail git 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 &&
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 :2:w/c :3: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~B^0 >actual &&
git rev-parse O:x/c >expect &&
test_cmp expect actual &&
echo important >expect &&
test_cmp expect y/c
)
'
test_expect_success '10d-setup: Delete untracked with dir rename/rename(2to1)' '
test_create_repo 10d &&
(
cd 10d &&
mkdir z x &&
echo a >z/a &&
echo b >z/b &&
echo c >z/c &&
echo d >x/d &&
echo e >x/e &&
echo f >x/f &&
git add z x &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
git mv z/c x/wham &&
git mv z/ y/ &&
test_tick &&
git commit -m "A" &&
git checkout B &&
git mv x/f z/wham &&
git mv x/ y/ &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '10d-check: Delete untracked with dir rename/rename(2to1)' '
(
cd 10d &&
git checkout A^0 &&
echo important >y/wham &&
test_must_fail git 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 -s >out &&
test_line_count = 6 out &&
git ls-files -u >out &&
test_line_count = 2 out &&
git ls-files -o >out &&
test_line_count = 4 out &&
git rev-parse >actual \
:0:y/a :0:y/b :0:y/d :0:y/e :2:y/wham :3:y/wham &&
git rev-parse >expect \
O:z/a O:z/b O:x/d O:x/e O:z/c O:x/f &&
test_cmp expect actual &&
test_must_fail git rev-parse :1: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_expect_success '10e-setup: Does git complain about untracked file that is not really in the way?' '
test_create_repo 10e &&
(
cd 10e &&
mkdir z &&
echo a >z/a &&
echo b >z/b &&
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 c >z/c &&
git add z/c &&
test_tick &&
git commit -m "B"
)
'
test_expect_failure '10e-check: Does git complain about untracked file that is not really in the way?' '
(
cd 10e &&
git checkout A^0 &&
mkdir z &&
echo random >z/c &&
git 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 &&
test_line_count = 3 out &&
git ls-files -u >out &&
test_line_count = 0 out &&
git ls-files -o >out &&
test_line_count = 3 out &&
git rev-parse >actual \
:0:y/a :0:y/b :0:y/c &&
git rev-parse >expect \
O:z/a O:z/b B:z/c &&
test_cmp expect actual &&
echo random >expect &&
test_cmp expect z/c
)
'
test_expect_success '11a-setup: Avoid losing dirty contents with simple rename' '
test_create_repo 11a &&
(
cd 11a &&
mkdir z &&
echo a >z/a &&
test_seq 1 10 >z/b &&
git add z &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
git mv z/b z/c &&
test_tick &&
git commit -m "A" &&
git checkout B &&
echo 11 >>z/b &&
git add z/b &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '11a-check: Avoid losing dirty contents with simple rename' '
(
cd 11a &&
git checkout A^0 &&
echo stuff >>z/c &&
test_must_fail git merge -s recursive B^0 >out 2>err &&
test_i18ngrep "Refusing to lose dirty file at z/c" out &&
test_seq 1 10 >expected &&
echo stuff >>expected &&
test_cmp expected z/c &&
git ls-files -s >out &&
test_line_count = 2 out &&
git ls-files -u >out &&
test_line_count = 1 out &&
git ls-files -o >out &&
test_line_count = 4 out &&
git rev-parse >actual \
:0:z/a :2:z/c &&
git rev-parse >expect \
O:z/a B:z/b &&
test_cmp expect actual &&
git hash-object z/c~HEAD >actual &&
git rev-parse B:z/b >expect &&
test_cmp expect actual
)
'
test_expect_success '11b-setup: Avoid losing dirty file involved in directory rename' '
test_create_repo 11b &&
(
cd 11b &&
mkdir z x &&
echo a >z/a &&
echo b >x/b &&
test_seq 1 10 >x/c &&
git add z x &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
git mv x/c z/c &&
test_tick &&
git commit -m "A" &&
git checkout B &&
git mv z y &&
echo 11 >>x/c &&
git add x/c &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '11b-check: Avoid losing dirty file involved in directory rename' '
(
cd 11b &&
git checkout A^0 &&
echo stuff >>z/c &&
git merge -s recursive B^0 >out 2>err &&
test_i18ngrep "Refusing to lose dirty file at z/c" out &&
grep -q stuff z/c &&
test_seq 1 10 >expected &&
echo stuff >>expected &&
test_cmp expected z/c &&
git ls-files -s >out &&
test_line_count = 3 out &&
git ls-files -u >out &&
test_line_count = 0 out &&
git ls-files -m >out &&
test_line_count = 0 out &&
git ls-files -o >out &&
test_line_count = 4 out &&
git rev-parse >actual \
:0:x/b :0:y/a :0:y/c &&
git rev-parse >expect \
O:x/b O:z/a B:x/c &&
test_cmp expect actual &&
git hash-object y/c >actual &&
git rev-parse B:x/c >expect &&
test_cmp expect actual
)
'
test_expect_success '11c-setup: Avoid losing not-uptodate with rename + D/F conflict' '
test_create_repo 11c &&
(
cd 11c &&
mkdir y x &&
echo a >y/a &&
echo b >x/b &&
test_seq 1 10 >x/c &&
git add y x &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
git mv x/c y/c &&
test_tick &&
git commit -m "A" &&
git checkout B &&
mkdir y/c &&
echo d >y/c/d &&
echo 11 >>x/c &&
git add x/c y/c/d &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '11c-check: Avoid losing not-uptodate with rename + D/F conflict' '
(
cd 11c &&
git checkout A^0 &&
echo stuff >>y/c &&
test_must_fail git merge -s recursive B^0 >out 2>err &&
test_i18ngrep "following files would be overwritten by merge" err &&
grep -q stuff y/c &&
test_seq 1 10 >expected &&
echo stuff >>expected &&
test_cmp expected y/c &&
git ls-files -s >out &&
test_line_count = 3 out &&
git ls-files -u >out &&
test_line_count = 0 out &&
git ls-files -m >out &&
test_line_count = 1 out &&
git ls-files -o >out &&
test_line_count = 3 out
)
'
test_expect_success '11d-setup: Avoid losing not-uptodate with rename + D/F conflict' '
test_create_repo 11d &&
(
cd 11d &&
mkdir z x &&
echo a >z/a &&
echo b >x/b &&
test_seq 1 10 >x/c &&
git add z x &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
git mv x/c z/c &&
test_tick &&
git commit -m "A" &&
git checkout B &&
git mv z y &&
mkdir y/c &&
echo d >y/c/d &&
echo 11 >>x/c &&
git add x/c y/c/d &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '11d-check: Avoid losing not-uptodate with rename + D/F conflict' '
(
cd 11d &&
git checkout A^0 &&
echo stuff >>z/c &&
test_must_fail git merge -s recursive B^0 >out 2>err &&
test_i18ngrep "Refusing to lose dirty file at z/c" out &&
grep -q stuff z/c &&
test_seq 1 10 >expected &&
echo stuff >>expected &&
test_cmp expected z/c &&
git ls-files -s >out &&
test_line_count = 4 out &&
git ls-files -u >out &&
test_line_count = 1 out &&
git ls-files -o >out &&
test_line_count = 5 out &&
git rev-parse >actual \
:0:x/b :0:y/a :0:y/c/d :3:y/c &&
git rev-parse >expect \
O:x/b O:z/a B:y/c/d B:x/c &&
test_cmp expect actual &&
git hash-object y/c~HEAD >actual &&
git rev-parse B:x/c >expect &&
test_cmp expect actual
)
'
test_expect_success '11e-setup: Avoid deleting not-uptodate with dir rename/rename(1to2)/add' '
test_create_repo 11e &&
(
cd 11e &&
mkdir z x &&
echo a >z/a &&
echo b >z/b &&
echo c >x/c &&
echo d >x/d &&
git add z x &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
git mv z/ y/ &&
echo different >y/c &&
mkdir w &&
git mv x/c w/ &&
git add y/c &&
test_tick &&
git commit -m "A" &&
git checkout B &&
git mv x/c z/ &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '11e-check: Avoid deleting not-uptodate with dir rename/rename(1to2)/add' '
(
cd 11e &&
git checkout A^0 &&
echo mods >>y/c &&
test_must_fail git 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 -s >out &&
test_line_count = 7 out &&
git ls-files -u >out &&
test_line_count = 4 out &&
git ls-files -o >out &&
test_line_count = 4 out &&
echo different >expected &&
echo mods >>expected &&
test_cmp expected y/c &&
git rev-parse >actual \
:0:y/a :0:y/b :0:x/d :1:x/c :2:w/c :2:y/c :3:y/c &&
git rev-parse >expect \
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
)
'
test_expect_success '11f-setup: Avoid deleting not-uptodate with dir rename/rename(2to1)' '
test_create_repo 11f &&
(
cd 11f &&
mkdir z x &&
echo a >z/a &&
echo b >z/b &&
test_seq 1 10 >x/c &&
echo d >x/d &&
git add z x &&
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/c y/wham &&
test_tick &&
git commit -m "A" &&
git checkout B &&
git mv x/d z/wham &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '11f-check: Avoid deleting not-uptodate with dir rename/rename(2to1)' '
(
cd 11f &&
git checkout A^0 &&
echo important >>y/wham &&
test_must_fail git 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 -s >out &&
test_line_count = 4 out &&
git ls-files -u >out &&
test_line_count = 2 out &&
git ls-files -o >out &&
test_line_count = 4 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_expect_success '12a-setup: Moving one directory hierarchy into another' '
test_create_repo 12a &&
(
cd 12a &&
mkdir -p node1 node2 &&
echo leaf1 >node1/leaf1 &&
echo leaf2 >node1/leaf2 &&
echo leaf3 >node2/leaf3 &&
echo leaf4 >node2/leaf4 &&
git add node1 node2 &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
git mv node2/ node1/ &&
test_tick &&
git commit -m "A" &&
git checkout B &&
echo leaf5 >node1/leaf5 &&
echo leaf6 >node2/leaf6 &&
git add node1 node2 &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '12a-check: Moving one directory hierarchy into another' '
(
cd 12a &&
git checkout A^0 &&
git merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 6 out &&
git rev-parse >actual \
HEAD:node1/leaf1 HEAD:node1/leaf2 HEAD:node1/leaf5 \
HEAD:node1/node2/leaf3 \
HEAD:node1/node2/leaf4 \
HEAD:node1/node2/leaf6 &&
git rev-parse >expect \
O:node1/leaf1 O:node1/leaf2 B:node1/leaf5 \
O:node2/leaf3 \
O:node2/leaf4 \
B:node2/leaf6 &&
test_cmp expect actual
)
'
test_expect_success '12b-setup: Moving one directory hierarchy into another' '
test_create_repo 12b &&
(
cd 12b &&
mkdir -p node1 node2 &&
echo leaf1 >node1/leaf1 &&
echo leaf2 >node1/leaf2 &&
echo leaf3 >node2/leaf3 &&
echo leaf4 >node2/leaf4 &&
git add node1 node2 &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
git mv node2/ node1/ &&
test_tick &&
git commit -m "A" &&
git checkout B &&
git mv node1/ node2/ &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '12b-check: Moving one directory hierarchy into another' '
(
cd 12b &&
git checkout A^0 &&
git merge -s recursive B^0 &&
git ls-files -s >out &&
test_line_count = 4 out &&
git rev-parse >actual \
HEAD:node1/node2/node1/leaf1 \
HEAD:node1/node2/node1/leaf2 \
HEAD:node2/node1/node2/leaf3 \
HEAD:node2/node1/node2/leaf4 &&
git rev-parse >expect \
O:node1/leaf1 \
O:node1/leaf2 \
O:node2/leaf3 \
O:node2/leaf4 &&
test_cmp expect actual
)
'
test_expect_success '12c-setup: Moving one directory hierarchy into another w/ content merge' '
test_create_repo 12c &&
(
cd 12c &&
mkdir -p node1 node2 &&
printf "1\n2\n3\n4\n5\n6\n7\n8\nleaf1\n" >node1/leaf1 &&
printf "1\n2\n3\n4\n5\n6\n7\n8\nleaf2\n" >node1/leaf2 &&
printf "1\n2\n3\n4\n5\n6\n7\n8\nleaf3\n" >node2/leaf3 &&
printf "1\n2\n3\n4\n5\n6\n7\n8\nleaf4\n" >node2/leaf4 &&
git add node1 node2 &&
test_tick &&
git commit -m "O" &&
git branch O &&
git branch A &&
git branch B &&
git checkout A &&
git mv node2/ node1/ &&
for i in `git ls-files`; do echo side A >>$i; done &&
git add -u &&
test_tick &&
git commit -m "A" &&
git checkout B &&
git mv node1/ node2/ &&
for i in `git ls-files`; do echo side B >>$i; done &&
git add -u &&
test_tick &&
git commit -m "B"
)
'
test_expect_success '12c-check: Moving one directory hierarchy into another w/ content merge' '
(
cd 12c &&
git checkout A^0 &&
test_must_fail git merge -s recursive B^0 &&
git ls-files -u >out &&
test_line_count = 12 out &&
git rev-parse >actual \
:1:node1/node2/node1/leaf1 \
:1:node1/node2/node1/leaf2 \
:1:node2/node1/node2/leaf3 \
:1:node2/node1/node2/leaf4 \
:2:node1/node2/node1/leaf1 \
:2:node1/node2/node1/leaf2 \
:2:node2/node1/node2/leaf3 \
:2:node2/node1/node2/leaf4 \
:3:node1/node2/node1/leaf1 \
:3:node1/node2/node1/leaf2 \
:3:node2/node1/node2/leaf3 \
:3:node2/node1/node2/leaf4 &&
git rev-parse >expect \
O:node1/leaf1 \
O:node1/leaf2 \
O:node2/leaf3 \
O:node2/leaf4 \
A:node1/leaf1 \
A:node1/leaf2 \
A:node1/node2/leaf3 \
A:node1/node2/leaf4 \
B:node2/node1/leaf1 \
B:node2/node1/leaf2 \
B:node2/leaf3 \
B:node2/leaf4 &&
test_cmp expect actual
)
'
test_done