merge tests: expect improved directory/file conflict handling in ort

merge-recursive.c is built on the idea of running unpack_trees() and
then "doing minor touch-ups" to get the result.  Unfortunately,
unpack_trees() was run in an update-as-it-goes mode, leading
merge-recursive.c to follow suit and end up with an immediate evaluation
and fix-it-up-as-you-go design.  Some things like directory/file
conflicts are not well representable in the index data structure, and
required special extra code to handle.  But then when it was discovered
that rename/delete conflicts could also be involved in directory/file
conflicts, the special directory/file conflict handling code had to be
copied to the rename/delete codepath.  ...and then it had to be copied
for modify/delete, and for rename/rename(1to2) conflicts, ...and yet it
still missed some.  Further, when it was discovered that there were also
file/submodule conflicts and submodule/directory conflicts, we needed to
copy the special submodule handling code to all the special cases
throughout the codebase.

And then it was discovered that our handling of directory/file conflicts
was suboptimal because it would create untracked files to store the
contents of the conflicting file, which would not be cleaned up if
someone were to run a 'git merge --abort' or 'git rebase --abort'.  It
was also difficult or scary to try to add or remove the index entries
corresponding to these files given the directory/file conflict in the
index.  But changing merge-recursive.c to handle these correctly was a
royal pain because there were so many sites in the code with similar but
not identical code for handling directory/file/submodule conflicts that
would all need to be updated.

I have worked hard to push all directory/file/submodule conflict
handling in merge-ort through a single codepath, and avoid creating
untracked files for storing tracked content (it does record things at
alternate paths, but makes sure they have higher-order stages in the
index).

Since updating merge-recursive is too much work and we don't want to
destabilize it, instead update the testsuite to have different
expectations for relevant directory/file/submodule conflict tests.

Signed-off-by: Elijah Newren <newren@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Elijah Newren
2020-10-26 17:01:37 +00:00
committed by Junio C Hamano
parent f06481f127
commit ef52778708
6 changed files with 308 additions and 102 deletions

View File

@ -538,9 +538,15 @@ test_expect_success 'setup differently handled merges of directory/file conflict
git checkout B^0 &&
test_must_fail git merge C^0 &&
git clean -fd &&
git rm -rf a/ &&
git rm a &&
if test "$GIT_TEST_MERGE_ALGORITHM" = ort
then
git rm -rf a/ &&
git rm a~HEAD
else
git clean -fd &&
git rm -rf a/ &&
git rm a
fi &&
git cat-file -p B:a >a2 &&
git add a2 &&
git commit -m D2 &&
@ -559,7 +565,12 @@ test_expect_success 'setup differently handled merges of directory/file conflict
git checkout C^0 &&
test_must_fail git merge B^0 &&
git clean -fd &&
if test "$GIT_TEST_MERGE_ALGORITHM" = ort
then
git rm a~B^0
else
git clean -fd
fi &&
git rm -rf a/ &&
test_write_lines 1 2 3 4 5 6 7 8 >a &&
git add a &&
@ -568,9 +579,15 @@ test_expect_success 'setup differently handled merges of directory/file conflict
git checkout C^0 &&
test_must_fail git merge B^0 &&
git clean -fd &&
git rm -rf a/ &&
git rm a &&
if test "$GIT_TEST_MERGE_ALGORITHM" = ort
then
git rm -rf a/ &&
git rm a~B^0
else
git clean -fd &&
git rm -rf a/ &&
git rm a
fi &&
test_write_lines 1 2 3 4 5 6 7 8 >a2 &&
git add a2 &&
git commit -m E4 &&
@ -588,18 +605,34 @@ test_expect_success 'merge of D1 & E1 fails but has appropriate contents' '
test_must_fail git merge -s recursive E1^0 &&
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 &&
if test "$GIT_TEST_MERGE_ALGORITHM" = ort
then
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 = 1 out &&
git rev-parse >expect \
A:ignore-me B:a &&
git rev-parse >actual \
:0:ignore-me :2:a &&
test_cmp expect actual
git rev-parse >expect \
A:ignore-me B:a D1:a &&
git rev-parse >actual \
:0:ignore-me :1:a :2:a &&
test_cmp expect actual
else
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 >expect \
A:ignore-me B:a &&
git rev-parse >actual \
:0:ignore-me :2:a &&
test_cmp expect actual
fi
)
'
@ -613,18 +646,34 @@ test_expect_success 'merge of E1 & D1 fails but has appropriate contents' '
test_must_fail git merge -s recursive D1^0 &&
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 &&
if test "$GIT_TEST_MERGE_ALGORITHM" = ort
then
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 = 1 out &&
git rev-parse >expect \
A:ignore-me B:a &&
git rev-parse >actual \
:0:ignore-me :3:a &&
test_cmp expect actual
git rev-parse >expect \
A:ignore-me B:a D1:a &&
git rev-parse >actual \
:0:ignore-me :1:a :3:a &&
test_cmp expect actual
else
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 >expect \
A:ignore-me B:a &&
git rev-parse >actual \
:0:ignore-me :3:a &&
test_cmp expect actual
fi
)
'
@ -638,17 +687,32 @@ test_expect_success 'merge of D1 & E2 fails but has appropriate contents' '
test_must_fail git merge -s recursive E2^0 &&
git ls-files -s >out &&
test_line_count = 4 out &&
git ls-files -u >out &&
test_line_count = 3 out &&
git ls-files -o >out &&
test_line_count = 2 out &&
if test "$GIT_TEST_MERGE_ALGORITHM" = ort
then
git ls-files -s >out &&
test_line_count = 5 out &&
git ls-files -u >out &&
test_line_count = 4 out &&
git ls-files -o >out &&
test_line_count = 1 out &&
git rev-parse >expect \
B:a E2:a/file C:a/file A:ignore-me &&
git rev-parse >actual \
:2:a :3:a/file :1:a/file :0:ignore-me &&
git rev-parse >expect \
B:a D1:a E2:a/file C:a/file A:ignore-me &&
git rev-parse >actual \
:1:a~HEAD :2:a~HEAD :3:a/file :1:a/file :0:ignore-me
else
git ls-files -s >out &&
test_line_count = 4 out &&
git ls-files -u >out &&
test_line_count = 3 out &&
git ls-files -o >out &&
test_line_count = 2 out &&
git rev-parse >expect \
B:a E2:a/file C:a/file A:ignore-me &&
git rev-parse >actual \
:2:a :3:a/file :1:a/file :0:ignore-me
fi &&
test_cmp expect actual &&
test_path_is_file a~HEAD
@ -665,17 +729,32 @@ test_expect_success 'merge of E2 & D1 fails but has appropriate contents' '
test_must_fail git merge -s recursive D1^0 &&
git ls-files -s >out &&
test_line_count = 4 out &&
git ls-files -u >out &&
test_line_count = 3 out &&
git ls-files -o >out &&
test_line_count = 2 out &&
if test "$GIT_TEST_MERGE_ALGORITHM" = ort
then
git ls-files -s >out &&
test_line_count = 5 out &&
git ls-files -u >out &&
test_line_count = 4 out &&
git ls-files -o >out &&
test_line_count = 1 out &&
git rev-parse >expect \
B:a E2:a/file C:a/file A:ignore-me &&
git rev-parse >actual \
:3:a :2:a/file :1:a/file :0:ignore-me &&
git rev-parse >expect \
B:a D1:a E2:a/file C:a/file A:ignore-me &&
git rev-parse >actual \
:1:a~D1^0 :3:a~D1^0 :2:a/file :1:a/file :0:ignore-me
else
git ls-files -s >out &&
test_line_count = 4 out &&
git ls-files -u >out &&
test_line_count = 3 out &&
git ls-files -o >out &&
test_line_count = 2 out &&
git rev-parse >expect \
B:a E2:a/file C:a/file A:ignore-me &&
git rev-parse >actual \
:3:a :2:a/file :1:a/file :0:ignore-me
fi &&
test_cmp expect actual &&
test_path_is_file a~D1^0