{"thread":{"id":"54492","subject":"[PATCH 0/9] Support both merge backends in the testsuite, via environment variable","startedAt":"2020-10-23T16:01:30Z","lastAt":"2020-10-26T17:43:23Z","messageCount":31,"participants":["Elijah Newren via GitGitGadget","Junio C Hamano","Elijah Newren","Đoàn Trần Công Danh"],"isPatch":true,"patchVersion":1,"patchTotal":9},"messages":[{"id":"408249","messageId":"pull.769.git.1603468885.gitgitgadget@gmail.com","threadId":"54492","inReplyTo":null,"subject":"[PATCH 0/9] Support both merge backends in the testsuite, via environment variable","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-10-23T16:01:15Z","receivedAt":"2020-10-23T16:01:30Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"This patch series builds on top of en/dir-rename-tests. It can be applied\nindependent of my \"new merge-ort\" API series I submitted a couple days\nago[1], but this series uses the same environment variable as patch 4 of\nthat series. [Also, if gitgitgadget emails more than 8 patches, then my\nattempts to use it to send out a patch series based on en/dir-rename-tests\nwent wrong.]\n\nAs promised, here is a series that makes the testsuite changes needed to\nsimultaneously support both merge backends, keyed off a\nGIT_TEST_MERGE_ALGORITHM environment variable setting.\n\nNOTE: The tests do not yet pass with GIT_TEST_MERGE_ALGORITHM=ort, because I\nhaven't submitted the implementation of the merge-ort functions -- yet. I\nfigured they are useful as a high level overview of the differences in\nbehavior between the two backends, and thus am providing these before the\nimplementation.\n\n[1] \nhttps://lore.kernel.org/git/pull.895.git.git.1603286555.gitgitgadget@gmail.com/\n\nElijah Newren (9):\n  t/: new helper for tests that pass with ort but fail with recursive\n  merge tests: expect improved directory/file conflict handling in ort\n  t6416: correct expectation for rename/rename(1to2) + directory/file\n  t6404, t6423: expect improved rename/delete handling in ort backend\n  t6423: expect improved conflict markers labels in the ort backend\n  merge tests: expect slight differences in output for recursive vs. ort\n  t6423, t6436: note improved ort handling with dirty files\n  t6423: note improved ort handling with untracked files\n  t6423: add more details about direct resolution of directories\n\n t/lib-merge.sh                         |  15 +\n t/t6400-merge-df.sh                    |  14 +-\n t/t6402-merge-rename.sh                | 122 ++++-\n t/t6404-recursive-merge.sh             |  14 +-\n t/t6416-recursive-corner-cases.sh      | 200 ++++---\n t/t6422-merge-rename-corner-cases.sh   |  37 +-\n t/t6423-merge-rename-directories.sh    | 704 +++++++++++++++----------\n t/t6426-merge-skip-unneeded-updates.sh |   3 +-\n t/t6430-merge-recursive.sh             |   3 +-\n t/t6436-merge-overwrite.sh             |  18 +-\n t/t6437-submodule-merge.sh             |  25 +-\n t/t7602-merge-octopus-many.sh          |   4 +\n t/t7610-mergetool.sh                   |  32 +-\n 13 files changed, 805 insertions(+), 386 deletions(-)\n create mode 100644 t/lib-merge.sh\n\n\nbase-commit: c64432aacda9054459ce550eca95929897c301bd\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-769%2Fnewren%2Ftests-support-both-merge-backends-v1\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-769/newren/tests-support-both-merge-backends-v1\nPull-Request: https://github.com/gitgitgadget/git/pull/769\n-- \ngitgitgadget\n"},{"id":"408250","messageId":"9394d526f1425fcf6b8865b53b737ba81c11dd80.1603468885.git.gitgitgadget@gmail.com","threadId":"54492","inReplyTo":"pull.769.git.1603468885.gitgitgadget@gmail.com","subject":"[PATCH 2/9] merge tests: expect improved directory/file conflict handling in ort","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-10-23T16:01:17Z","receivedAt":"2020-10-23T16:01:32Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nmerge-recursive.c is built on the idea of running unpack_trees() and\nthen \"doing minor touch-ups\" to get the result.  Unfortunately,\nunpack_trees() was run in an update-as-it-goes mode, leading\nmerge-recursive.c to follow suit and end up with an immediate evaluation\nand fix-it-up-as-you-go design.  Some things like directory/file\nconflicts are not well representable in the index data structure, and\nrequired special extra code to handle.  But then when it was discovered\nthat rename/delete conflicts could also be involved in directory/file\nconflicts, the special directory/file conflict handling code had to be\ncopied to the rename/delete codepath.  ...and then it had to be copied\nfor modify/delete, and for rename/rename(1to2) conflicts, ...and yet it\nstill missed some.  Further, when it was discovered that there were also\nfile/submodule conflicts and submodule/directory conflicts, we needed to\ncopy the special submodule handling code to all the special cases\nthroughout the codebase.\n\nAnd then it was discovered that our handling of directory/file conflicts\nwas suboptimal because it would create untracked files to store the\ncontents of the conflicting file, which would not be cleaned up if\nsomeone were to run a 'git merge --abort' or 'git rebase --abort'.  It\nwas also difficult or scary to try to add or remove the index entries\ncorresponding to these files given the directory/file conflict in the\nindex.  But changing merge-recursive.c to handle these correctly was a\nroyal pain because there were so many sites in the code with similar but\nnot identical code for handling directory/file/submodule conflicts that\nwould all need to be updated.\n\nI have worked hard to push all directory/file/submodule conflict\nhandling in merge-ort through a single codepath, and avoid creating\nuntracked files for storing tracked content (it does record things at\nalternate paths, but makes sure they have higher-order stages in the\nindex).\n\nSince updating merge-recursive is too much work and we don't want to\ndestabilize it, instead update the testsuite to have different\nexpectations for relevant directory/file/submodule conflict tests.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n t/t6400-merge-df.sh                  |  14 +-\n t/t6402-merge-rename.sh              | 108 ++++++++++++----\n t/t6416-recursive-corner-cases.sh    | 185 +++++++++++++++++++--------\n t/t6422-merge-rename-corner-cases.sh |  30 +++--\n t/t6423-merge-rename-directories.sh  |  53 +++++---\n t/t7610-mergetool.sh                 |  32 ++++-\n 6 files changed, 314 insertions(+), 108 deletions(-)\n\ndiff --git a/t/t6400-merge-df.sh b/t/t6400-merge-df.sh\nindex f1b84617af..9da0838216 100755\n--- a/t/t6400-merge-df.sh\n+++ b/t/t6400-merge-df.sh\n@@ -81,7 +81,12 @@ test_expect_success 'modify/delete + directory/file conflict' '\n \n \ttest 5 -eq $(git ls-files -s | wc -l) &&\n \ttest 4 -eq $(git ls-files -u | wc -l) &&\n-\ttest 1 -eq $(git ls-files -o | wc -l) &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\ttest 0 -eq $(git ls-files -o | wc -l)\n+\telse\n+\t\ttest 1 -eq $(git ls-files -o | wc -l)\n+\tfi &&\n \n \ttest_path_is_file letters/file &&\n \ttest_path_is_file letters.txt &&\n@@ -97,7 +102,12 @@ test_expect_success 'modify/delete + directory/file conflict; other way' '\n \n \ttest 5 -eq $(git ls-files -s | wc -l) &&\n \ttest 4 -eq $(git ls-files -u | wc -l) &&\n-\ttest 1 -eq $(git ls-files -o | wc -l) &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\ttest 0 -eq $(git ls-files -o | wc -l)\n+\telse\n+\t\ttest 1 -eq $(git ls-files -o | wc -l)\n+\tfi &&\n \n \ttest_path_is_file letters/file &&\n \ttest_path_is_file letters.txt &&\ndiff --git a/t/t6402-merge-rename.sh b/t/t6402-merge-rename.sh\nindex bbbba3dcbf..47d4434d64 100755\n--- a/t/t6402-merge-rename.sh\n+++ b/t/t6402-merge-rename.sh\n@@ -397,7 +397,12 @@ test_expect_success 'Rename+D/F conflict; renamed file cannot merge and dir in t\n \ttest_must_fail git merge --strategy=recursive dir-in-way &&\n \n \ttest 5 -eq \"$(git ls-files -u | wc -l)\" &&\n-\ttest 3 -eq \"$(git ls-files -u dir | grep -v file-in-the-way | wc -l)\" &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\ttest 3 -eq \"$(git ls-files -u dir~HEAD | wc -l)\"\n+\telse\n+\t\ttest 3 -eq \"$(git ls-files -u dir | grep -v file-in-the-way | wc -l)\"\n+\tfi &&\n \ttest 2 -eq \"$(git ls-files -u dir/file-in-the-way | wc -l)\" &&\n \n \ttest_must_fail git diff --quiet &&\n@@ -415,7 +420,12 @@ test_expect_success 'Same as previous, but merged other way' '\n \ttest_must_fail git merge --strategy=recursive renamed-file-has-conflicts &&\n \n \ttest 5 -eq \"$(git ls-files -u | wc -l)\" &&\n-\ttest 3 -eq \"$(git ls-files -u dir | grep -v file-in-the-way | wc -l)\" &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\ttest 3 -eq \"$(git ls-files -u dir~renamed-file-has-conflicts | wc -l)\"\n+\telse\n+\t\ttest 3 -eq \"$(git ls-files -u dir | grep -v file-in-the-way | wc -l)\"\n+\tfi &&\n \ttest 2 -eq \"$(git ls-files -u dir/file-in-the-way | wc -l)\" &&\n \n \ttest_must_fail git diff --quiet &&\n@@ -471,7 +481,12 @@ test_expect_success 'both rename source and destination involved in D/F conflict\n \tgit checkout -q rename-dest^0 &&\n \ttest_must_fail git merge --strategy=recursive source-conflict &&\n \n-\ttest 1 -eq \"$(git ls-files -u | wc -l)\" &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\ttest 2 -eq \"$(git ls-files -u | wc -l)\"\n+\telse\n+\t\ttest 1 -eq \"$(git ls-files -u | wc -l)\"\n+\tfi &&\n \n \ttest_must_fail git diff --quiet &&\n \n@@ -505,34 +520,63 @@ test_expect_success 'setup pair rename to parent of other (D/F conflicts)' '\n \tgit commit -m \"Rename one/file -> two\"\n '\n \n-test_expect_success 'pair rename to parent of other (D/F conflicts) w/ untracked dir' '\n-\tgit checkout -q rename-one^0 &&\n-\tmkdir one &&\n-\ttest_must_fail git merge --strategy=recursive rename-two &&\n+if test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+then\n+\ttest_expect_success 'pair rename to parent of other (D/F conflicts) w/ untracked dir' '\n+\t\tgit checkout -q rename-one^0 &&\n+\t\tmkdir one &&\n+\t\ttest_must_fail git merge --strategy=recursive rename-two &&\n \n-\ttest 2 -eq \"$(git ls-files -u | wc -l)\" &&\n-\ttest 1 -eq \"$(git ls-files -u one | wc -l)\" &&\n-\ttest 1 -eq \"$(git ls-files -u two | wc -l)\" &&\n+\t\ttest 4 -eq \"$(git ls-files -u | wc -l)\" &&\n+\t\ttest 2 -eq \"$(git ls-files -u one | wc -l)\" &&\n+\t\ttest 2 -eq \"$(git ls-files -u two | wc -l)\" &&\n \n-\ttest_must_fail git diff --quiet &&\n+\t\ttest_must_fail git diff --quiet &&\n \n-\ttest 4 -eq $(find . | grep -v .git | wc -l) &&\n+\t\ttest 3 -eq $(find . | grep -v .git | wc -l) &&\n \n-\ttest_path_is_dir one &&\n-\ttest_path_is_file one~rename-two &&\n-\ttest_path_is_file two &&\n-\ttest \"other\" = $(cat one~rename-two) &&\n-\ttest \"stuff\" = $(cat two)\n-'\n+\t\ttest_path_is_file one &&\n+\t\ttest_path_is_file two &&\n+\t\ttest \"other\" = $(cat one) &&\n+\t\ttest \"stuff\" = $(cat two)\n+\t'\n+else\n+\ttest_expect_success 'pair rename to parent of other (D/F conflicts) w/ untracked dir' '\n+\t\tgit checkout -q rename-one^0 &&\n+\t\tmkdir one &&\n+\t\ttest_must_fail git merge --strategy=recursive rename-two &&\n+\n+\t\ttest 2 -eq \"$(git ls-files -u | wc -l)\" &&\n+\t\ttest 1 -eq \"$(git ls-files -u one | wc -l)\" &&\n+\t\ttest 1 -eq \"$(git ls-files -u two | wc -l)\" &&\n+\n+\t\ttest_must_fail git diff --quiet &&\n+\n+\t\ttest 4 -eq $(find . | grep -v .git | wc -l) &&\n+\n+\t\ttest_path_is_dir one &&\n+\t\ttest_path_is_file one~rename-two &&\n+\t\ttest_path_is_file two &&\n+\t\ttest \"other\" = $(cat one~rename-two) &&\n+\t\ttest \"stuff\" = $(cat two)\n+\t'\n+fi\n \n test_expect_success 'pair rename to parent of other (D/F conflicts) w/ clean start' '\n \tgit reset --hard &&\n \tgit clean -fdqx &&\n \ttest_must_fail git merge --strategy=recursive rename-two &&\n \n-\ttest 2 -eq \"$(git ls-files -u | wc -l)\" &&\n-\ttest 1 -eq \"$(git ls-files -u one | wc -l)\" &&\n-\ttest 1 -eq \"$(git ls-files -u two | wc -l)\" &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\ttest 4 -eq \"$(git ls-files -u | wc -l)\" &&\n+\t\ttest 2 -eq \"$(git ls-files -u one | wc -l)\" &&\n+\t\ttest 2 -eq \"$(git ls-files -u two | wc -l)\"\n+\telse\n+\t\ttest 2 -eq \"$(git ls-files -u | wc -l)\" &&\n+\t\ttest 1 -eq \"$(git ls-files -u one | wc -l)\" &&\n+\t\ttest 1 -eq \"$(git ls-files -u two | wc -l)\"\n+\tfi &&\n \n \ttest_must_fail git diff --quiet &&\n \n@@ -572,12 +616,22 @@ test_expect_success 'check handling of differently renamed file with D/F conflic\n \tgit checkout -q first-rename^0 &&\n \ttest_must_fail git merge --strategy=recursive second-rename &&\n \n-\ttest 5 -eq \"$(git ls-files -s | wc -l)\" &&\n-\ttest 3 -eq \"$(git ls-files -u | wc -l)\" &&\n-\ttest 1 -eq \"$(git ls-files -u one | wc -l)\" &&\n-\ttest 1 -eq \"$(git ls-files -u two | wc -l)\" &&\n-\ttest 1 -eq \"$(git ls-files -u original | wc -l)\" &&\n-\ttest 2 -eq \"$(git ls-files -o | wc -l)\" &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\ttest 5 -eq \"$(git ls-files -s | wc -l)\" &&\n+\t\ttest 3 -eq \"$(git ls-files -u | wc -l)\" &&\n+\t\ttest 1 -eq \"$(git ls-files -u one~HEAD | wc -l)\" &&\n+\t\ttest 1 -eq \"$(git ls-files -u two~second-rename | wc -l)\" &&\n+\t\ttest 1 -eq \"$(git ls-files -u original | wc -l)\" &&\n+\t\ttest 0 -eq \"$(git ls-files -o | wc -l)\"\n+\telse\n+\t\ttest 5 -eq \"$(git ls-files -s | wc -l)\" &&\n+\t\ttest 3 -eq \"$(git ls-files -u | wc -l)\" &&\n+\t\ttest 1 -eq \"$(git ls-files -u one | wc -l)\" &&\n+\t\ttest 1 -eq \"$(git ls-files -u two | wc -l)\" &&\n+\t\ttest 1 -eq \"$(git ls-files -u original | wc -l)\" &&\n+\t\ttest 2 -eq \"$(git ls-files -o | wc -l)\"\n+\tfi &&\n \n \ttest_path_is_file one/file &&\n \ttest_path_is_file two/file &&\ndiff --git a/t/t6416-recursive-corner-cases.sh b/t/t6416-recursive-corner-cases.sh\nindex 8b3a4fc843..0317e83970 100755\n--- a/t/t6416-recursive-corner-cases.sh\n+++ b/t/t6416-recursive-corner-cases.sh\n@@ -538,9 +538,15 @@ test_expect_success 'setup differently handled merges of directory/file conflict\n \n \t\tgit checkout B^0 &&\n \t\ttest_must_fail git merge C^0 &&\n-\t\tgit clean -fd &&\n-\t\tgit rm -rf a/ &&\n-\t\tgit rm a &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\tgit rm -rf a/ &&\n+\t\t\tgit rm a~HEAD\n+\t\telse\n+\t\t\tgit clean -fd &&\n+\t\t\tgit rm -rf a/ &&\n+\t\t\tgit rm a\n+\t\tfi &&\n \t\tgit cat-file -p B:a >a2 &&\n \t\tgit add a2 &&\n \t\tgit commit -m D2 &&\n@@ -559,7 +565,12 @@ test_expect_success 'setup differently handled merges of directory/file conflict\n \n \t\tgit checkout C^0 &&\n \t\ttest_must_fail git merge B^0 &&\n-\t\tgit clean -fd &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\tgit rm a~B^0\n+\t\telse\n+\t\t\tgit clean -fd\n+\t\tfi &&\n \t\tgit rm -rf a/ &&\n \t\ttest_write_lines 1 2 3 4 5 6 7 8 >a &&\n \t\tgit add a &&\n@@ -568,9 +579,15 @@ test_expect_success 'setup differently handled merges of directory/file conflict\n \n \t\tgit checkout C^0 &&\n \t\ttest_must_fail git merge B^0 &&\n-\t\tgit clean -fd &&\n-\t\tgit rm -rf a/ &&\n-\t\tgit rm a &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\tgit rm -rf a/ &&\n+\t\t\tgit rm a~B^0\n+\t\telse\n+\t\t\tgit clean -fd &&\n+\t\t\tgit rm -rf a/ &&\n+\t\t\tgit rm a\n+\t\tfi &&\n \t\ttest_write_lines 1 2 3 4 5 6 7 8 >a2 &&\n \t\tgit add a2 &&\n \t\tgit commit -m E4 &&\n@@ -588,18 +605,34 @@ test_expect_success 'merge of D1 & E1 fails but has appropriate contents' '\n \n \t\ttest_must_fail git merge -s recursive E1^0 &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 2 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 1 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 1 out &&\n-\n-\t\tgit rev-parse >expect    \\\n-\t\t\tA:ignore-me  B:a &&\n-\t\tgit rev-parse   >actual   \\\n-\t\t\t:0:ignore-me :2:a &&\n-\t\ttest_cmp expect actual\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\n+\t\t\tgit rev-parse >expect    \\\n+\t\t\t\tA:ignore-me  B:a  D1:a &&\n+\t\t\tgit rev-parse   >actual   \\\n+\t\t\t\t:0:ignore-me :1:a :2:a &&\n+\t\t\ttest_cmp expect actual\n+\t\telse\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\n+\t\t\tgit rev-parse >expect    \\\n+\t\t\t\tA:ignore-me  B:a &&\n+\t\t\tgit rev-parse   >actual   \\\n+\t\t\t\t:0:ignore-me :2:a &&\n+\t\t\ttest_cmp expect actual\n+\t\tfi\n \t)\n '\n \n@@ -613,18 +646,34 @@ test_expect_success 'merge of E1 & D1 fails but has appropriate contents' '\n \n \t\ttest_must_fail git merge -s recursive D1^0 &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 2 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 1 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 1 out &&\n-\n-\t\tgit rev-parse >expect    \\\n-\t\t\tA:ignore-me  B:a &&\n-\t\tgit rev-parse   >actual   \\\n-\t\t\t:0:ignore-me :3:a &&\n-\t\ttest_cmp expect actual\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\n+\t\t\tgit rev-parse >expect    \\\n+\t\t\t\tA:ignore-me  B:a  D1:a &&\n+\t\t\tgit rev-parse   >actual   \\\n+\t\t\t\t:0:ignore-me :1:a :3:a &&\n+\t\t\ttest_cmp expect actual\n+\t\telse\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\n+\t\t\tgit rev-parse >expect    \\\n+\t\t\t\tA:ignore-me  B:a &&\n+\t\t\tgit rev-parse   >actual   \\\n+\t\t\t\t:0:ignore-me :3:a &&\n+\t\t\ttest_cmp expect actual\n+\t\tfi\n \t)\n '\n \n@@ -638,17 +687,32 @@ test_expect_success 'merge of D1 & E2 fails but has appropriate contents' '\n \n \t\ttest_must_fail git merge -s recursive E2^0 &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 4 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 3 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 2 out &&\n-\n-\t\tgit rev-parse >expect    \\\n-\t\t\tB:a   E2:a/file  C:a/file   A:ignore-me &&\n-\t\tgit rev-parse   >actual   \\\n-\t\t\t:2:a  :3:a/file  :1:a/file  :0:ignore-me &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 5 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 4 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\n+\t\t\tgit rev-parse >expect    \\\n+\t\t\t\tB:a       D1:a      E2:a/file  C:a/file   A:ignore-me &&\n+\t\t\tgit rev-parse   >actual   \\\n+\t\t\t\t:1:a~HEAD :2:a~HEAD :3:a/file  :1:a/file  :0:ignore-me\n+\t\telse\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 4 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\n+\t\t\tgit rev-parse >expect    \\\n+\t\t\t\tB:a    E2:a/file  C:a/file   A:ignore-me &&\n+\t\t\tgit rev-parse   >actual   \\\n+\t\t\t\t:2:a   :3:a/file  :1:a/file  :0:ignore-me\n+\t\tfi &&\n \t\ttest_cmp expect actual &&\n \n \t\ttest_path_is_file a~HEAD\n@@ -665,17 +729,32 @@ test_expect_success 'merge of E2 & D1 fails but has appropriate contents' '\n \n \t\ttest_must_fail git merge -s recursive D1^0 &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 4 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 3 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 2 out &&\n-\n-\t\tgit rev-parse >expect    \\\n-\t\t\tB:a   E2:a/file  C:a/file   A:ignore-me &&\n-\t\tgit rev-parse   >actual   \\\n-\t\t\t:3:a  :2:a/file  :1:a/file  :0:ignore-me &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 5 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 4 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\n+\t\t\tgit rev-parse >expect    \\\n+\t\t\t\tB:a       D1:a      E2:a/file  C:a/file   A:ignore-me &&\n+\t\t\tgit rev-parse   >actual   \\\n+\t\t\t\t:1:a~D1^0 :3:a~D1^0 :2:a/file  :1:a/file  :0:ignore-me\n+\t\telse\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 4 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\n+\t\t\tgit rev-parse >expect    \\\n+\t\t\t\tB:a   E2:a/file  C:a/file   A:ignore-me &&\n+\t\t\tgit rev-parse   >actual   \\\n+\t\t\t\t:3:a  :2:a/file  :1:a/file  :0:ignore-me\n+\t\tfi &&\n \t\ttest_cmp expect actual &&\n \n \t\ttest_path_is_file a~D1^0\ndiff --git a/t/t6422-merge-rename-corner-cases.sh b/t/t6422-merge-rename-corner-cases.sh\nindex 58729593ba..78bfaf17f0 100755\n--- a/t/t6422-merge-rename-corner-cases.sh\n+++ b/t/t6422-merge-rename-corner-cases.sh\n@@ -313,15 +313,18 @@ test_expect_success 'rename/directory conflict + clean content merge' '\n \t\tgit ls-files -u >out &&\n \t\ttest_line_count = 1 out &&\n \t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 2 out &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_line_count = 1 out\n+\t\telse\n+\t\t\ttest_line_count = 2 out\n+\t\tfi &&\n \n \t\techo 0 >expect &&\n \t\tgit cat-file -p base:file >>expect &&\n \t\techo 7 >>expect &&\n \t\ttest_cmp expect newfile~HEAD &&\n \n-\t\ttest $(git rev-parse :2:newfile) = $(git hash-object expect) &&\n-\n \t\ttest_path_is_file newfile/realfile &&\n \t\ttest_path_is_file newfile~HEAD\n \t)\n@@ -344,7 +347,12 @@ test_expect_success 'rename/directory conflict + content merge conflict' '\n \t\tgit ls-files -u >out &&\n \t\ttest_line_count = 3 out &&\n \t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 2 out &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_line_count = 1 out\n+\t\telse\n+\t\t\ttest_line_count = 2 out\n+\t\tfi &&\n \n \t\tgit cat-file -p left-conflict:newfile >left &&\n \t\tgit cat-file -p base:file    >base &&\n@@ -356,10 +364,16 @@ test_expect_success 'rename/directory conflict + content merge conflict' '\n \t\t\tleft base right &&\n \t\ttest_cmp left newfile~HEAD &&\n \n-\t\tgit rev-parse >expect                                 \\\n-\t\t\tbase:file   left-conflict:newfile  right:file &&\n-\t\tgit rev-parse >actual                                 \\\n-\t\t\t:1:newfile  :2:newfile             :3:newfile &&\n+\t\tgit rev-parse >expect   \\\n+\t\t\tbase:file       left-conflict:newfile right:file &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:1:newfile~HEAD :2:newfile~HEAD :3:newfile~HEAD\n+\t\telse\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:1:newfile      :2:newfile      :3:newfile\n+\t\tfi &&\n \t\ttest_cmp expect actual &&\n \n \t\ttest_path_is_file newfile/realfile &&\ndiff --git a/t/t6423-merge-rename-directories.sh b/t/t6423-merge-rename-directories.sh\nindex 807a424a52..5ea77564d7 100755\n--- a/t/t6423-merge-rename-directories.sh\n+++ b/t/t6423-merge-rename-directories.sh\n@@ -1177,10 +1177,18 @@ test_expect_success '5d: Directory/file/file conflict due to directory rename' '\n \t\tgit ls-files -u >out &&\n \t\ttest_line_count = 1 out &&\n \t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 2 out &&\n-\n-\t\tgit rev-parse >actual \\\n-\t\t\t:0:y/b :0:y/c :0:z/d :0:y/f :2:y/d :0:y/d/e &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_line_count = 1 out &&\n+\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t    :0:y/b :0:y/c :0:z/d :0:y/f :2:y/d~HEAD :0:y/d/e\n+\t\telse\n+\t\t\ttest_line_count = 2 out &&\n+\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t    :0:y/b :0:y/c :0:z/d :0:y/f :2:y/d      :0:y/d/e\n+\t\tfi &&\n \t\tgit rev-parse >expect \\\n \t\t\t O:z/b  O:z/c  B:z/d  B:z/f  A:y/d  B:y/d/e &&\n \t\ttest_cmp expect actual &&\n@@ -2017,17 +2025,32 @@ test_expect_success '7e: transitive rename in rename/delete AND dirs in the way'\n \t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&\n \t\ttest_i18ngrep \"CONFLICT (rename/delete).*x/d.*y/d\" out &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 5 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 1 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 2 out &&\n-\n-\t\tgit rev-parse >actual \\\n-\t\t\t:0:x/d/f :0:y/d/g :0:y/b :0:y/c :3:y/d &&\n-\t\tgit rev-parse >expect \\\n-\t\t\t A:x/d/f  A:y/d/g  O:z/b  O:z/c  O:x/d &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 6 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:x/d/f :0:y/d/g :0:y/b :0:y/c :1:y/d~B^0 :3:y/d~B^0 &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t A:x/d/f  A:y/d/g  O:z/b  O:z/c  O:x/d      O:x/d\n+\t\telse\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 5 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:x/d/f :0:y/d/g :0:y/b :0:y/c :3:y/d &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t A:x/d/f  A:y/d/g  O:z/b  O:z/c  O:x/d\n+\t\tfi &&\n \t\ttest_cmp expect actual &&\n \n \t\tgit hash-object y/d~B^0 >actual &&\ndiff --git a/t/t7610-mergetool.sh b/t/t7610-mergetool.sh\nindex ad288ddc69..70afdd06fa 100755\n--- a/t/t7610-mergetool.sh\n+++ b/t/t7610-mergetool.sh\n@@ -532,7 +532,14 @@ test_expect_success 'file vs modified submodule' '\n \tyes \"\" | git mergetool file1 file2 spaced\\ name subdir/file3 &&\n \tyes \"\" | git mergetool both &&\n \tyes \"d\" | git mergetool file11 file12 &&\n-\tyes \"l\" | git mergetool submod &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\tyes \"c\" | git mergetool submod~HEAD &&\n+\t\tgit rm submod &&\n+\t\tgit mv submod~HEAD submod\n+\telse\n+\t\tyes \"l\" | git mergetool submod\n+\tfi &&\n \tgit submodule update -N &&\n \techo \"not a submodule\" >expect &&\n \ttest_cmp expect submod &&\n@@ -549,7 +556,15 @@ test_expect_success 'file vs modified submodule' '\n \tyes \"\" | git mergetool file1 file2 spaced\\ name subdir/file3 &&\n \tyes \"\" | git mergetool both &&\n \tyes \"d\" | git mergetool file11 file12 &&\n-\tyes \"r\" | git mergetool submod &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\tmv submod submod.orig &&\n+\t\tgit rm --cached submod &&\n+\t\tyes \"c\" | git mergetool submod~test19 &&\n+\t\tgit mv submod~test19 submod\n+\telse\n+\t\tyes \"r\" | git mergetool submod\n+\tfi &&\n \ttest -d submod.orig &&\n \tgit submodule update -N &&\n \techo \"not a submodule\" >expect &&\n@@ -567,6 +582,10 @@ test_expect_success 'file vs modified submodule' '\n \tyes \"\" | git mergetool both &&\n \tyes \"d\" | git mergetool file11 file12 &&\n \tyes \"l\" | git mergetool submod &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\tyes \"d\" | git mergetool submod~test19\n+\tfi &&\n \techo \"master submodule\" >expect &&\n \ttest_cmp expect submod/bar &&\n \tgit submodule update -N &&\n@@ -664,7 +683,14 @@ test_expect_success 'directory vs modified submodule' '\n \ttest_must_fail git merge master &&\n \ttest -n \"$(git ls-files -u)\" &&\n \ttest ! -e submod.orig &&\n-\tyes \"r\" | git mergetool submod &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\tyes \"r\" | git mergetool submod~master &&\n+\t\tgit mv submod submod.orig &&\n+\t\tgit mv submod~master submod\n+\telse\n+\t\tyes \"r\" | git mergetool submod\n+\tfi &&\n \ttest -d submod.orig &&\n \techo \"not a submodule\" >expect &&\n \ttest_cmp expect submod.orig/file16 &&\n-- \ngitgitgadget\n\n"},{"id":"408251","messageId":"1eae84b7878dc6ebe7ee1fb4e860c316cd773ad5.1603468885.git.gitgitgadget@gmail.com","threadId":"54492","inReplyTo":"pull.769.git.1603468885.gitgitgadget@gmail.com","subject":"[PATCH 3/9] t6416: correct expectation for rename/rename(1to2) + directory/file","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-10-23T16:01:18Z","receivedAt":"2020-10-23T16:01:33Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nWhen files are renamed and modified, we need to do three-way content\nmerges to get the appropriate content in the right location.  When we\nhave a rename/rename(1to2) conflict (both sides rename the same file,\nbut differently), that merged content should be placed in each of the\ntwo resulting files.  merge-recursive handled that fine when that was\nall that was involved, but when one or more of the two resulting files\nwere ALSO involved in a directory/file conflict, it failed to propagate\nthe merged content to that file.  Unfortunately, the one test in t6416\nthat touched on this combination of cases had been coded to not expect\nthe merged contents to be present.\n\nFix the test to check for the right behavior, and record how the\ndifferent merge backends will be expected to handle it.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n t/t6416-recursive-corner-cases.sh | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/t/t6416-recursive-corner-cases.sh b/t/t6416-recursive-corner-cases.sh\nindex 0317e83970..887c2195a9 100755\n--- a/t/t6416-recursive-corner-cases.sh\n+++ b/t/t6416-recursive-corner-cases.sh\n@@ -786,7 +786,7 @@ test_expect_success 'merge of D1 & E3 succeeds' '\n \t)\n '\n \n-test_expect_success 'merge of D1 & E4 notifies user a and a2 are related' '\n+test_expect_merge_algorithm failure success 'merge of D1 & E4 puts merge of a and a2 in both a and a2' '\n \ttest_when_finished \"git -C directory-file reset --hard\" &&\n \ttest_when_finished \"git -C directory-file clean -fdqx\" &&\n \t(\n@@ -804,7 +804,7 @@ test_expect_success 'merge of D1 & E4 notifies user a and a2 are related' '\n \t\ttest_line_count = 1 out &&\n \n \t\tgit rev-parse >expect                  \\\n-\t\t\tA:ignore-me  B:a   D1:a  E4:a2 &&\n+\t\t\tA:ignore-me  B:a   E4:a2  E4:a2 &&\n \t\tgit rev-parse   >actual                \\\n \t\t\t:0:ignore-me :1:a~Temporary\\ merge\\ branch\\ 2  :2:a  :3:a2 &&\n \t\ttest_cmp expect actual\n-- \ngitgitgadget\n\n"},{"id":"408252","messageId":"a8d4825a323d5c1e7b2dc1edc8621c51c030ae1e.1603468885.git.gitgitgadget@gmail.com","threadId":"54492","inReplyTo":"pull.769.git.1603468885.gitgitgadget@gmail.com","subject":"[PATCH 1/9] t/: new helper for tests that pass with ort but fail with recursive","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-10-23T16:01:16Z","receivedAt":"2020-10-23T16:01:33Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nThere are a number of tests that the \"recursive\" backend does not handle\ncorrectly but which the redesign in \"ort\" will.  Add a new helper in\nlib-merge.sh for selecting a different test expectation based on the\nsetting of GIT_TEST_MERGE_ALGORITHM, and use it in various testcases to\ndocument which ones we expect to fail under recursive but pass under\nort.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n t/lib-merge.sh                         | 15 +++++++++++++++\n t/t6416-recursive-corner-cases.sh      | 11 ++++++-----\n t/t6422-merge-rename-corner-cases.sh   |  7 ++++---\n t/t6423-merge-rename-directories.sh    | 13 +++++++------\n t/t6426-merge-skip-unneeded-updates.sh |  3 ++-\n t/t6430-merge-recursive.sh             |  3 ++-\n 6 files changed, 36 insertions(+), 16 deletions(-)\n create mode 100644 t/lib-merge.sh\n\ndiff --git a/t/lib-merge.sh b/t/lib-merge.sh\nnew file mode 100644\nindex 0000000000..fac2bc5919\n--- /dev/null\n+++ b/t/lib-merge.sh\n@@ -0,0 +1,15 @@\n+# Helper functions used by merge tests.\n+\n+test_expect_merge_algorithm () {\n+\tstatus_for_recursive=$1\n+\tshift\n+\tstatus_for_ort=$1\n+\tshift\n+\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\ttest_expect_${status_for_ort} \"$@\"\n+\telse\n+\t\ttest_expect_${status_for_recursive} \"$@\"\n+\tfi\n+}\ndiff --git a/t/t6416-recursive-corner-cases.sh b/t/t6416-recursive-corner-cases.sh\nindex fd98989b14..8b3a4fc843 100755\n--- a/t/t6416-recursive-corner-cases.sh\n+++ b/t/t6416-recursive-corner-cases.sh\n@@ -3,6 +3,7 @@\n test_description='recursive merge corner cases involving criss-cross merges'\n \n . ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-merge.sh\n \n #\n #  L1  L2\n@@ -1069,7 +1070,7 @@ test_expect_success 'setup symlink modify/modify' '\n \t)\n '\n \n-test_expect_failure 'check symlink modify/modify' '\n+test_expect_merge_algorithm failure success 'check symlink modify/modify' '\n \t(\n \t\tcd symlink-modify-modify &&\n \n@@ -1135,7 +1136,7 @@ test_expect_success 'setup symlink add/add' '\n \t)\n '\n \n-test_expect_failure 'check symlink add/add' '\n+test_expect_merge_algorithm failure success 'check symlink add/add' '\n \t(\n \t\tcd symlink-add-add &&\n \n@@ -1223,7 +1224,7 @@ test_expect_success 'setup submodule modify/modify' '\n \t)\n '\n \n-test_expect_failure 'check submodule modify/modify' '\n+test_expect_merge_algorithm failure success 'check submodule modify/modify' '\n \t(\n \t\tcd submodule-modify-modify &&\n \n@@ -1311,7 +1312,7 @@ test_expect_success 'setup submodule add/add' '\n \t)\n '\n \n-test_expect_failure 'check submodule add/add' '\n+test_expect_merge_algorithm failure success 'check submodule add/add' '\n \t(\n \t\tcd submodule-add-add &&\n \n@@ -1386,7 +1387,7 @@ test_expect_success 'setup conflicting entry types (submodule vs symlink)' '\n \t)\n '\n \n-test_expect_failure 'check conflicting entry types (submodule vs symlink)' '\n+test_expect_merge_algorithm failure success 'check conflicting entry types (submodule vs symlink)' '\n \t(\n \t\tcd submodule-symlink-add-add &&\n \ndiff --git a/t/t6422-merge-rename-corner-cases.sh b/t/t6422-merge-rename-corner-cases.sh\nindex 3375eaf4e7..58729593ba 100755\n--- a/t/t6422-merge-rename-corner-cases.sh\n+++ b/t/t6422-merge-rename-corner-cases.sh\n@@ -4,6 +4,7 @@ test_description=\"recursive merge corner cases w/ renames but not criss-crosses\"\n # t6036 has corner cases that involve both criss-cross merges and renames\n \n . ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-merge.sh\n \n test_setup_rename_delete_untracked () {\n \ttest_create_repo rename-delete-untracked &&\n@@ -878,7 +879,7 @@ test_setup_rad () {\n \t)\n }\n \n-test_expect_failure 'rad-check: rename/add/delete conflict' '\n+test_expect_merge_algorithm failure success 'rad-check: rename/add/delete conflict' '\n \ttest_setup_rad &&\n \t(\n \t\tcd rad &&\n@@ -951,7 +952,7 @@ test_setup_rrdd () {\n \t)\n }\n \n-test_expect_failure 'rrdd-check: rename/rename(2to1)/delete/delete conflict' '\n+test_expect_merge_algorithm failure success 'rrdd-check: rename/rename(2to1)/delete/delete conflict' '\n \ttest_setup_rrdd &&\n \t(\n \t\tcd rrdd &&\n@@ -1040,7 +1041,7 @@ test_setup_mod6 () {\n \t)\n }\n \n-test_expect_failure 'mod6-check: chains of rename/rename(1to2) and rename/rename(2to1)' '\n+test_expect_merge_algorithm failure success 'mod6-check: chains of rename/rename(1to2) and rename/rename(2to1)' '\n \ttest_setup_mod6 &&\n \t(\n \t\tcd mod6 &&\ndiff --git a/t/t6423-merge-rename-directories.sh b/t/t6423-merge-rename-directories.sh\nindex 06b46af765..807a424a52 100755\n--- a/t/t6423-merge-rename-directories.sh\n+++ b/t/t6423-merge-rename-directories.sh\n@@ -26,6 +26,7 @@ test_description=\"recursive merge with directory renames\"\n #                     files that might be renamed into each other's paths.)\n \n . ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-merge.sh\n \n \n ###########################################################################\n@@ -1339,7 +1340,7 @@ test_setup_6b1 () {\n \t)\n }\n \n-test_expect_failure '6b1: Same renames done on both sides, plus another rename' '\n+test_expect_merge_algorithm failure success '6b1: Same renames done on both sides, plus another rename' '\n \ttest_setup_6b1 &&\n \t(\n \t\tcd 6b1 &&\n@@ -1412,7 +1413,7 @@ test_setup_6b2 () {\n \t)\n }\n \n-test_expect_failure '6b2: Same rename done on both sides' '\n+test_expect_merge_algorithm failure success '6b2: Same rename done on both sides' '\n \ttest_setup_6b2 &&\n \t(\n \t\tcd 6b2 &&\n@@ -3471,7 +3472,7 @@ test_setup_10e () {\n \t)\n }\n \n-test_expect_failure '10e: Does git complain about untracked file that is not really in the way?' '\n+test_expect_merge_algorithm failure success '10e: Does git complain about untracked file that is not really in the way?' '\n \ttest_setup_10e &&\n \t(\n \t\tcd 10e &&\n@@ -4104,7 +4105,7 @@ test_setup_12b1 () {\n \t)\n }\n \n-test_expect_failure '12b1: Moving two directory hierarchies into each other' '\n+test_expect_merge_algorithm failure success '12b1: Moving two directory hierarchies into each other' '\n \ttest_setup_12b1 &&\n \t(\n \t\tcd 12b1 &&\n@@ -4272,7 +4273,7 @@ test_setup_12c1 () {\n \t)\n }\n \n-test_expect_failure '12c1: Moving one directory hierarchy into another w/ content merge' '\n+test_expect_merge_algorithm failure success '12c1: Moving one directory hierarchy into another w/ content merge' '\n \ttest_setup_12c1 &&\n \t(\n \t\tcd 12c1 &&\n@@ -4632,7 +4633,7 @@ test_setup_12f () {\n \t)\n }\n \n-test_expect_failure '12f: Trivial directory resolve, caching, all kinds of fun' '\n+test_expect_merge_algorithm failure success '12f: Trivial directory resolve, caching, all kinds of fun' '\n \ttest_setup_12f &&\n \t(\n \t\tcd 12f &&\ndiff --git a/t/t6426-merge-skip-unneeded-updates.sh b/t/t6426-merge-skip-unneeded-updates.sh\nindex 699813671c..d7eeee4310 100755\n--- a/t/t6426-merge-skip-unneeded-updates.sh\n+++ b/t/t6426-merge-skip-unneeded-updates.sh\n@@ -23,6 +23,7 @@ test_description=\"merge cases\"\n #                     files that might be renamed into each other's paths.)\n \n . ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-merge.sh\n \n \n ###########################################################################\n@@ -666,7 +667,7 @@ test_setup_4a () {\n #   correct requires doing the merge in-memory first, then realizing that no\n #   updates to the file are necessary, and thus that we can just leave the path\n #   alone.\n-test_expect_failure '4a: Change on A, change on B subset of A, dirty mods present' '\n+test_expect_merge_algorithm failure success '4a: Change on A, change on B subset of A, dirty mods present' '\n \ttest_setup_4a &&\n \t(\n \t\tcd 4a &&\ndiff --git a/t/t6430-merge-recursive.sh b/t/t6430-merge-recursive.sh\nindex a328260d42..9c08e63af2 100755\n--- a/t/t6430-merge-recursive.sh\n+++ b/t/t6430-merge-recursive.sh\n@@ -3,6 +3,7 @@\n test_description='merge-recursive backend test'\n \n . ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-merge.sh\n \n test_expect_success 'setup 1' '\n \n@@ -641,7 +642,7 @@ test_expect_success 'merge-recursive copy vs. rename' '\n \ttest_cmp expected actual\n '\n \n-test_expect_failure 'merge-recursive rename vs. rename/symlink' '\n+test_expect_merge_algorithm failure success 'merge-recursive rename vs. rename/symlink' '\n \n \tgit checkout -f rename &&\n \tgit merge rename-ln &&\n-- \ngitgitgadget\n\n"},{"id":"408253","messageId":"554feb2aa734367bd9fcd4dd63726c985514be2a.1603468885.git.gitgitgadget@gmail.com","threadId":"54492","inReplyTo":"pull.769.git.1603468885.gitgitgadget@gmail.com","subject":"[PATCH 4/9] t6404, t6423: expect improved rename/delete handling in ort backend","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-10-23T16:01:19Z","receivedAt":"2020-10-23T16:01:38Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nWhen a file is renamed and has content conflicts, merge-recursive does\nnot have some stages for the old filename and some stages for the new\nfilename in the index; instead it copies all the stages corresponding to\nthe old filename over to the corresponding locations for the new\nfilename, so that there are three higher order stages all corresponding\nto the new filename.  Doing things this way makes it easier for the user\nto access the different versions and to resolve the conflict (no need to\nmanually 'git rm' the old version as well as 'git add' the new one).\n\nrename/deletes should be handled similarly -- there should be two stages\nfor the renamed file rather than just one.  We do not want to\ndestabilize merge-recursive right now, so instead update relevant tests\nto have different expectations depending on whether the \"recursive\" or\n\"ort\" merge strategies are in use.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n t/t6404-recursive-merge.sh          | 14 +++++-\n t/t6423-merge-rename-directories.sh | 70 ++++++++++++++++++++---------\n 2 files changed, 62 insertions(+), 22 deletions(-)\n\ndiff --git a/t/t6404-recursive-merge.sh b/t/t6404-recursive-merge.sh\nindex 332cfc53fd..b1c3d4dda4 100755\n--- a/t/t6404-recursive-merge.sh\n+++ b/t/t6404-recursive-merge.sh\n@@ -118,12 +118,22 @@ test_expect_success 'mark rename/delete as unmerged' '\n \ttest_tick &&\n \tgit commit -m rename &&\n \ttest_must_fail git merge delete &&\n-\ttest 1 = $(git ls-files --unmerged | wc -l) &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\ttest 2 = $(git ls-files --unmerged | wc -l)\n+\telse\n+\t\ttest 1 = $(git ls-files --unmerged | wc -l)\n+\tfi &&\n \tgit rev-parse --verify :2:a2 &&\n \ttest_must_fail git rev-parse --verify :3:a2 &&\n \tgit checkout -f delete &&\n \ttest_must_fail git merge rename &&\n-\ttest 1 = $(git ls-files --unmerged | wc -l) &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\ttest 2 = $(git ls-files --unmerged | wc -l)\n+\telse\n+\t\ttest 1 = $(git ls-files --unmerged | wc -l)\n+\tfi &&\n \ttest_must_fail git rev-parse --verify :2:a2 &&\n \tgit rev-parse --verify :3:a2\n '\ndiff --git a/t/t6423-merge-rename-directories.sh b/t/t6423-merge-rename-directories.sh\nindex 5ea77564d7..f9a3f24039 100755\n--- a/t/t6423-merge-rename-directories.sh\n+++ b/t/t6423-merge-rename-directories.sh\n@@ -1271,17 +1271,32 @@ test_expect_success '6a: Tricky rename/delete' '\n \t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&\n \t\ttest_i18ngrep \"CONFLICT (rename/delete).*z/c.*y/c\" out &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 2 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 1 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 1 out &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 1 out &&\n \n-\t\tgit rev-parse >actual \\\n-\t\t\t:0:y/b :3:y/c &&\n-\t\tgit rev-parse >expect \\\n-\t\t\t O:z/b  O:z/c &&\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:y/b :1:y/c :3:y/c &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t O:z/b  O:z/c  O:z/c\n+\t\telse\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:y/b :3:y/c &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t O:z/b  O:z/c\n+\t\tfi &&\n \t\ttest_cmp expect actual\n \t)\n '\n@@ -1934,17 +1949,32 @@ test_expect_success '7d: transitive rename involved in rename/delete; how is it\n \t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&\n \t\ttest_i18ngrep \"CONFLICT (rename/delete).*x/d.*y/d\" out &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 3 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 1 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 1 out &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 4 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 1 out &&\n \n-\t\tgit rev-parse >actual \\\n-\t\t\t:0:y/b :0:y/c :3:y/d &&\n-\t\tgit rev-parse >expect \\\n-\t\t\t O:z/b  O:z/c  O:x/d &&\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:y/b :0:y/c :1:y/d :3:y/d &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t O:z/b  O:z/c  O:x/d  O:x/d\n+\t\telse\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:y/b :0:y/c :3:y/d &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t O:z/b  O:z/c  O:x/d\n+\t\tfi &&\n \t\ttest_cmp expect actual\n \t)\n '\n-- \ngitgitgadget\n\n"},{"id":"408254","messageId":"5bead7fa0d8d11f9587818e49b3e867f64e5a7b7.1603468885.git.gitgitgadget@gmail.com","threadId":"54492","inReplyTo":"pull.769.git.1603468885.gitgitgadget@gmail.com","subject":"[PATCH 5/9] t6423: expect improved conflict markers labels in the ort backend","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-10-23T16:01:20Z","receivedAt":"2020-10-23T16:01:39Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nConflict markers carry an extra annotation of the form\n   REF-OR-COMMIT:FILENAME\nto help distinguish where the content is coming from, with the :FILENAME\npiece being left off if it is the same for both sides of history (thus\nonly renames with content conflicts carry that part of the annotation).\nHowever, there were cases where the :FILENAME annotation was\naccidentally left off, due to merge-recursive's\nevery-codepath-needs-a-copy-of-all-special-case-code format.\n\nUpdate a few tests to have the correct :FILENAME extension on relevant\npaths with the ort backend, while leaving the expectation for\nmerge-recursive the same to avoid destabilizing it.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n t/t6423-merge-rename-directories.sh | 38 +++++++++++++++++++++--------\n 1 file changed, 28 insertions(+), 10 deletions(-)\n\ndiff --git a/t/t6423-merge-rename-directories.sh b/t/t6423-merge-rename-directories.sh\nindex f9a3f24039..7e32626913 100755\n--- a/t/t6423-merge-rename-directories.sh\n+++ b/t/t6423-merge-rename-directories.sh\n@@ -302,11 +302,20 @@ test_expect_success '1d: Directory renames cause a rename/rename(2to1) conflict'\n \t\tgit cat-file -p :2:x/wham >expect &&\n \t\tgit cat-file -p :3:x/wham >other &&\n \t\t>empty &&\n-\t\ttest_must_fail git merge-file \\\n-\t\t\t-L \"HEAD\" \\\n-\t\t\t-L \"\" \\\n-\t\t\t-L \"B^0\" \\\n-\t\t\texpect empty other &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_must_fail git merge-file \\\n+\t\t\t\t-L \"HEAD:y/wham\" \\\n+\t\t\t\t-L \"\" \\\n+\t\t\t\t-L \"B^0:z/wham\" \\\n+\t\t\t\texpect empty other\n+\t\telse\n+\t\t\ttest_must_fail git merge-file \\\n+\t\t\t\t-L \"HEAD\" \\\n+\t\t\t\t-L \"\" \\\n+\t\t\t\t-L \"B^0\" \\\n+\t\t\t\texpect empty other\n+\t\tfi &&\n \t\ttest_cmp expect x/wham\n \t)\n '\n@@ -1823,11 +1832,20 @@ test_expect_success '7b: rename/rename(2to1), but only due to transitive rename'\n \t\tgit cat-file -p :2:y/d >expect &&\n \t\tgit cat-file -p :3:y/d >other &&\n \t\t>empty &&\n-\t\ttest_must_fail git merge-file \\\n-\t\t\t-L \"HEAD\" \\\n-\t\t\t-L \"\" \\\n-\t\t\t-L \"B^0\" \\\n-\t\t\texpect empty other &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_must_fail git merge-file \\\n+\t\t\t\t-L \"HEAD:y/d\" \\\n+\t\t\t\t-L \"\" \\\n+\t\t\t\t-L \"B^0:z/d\" \\\n+\t\t\t\texpect empty other\n+\t\telse\n+\t\t\ttest_must_fail git merge-file \\\n+\t\t\t\t-L \"HEAD\" \\\n+\t\t\t\t-L \"\" \\\n+\t\t\t\t-L \"B^0\" \\\n+\t\t\t\texpect empty other\n+\t\tfi &&\n \t\ttest_cmp expect y/d\n \t)\n '\n-- \ngitgitgadget\n\n"},{"id":"408255","messageId":"2aa44c1f13ac1fd70167770f7749611eadc396d4.1603468885.git.gitgitgadget@gmail.com","threadId":"54492","inReplyTo":"pull.769.git.1603468885.gitgitgadget@gmail.com","subject":"[PATCH 6/9] merge tests: expect slight differences in output for recursive vs. ort","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-10-23T16:01:21Z","receivedAt":"2020-10-23T16:01:41Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nThe ort merge strategy has some slight differences in commit\ndescriptions (shortened hashes), stdout vs stderr, and in conflict\nmessages.  Also, builtin/merge.c reports usage of \"ort\" as \"Merge made\nby the 'ort' strategy\" -- while it is meant as a drop in replacement for\n\"recursive\" it is not yet treated as though it is recursive.  Update the\ntestcases to expect different output for the different merge backends.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n t/t6402-merge-rename.sh       | 14 ++++++++++++--\n t/t6437-submodule-merge.sh    | 25 +++++++++++++++++++++----\n t/t7602-merge-octopus-many.sh |  4 ++++\n 3 files changed, 37 insertions(+), 6 deletions(-)\n\ndiff --git a/t/t6402-merge-rename.sh b/t/t6402-merge-rename.sh\nindex 47d4434d64..3f64f62224 100755\n--- a/t/t6402-merge-rename.sh\n+++ b/t/t6402-merge-rename.sh\n@@ -320,7 +320,12 @@ test_expect_success 'Rename+D/F conflict; renamed file merges but dir in way' '\n \n \ttest_i18ngrep \"CONFLICT (modify/delete): dir/file-in-the-way\" output &&\n \ttest_i18ngrep \"Auto-merging dir\" output &&\n-\ttest_i18ngrep \"Adding as dir~HEAD instead\" output &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\ttest_i18ngrep \"moving it to dir~HEAD instead\" output\n+\telse\n+\t\ttest_i18ngrep \"Adding as dir~HEAD instead\" output\n+\tfi &&\n \n \ttest 3 -eq \"$(git ls-files -u | wc -l)\" &&\n \ttest 2 -eq \"$(git ls-files -u dir/file-in-the-way | wc -l)\" &&\n@@ -342,7 +347,12 @@ test_expect_success 'Same as previous, but merged other way' '\n \t! grep \"error: refusing to lose untracked file at\" errors &&\n \ttest_i18ngrep \"CONFLICT (modify/delete): dir/file-in-the-way\" output &&\n \ttest_i18ngrep \"Auto-merging dir\" output &&\n-\ttest_i18ngrep \"Adding as dir~renamed-file-has-no-conflicts instead\" output &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\ttest_i18ngrep \"moving it to dir~renamed-file-has-no-conflicts instead\" output\n+\telse\n+\t\ttest_i18ngrep \"Adding as dir~renamed-file-has-no-conflicts instead\" output\n+\tfi &&\n \n \ttest 3 -eq \"$(git ls-files -u | wc -l)\" &&\n \ttest 2 -eq \"$(git ls-files -u dir/file-in-the-way | wc -l)\" &&\ndiff --git a/t/t6437-submodule-merge.sh b/t/t6437-submodule-merge.sh\nindex 6a1e5f8232..3ead2b726f 100755\n--- a/t/t6437-submodule-merge.sh\n+++ b/t/t6437-submodule-merge.sh\n@@ -127,7 +127,12 @@ test_expect_success 'merging should conflict for non fast-forward' '\n \t git checkout -b test-nonforward b &&\n \t (cd sub &&\n \t  git rev-parse sub-d > ../expect) &&\n-\t test_must_fail git merge c 2> actual  &&\n+\t  if test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t  then\n+\t\ttest_must_fail git merge c >actual\n+\t  else\n+\t\ttest_must_fail git merge c 2> actual\n+\t  fi &&\n \t grep $(cat expect) actual > /dev/null &&\n \t git reset --hard)\n '\n@@ -138,9 +143,21 @@ test_expect_success 'merging should fail for ambiguous common parent' '\n \t(cd sub &&\n \t git checkout -b ambiguous sub-b &&\n \t git merge sub-c &&\n-\t git rev-parse sub-d > ../expect1 &&\n-\t git rev-parse ambiguous > ../expect2) &&\n-\ttest_must_fail git merge c 2> actual &&\n+\t if test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t then\n+\t\tgit rev-parse --short sub-d >../expect1 &&\n+\t\tgit rev-parse --short ambiguous >../expect2\n+\t else\n+\t\tgit rev-parse sub-d > ../expect1 &&\n+\t\tgit rev-parse ambiguous > ../expect2\n+\t fi\n+\t ) &&\n+\t if test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t then\n+\t\ttest_must_fail git merge c >actual\n+\t else\n+\t\ttest_must_fail git merge c 2> actual\n+\t fi &&\n \tgrep $(cat expect1) actual > /dev/null &&\n \tgrep $(cat expect2) actual > /dev/null &&\n \tgit reset --hard)\ndiff --git a/t/t7602-merge-octopus-many.sh b/t/t7602-merge-octopus-many.sh\nindex 6abe441ae3..b205b5619e 100755\n--- a/t/t7602-merge-octopus-many.sh\n+++ b/t/t7602-merge-octopus-many.sh\n@@ -77,6 +77,10 @@ Merge made by the 'recursive' strategy.\n EOF\n \n test_expect_success 'merge reduces irrelevant remote heads' '\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\tsed -i'' s/recursive/ort/ expected\n+\tfi &&\n \tGIT_MERGE_VERBOSITY=0 git merge c4 c5 >actual &&\n \ttest_i18ncmp expected actual\n '\n-- \ngitgitgadget\n\n"},{"id":"408256","messageId":"2659d1cb987735ec123ca7a82ed7e058e4d6bef0.1603468885.git.gitgitgadget@gmail.com","threadId":"54492","inReplyTo":"pull.769.git.1603468885.gitgitgadget@gmail.com","subject":"[PATCH 9/9] t6423: add more details about direct resolution of directories","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-10-23T16:01:24Z","receivedAt":"2020-10-23T16:01:44Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n t/t6423-merge-rename-directories.sh | 37 ++++++++++++++++-------------\n 1 file changed, 21 insertions(+), 16 deletions(-)\n\ndiff --git a/t/t6423-merge-rename-directories.sh b/t/t6423-merge-rename-directories.sh\nindex db694a6316..9e51320ee0 100755\n--- a/t/t6423-merge-rename-directories.sh\n+++ b/t/t6423-merge-rename-directories.sh\n@@ -4725,20 +4725,22 @@ test_expect_success '12e: Rename/merge subdir into the root, variant 2' '\n #              folder/subdir/newsubdir/e_Merge2\n #              folder/subdir/tweaked/{h,Makefile_SUB_Merge1,newfile.py}\n #              folder/unchanged/<LOTS OF FILES>\n-#\n-# Notes: This testcase happens to exercise lots of the\n-#        optimization-specific codepaths in merge-ort, and also\n-#        demonstrated a failing of the directory rename detection algorithm\n-#        in merge-recursive; newfile.c should not get pushed into\n-#        folder/subdir/newsubdir/, yet merge-recursive put it there because\n-#        the rename of dir/subdir/{a,b,c,d} -> folder/subdir/{a,b,c,d}\n-#        looks like\n-#            dir/ -> folder/,\n-#        whereas the rename of dir/subdir/e -> folder/subdir/newsubdir/e\n-#        looks like\n-#            dir/subdir/ -> folder/subdir/newsubdir/\n-#        and if we note that newfile.c is found in dir/subdir/, we might\n-#        overlook the dir/ -> folder/ rule that has more weight.\n+# Things being checked here:\n+#   1. dir/subdir/newfile.c does not get pushed into folder/subdir/newsubdir/.\n+#      dir/subdir/{a,b,c,d} -> folder/subdir/{a,b,c,d} looks like\n+#          dir/ -> folder/,\n+#      whereas dir/subdir/e -> folder/subdir/newsubdir/e looks like\n+#          dir/subdir/ -> folder/subdir/newsubdir/\n+#      and if we note that newfile.c is found in dir/subdir/, we might overlook\n+#      the dir/ -> folder/ rule that has more weight.  Older git versions did\n+#      this.\n+#   2. The code to do trivial directory resolves.  Note that\n+#      dir/subdir/unchanged/ is unchanged and can be deleted, and files in the\n+#      new folder/subdir/unchanged/ are not needed as a target to any renames.\n+#      Thus, in the second collect_merge_info_callback() we can just resolve\n+#      these two directories trivially without recursing.)\n+#   3. Exercising the codepaths for caching renames and deletes from one cherry\n+#      pick and re-applying them in the subsequent one.\n \n test_setup_12f () {\n \ttest_create_repo 12f &&\n@@ -4803,7 +4805,7 @@ test_expect_merge_algorithm failure success '12f: Trivial directory resolve, cac\n \t\tgit checkout A^0 &&\n \t\tgit branch Bmod B &&\n \n-\t\tgit -c merge.directoryRenames=true rebase A Bmod &&\n+\t\tGIT_TRACE2_PERF=\"$(pwd)/trace.output\" git -c merge.directoryRenames=true rebase A Bmod &&\n \n \t\techo Checking the pick of B1... &&\n \n@@ -4884,7 +4886,10 @@ test_expect_merge_algorithm failure success '12f: Trivial directory resolve, cac\n \t\ttest_seq  2 12 >e_Merge2 &&\n \t\tgit hash-object e_Merge2 >expect &&\n \t\tgit rev-parse Bmod:folder/subdir/newsubdir/e >actual &&\n-\t\ttest_cmp expect actual\n+\t\ttest_cmp expect actual &&\n+\n+\t\tgrep region_enter.*collect_merge_info trace.output >collect &&\n+\t\ttest_line_count = 4 collect\n \t)\n '\n \n-- \ngitgitgadget\n"},{"id":"408257","messageId":"9d46cc1ef3dbc863c48a446f40419470b1bad5a3.1603468885.git.gitgitgadget@gmail.com","threadId":"54492","inReplyTo":"pull.769.git.1603468885.gitgitgadget@gmail.com","subject":"[PATCH 7/9] t6423, t6436: note improved ort handling with dirty files","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-10-23T16:01:22Z","receivedAt":"2020-10-23T16:01:45Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nThe \"recursive\" backend relies on unpack_trees() to check if unstaged\nchanges would be overwritten by a merge, but unpack_trees() does not\nunderstand renames -- and once it returns, it has already written many\nupdates to the working tree and index.  As such, \"recursive\" had to do a\nspecial 4-way merge where it would need to also treat the working copy\nas an extra source of differences that we had to carefully avoid\noverwriting and resulting in moving files to new locations to avoid\nconflicts.\n\nThe \"ort\" backend, by contrast, does the complete merge inmemory, and\nonly updates the index and working copy as a post-processing step.  If\nthere are dirty files in the way, it can simply abort the merge.\n\nUpdate t6423 and t6436 to reflect the better merge abilities and\nexpectations we have for ort, while still leaving the\nbest-case-as-good-as-recursive-can-do expectations there for the\nrecursive backend so we retain its stability until we are ready to\ndeprecate and remove it.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n t/t6423-merge-rename-directories.sh | 266 ++++++++++++++++------------\n t/t6436-merge-overwrite.sh          |  18 +-\n 2 files changed, 165 insertions(+), 119 deletions(-)\n\ndiff --git a/t/t6423-merge-rename-directories.sh b/t/t6423-merge-rename-directories.sh\nindex 7e32626913..32e6925ca4 100755\n--- a/t/t6423-merge-rename-directories.sh\n+++ b/t/t6423-merge-rename-directories.sh\n@@ -3634,28 +3634,35 @@ test_expect_success '11a: Avoid losing dirty contents with simple rename' '\n \t\techo stuff >>z/c &&\n \n \t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&\n-\t\ttest_i18ngrep \"Refusing to lose dirty file at z/c\" out &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_path_is_missing .git/MERGE_HEAD &&\n+\t\t\ttest_i18ngrep \"error: Your local changes to the following files would be overwritten by merge\" err\n+\t\telse\n+\t\t\ttest_i18ngrep \"Refusing to lose dirty file at z/c\" out &&\n \n-\t\ttest_seq 1 10 >expected &&\n-\t\techo stuff >>expected &&\n-\t\ttest_cmp expected z/c &&\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 3 out &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 2 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 1 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 4 out &&\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:z/a :2:z/c &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t O:z/a  B:z/b &&\n+\t\t\ttest_cmp expect actual &&\n \n-\t\tgit rev-parse >actual \\\n-\t\t\t:0:z/a :2:z/c &&\n-\t\tgit rev-parse >expect \\\n-\t\t\t O:z/a  B:z/b &&\n-\t\ttest_cmp expect actual &&\n+\t\t\tgit hash-object z/c~HEAD >actual &&\n+\t\t\tgit rev-parse B:z/b >expect &&\n+\t\t\ttest_cmp expect actual\n+\t\tfi &&\n+\n+\t\ttest_seq 1 10 >expected &&\n+\t\techo stuff >>expected &&\n+\t\ttest_cmp expected z/c\n \n-\t\tgit hash-object z/c~HEAD >actual &&\n-\t\tgit rev-parse B:z/b >expect &&\n-\t\ttest_cmp expect actual\n \t)\n '\n \n@@ -3706,32 +3713,39 @@ test_expect_success '11b: Avoid losing dirty file involved in directory rename'\n \t\tgit checkout A^0 &&\n \t\techo stuff >>z/c &&\n \n-\t\tgit -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&\n-\t\ttest_i18ngrep \"Refusing to lose dirty file at z/c\" out &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&\n+\t\t\ttest_path_is_missing .git/MERGE_HEAD &&\n+\t\t\ttest_i18ngrep \"error: Your local changes to the following files would be overwritten by merge\" err\n+\t\telse\n+\t\t\tgit -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&\n+\t\t\ttest_i18ngrep \"Refusing to lose dirty file at z/c\" out &&\n \n-\t\tgrep -q stuff z/c &&\n-\t\ttest_seq 1 10 >expected &&\n-\t\techo stuff >>expected &&\n-\t\ttest_cmp expected z/c &&\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 0 out &&\n+\t\t\tgit ls-files -m >out &&\n+\t\t\ttest_line_count = 0 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 3 out &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 3 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 0 out &&\n-\t\tgit ls-files -m >out &&\n-\t\ttest_line_count = 0 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 4 out &&\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:x/b :0:y/a :0:y/c &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t O:x/b  O:z/a  B:x/c &&\n+\t\t\ttest_cmp expect actual &&\n \n-\t\tgit rev-parse >actual \\\n-\t\t\t:0:x/b :0:y/a :0:y/c &&\n-\t\tgit rev-parse >expect \\\n-\t\t\t O:x/b  O:z/a  B:x/c &&\n-\t\ttest_cmp expect actual &&\n+\t\t\tgit hash-object y/c >actual &&\n+\t\t\tgit rev-parse B:x/c >expect &&\n+\t\t\ttest_cmp expect actual\n+\t\tfi &&\n \n-\t\tgit hash-object y/c >actual &&\n-\t\tgit rev-parse B:x/c >expect &&\n-\t\ttest_cmp expect actual\n+\t\tgrep -q stuff z/c &&\n+\t\ttest_seq 1 10 >expected &&\n+\t\techo stuff >>expected &&\n+\t\ttest_cmp expected z/c\n \t)\n '\n \n@@ -3783,7 +3797,13 @@ test_expect_success '11c: Avoid losing not-uptodate with rename + D/F conflict'\n \t\techo stuff >>y/c &&\n \n \t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&\n-\t\ttest_i18ngrep \"following files would be overwritten by merge\" err &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_path_is_missing .git/MERGE_HEAD &&\n+\t\t\ttest_i18ngrep \"error: Your local changes to the following files would be overwritten by merge\" err\n+\t\telse\n+\t\t\ttest_i18ngrep \"following files would be overwritten by merge\" err\n+\t\tfi &&\n \n \t\tgrep -q stuff y/c &&\n \t\ttest_seq 1 10 >expected &&\n@@ -3851,29 +3871,35 @@ test_expect_success '11d: Avoid losing not-uptodate with rename + D/F conflict'\n \t\techo stuff >>z/c &&\n \n \t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&\n-\t\ttest_i18ngrep \"Refusing to lose dirty file at z/c\" out &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_path_is_missing .git/MERGE_HEAD &&\n+\t\t\ttest_i18ngrep \"error: Your local changes to the following files would be overwritten by merge\" err\n+\t\telse\n+\t\t\ttest_i18ngrep \"Refusing to lose dirty file at z/c\" out &&\n \n-\t\tgrep -q stuff z/c &&\n-\t\ttest_seq 1 10 >expected &&\n-\t\techo stuff >>expected &&\n-\t\ttest_cmp expected z/c &&\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 4 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 4 out &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 4 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 1 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 5 out &&\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:x/b :0:y/a :0:y/c/d :3:y/c &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t O:x/b  O:z/a  B:y/c/d  B:x/c &&\n+\t\t\ttest_cmp expect actual &&\n \n-\t\tgit rev-parse >actual \\\n-\t\t\t:0:x/b :0:y/a :0:y/c/d :3:y/c &&\n-\t\tgit rev-parse >expect \\\n-\t\t\t O:x/b  O:z/a  B:y/c/d  B:x/c &&\n-\t\ttest_cmp expect actual &&\n+\t\t\tgit hash-object y/c~HEAD >actual &&\n+\t\t\tgit rev-parse B:x/c >expect &&\n+\t\t\ttest_cmp expect actual\n+\t\tfi &&\n \n-\t\tgit hash-object y/c~HEAD >actual &&\n-\t\tgit rev-parse B:x/c >expect &&\n-\t\ttest_cmp expect actual\n+\t\tgrep -q stuff z/c &&\n+\t\ttest_seq 1 10 >expected &&\n+\t\techo stuff >>expected &&\n+\t\ttest_cmp expected z/c\n \t)\n '\n \n@@ -3931,37 +3957,43 @@ test_expect_success '11e: Avoid deleting not-uptodate with dir rename/rename(1to\n \t\techo mods >>y/c &&\n \n \t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&\n-\t\ttest_i18ngrep \"CONFLICT (rename/rename)\" out &&\n-\t\ttest_i18ngrep \"Refusing to lose dirty file at y/c\" out &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_path_is_missing .git/MERGE_HEAD &&\n+\t\t\ttest_i18ngrep \"error: Your local changes to the following files would be overwritten by merge\" err\n+\t\telse\n+\t\t\ttest_i18ngrep \"CONFLICT (rename/rename)\" out &&\n+\t\t\ttest_i18ngrep \"Refusing to lose dirty file at y/c\" out &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 7 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 4 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 7 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 4 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 3 out &&\n+\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:y/a :0:y/b :0:x/d :1:x/c :2:w/c :2:y/c :3:y/c &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t O:z/a  O:z/b  O:x/d  O:x/c  O:x/c  A:y/c  O:x/c &&\n+\t\t\ttest_cmp expect actual &&\n+\n+\t\t\t# See if y/c~merged has expected contents; requires manually\n+\t\t\t# doing the expected file merge\n+\t\t\tgit cat-file -p A:y/c >c1 &&\n+\t\t\tgit cat-file -p B:z/c >c2 &&\n+\t\t\t>empty &&\n+\t\t\ttest_must_fail git merge-file \\\n+\t\t\t\t-L \"HEAD\" \\\n+\t\t\t\t-L \"\" \\\n+\t\t\t\t-L \"B^0\" \\\n+\t\t\t\tc1 empty c2 &&\n+\t\t\ttest_cmp c1 y/c~merged\n+\t\tfi &&\n \n \t\techo different >expected &&\n \t\techo mods >>expected &&\n-\t\ttest_cmp expected y/c &&\n-\n-\t\tgit rev-parse >actual \\\n-\t\t\t:0:y/a :0:y/b :0:x/d :1:x/c :2:w/c :2:y/c :3:y/c &&\n-\t\tgit rev-parse >expect \\\n-\t\t\t O:z/a  O:z/b  O:x/d  O:x/c  O:x/c  A:y/c  O:x/c &&\n-\t\ttest_cmp expect actual &&\n-\n-\t\t# See if y/c~merged has expected contents; requires manually\n-\t\t# doing the expected file merge\n-\t\tgit cat-file -p A:y/c >c1 &&\n-\t\tgit cat-file -p B:z/c >c2 &&\n-\t\t>empty &&\n-\t\ttest_must_fail git merge-file \\\n-\t\t\t-L \"HEAD\" \\\n-\t\t\t-L \"\" \\\n-\t\t\t-L \"B^0\" \\\n-\t\t\tc1 empty c2 &&\n-\t\ttest_cmp c1 y/c~merged\n+\t\ttest_cmp expected y/c\n \t)\n '\n \n@@ -4014,38 +4046,44 @@ test_expect_success '11f: Avoid deleting not-uptodate with dir rename/rename(2to\n \t\techo important >>y/wham &&\n \n \t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&\n-\t\ttest_i18ngrep \"CONFLICT (rename/rename)\" out &&\n-\t\ttest_i18ngrep \"Refusing to lose dirty file at y/wham\" out &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_path_is_missing .git/MERGE_HEAD &&\n+\t\t\ttest_i18ngrep \"error: Your local changes to the following files would be overwritten by merge\" err\n+\t\telse\n+\t\t\ttest_i18ngrep \"CONFLICT (rename/rename)\" out &&\n+\t\t\ttest_i18ngrep \"Refusing to lose dirty file at y/wham\" out &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 4 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 2 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 4 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 3 out &&\n \n-\t\ttest_seq 1 10 >expected &&\n-\t\techo important >>expected &&\n-\t\ttest_cmp expected y/wham &&\n+\t\t\ttest_must_fail git rev-parse :1:y/wham &&\n \n-\t\ttest_must_fail git rev-parse :1:y/wham &&\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:y/a :0:y/b :2:y/wham :3:y/wham &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t O:z/a  O:z/b  O:x/c     O:x/d &&\n+\t\t\ttest_cmp expect actual &&\n \n-\t\tgit rev-parse >actual \\\n-\t\t\t:0:y/a :0:y/b :2:y/wham :3:y/wham &&\n-\t\tgit rev-parse >expect \\\n-\t\t\t O:z/a  O:z/b  O:x/c     O:x/d &&\n-\t\ttest_cmp expect actual &&\n+\t\t\t# Test that two-way merge in y/wham~merged is as expected\n+\t\t\tgit cat-file -p :2:y/wham >expect &&\n+\t\t\tgit cat-file -p :3:y/wham >other &&\n+\t\t\t>empty &&\n+\t\t\ttest_must_fail git merge-file \\\n+\t\t\t\t-L \"HEAD\" \\\n+\t\t\t\t-L \"\" \\\n+\t\t\t\t-L \"B^0\" \\\n+\t\t\t\texpect empty other &&\n+\t\t\ttest_cmp expect y/wham~merged\n+\t\tfi &&\n \n-\t\t# Test that the two-way merge in y/wham~merged is as expected\n-\t\tgit cat-file -p :2:y/wham >expect &&\n-\t\tgit cat-file -p :3:y/wham >other &&\n-\t\t>empty &&\n-\t\ttest_must_fail git merge-file \\\n-\t\t\t-L \"HEAD\" \\\n-\t\t\t-L \"\" \\\n-\t\t\t-L \"B^0\" \\\n-\t\t\texpect empty other &&\n-\t\ttest_cmp expect y/wham~merged\n+\t\ttest_seq 1 10 >expected &&\n+\t\techo important >>expected &&\n+\t\ttest_cmp expected y/wham\n \t)\n '\n \ndiff --git a/t/t6436-merge-overwrite.sh b/t/t6436-merge-overwrite.sh\nindex dd8ab7ede1..dd9376842f 100755\n--- a/t/t6436-merge-overwrite.sh\n+++ b/t/t6436-merge-overwrite.sh\n@@ -97,11 +97,19 @@ test_expect_success 'will not overwrite unstaged changes in renamed file' '\n \tgit mv c1.c other.c &&\n \tgit commit -m rename &&\n \tcp important other.c &&\n-\ttest_must_fail git merge c1a >out &&\n-\ttest_i18ngrep \"Refusing to lose dirty file at other.c\" out &&\n-\ttest_path_is_file other.c~HEAD &&\n-\ttest $(git hash-object other.c~HEAD) = $(git rev-parse c1a:c1.c) &&\n-\ttest_cmp important other.c\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\ttest_must_fail git merge c1a >out 2>err &&\n+\t\ttest_i18ngrep \"would be overwritten by merge\" err &&\n+\t\ttest_cmp important other.c &&\n+\t\ttest_path_is_missing .git/MERGE_HEAD\n+\telse\n+\t\ttest_must_fail git merge c1a >out &&\n+\t\ttest_i18ngrep \"Refusing to lose dirty file at other.c\" out &&\n+\t\ttest_path_is_file other.c~HEAD &&\n+\t\ttest $(git hash-object other.c~HEAD) = $(git rev-parse c1a:c1.c) &&\n+\t\ttest_cmp important other.c\n+\tfi\n '\n \n test_expect_success 'will not overwrite untracked subtree' '\n-- \ngitgitgadget\n\n"},{"id":"408258","messageId":"436577106e6ad079ece200fc318acab9262f6ce7.1603468885.git.gitgitgadget@gmail.com","threadId":"54492","inReplyTo":"pull.769.git.1603468885.gitgitgadget@gmail.com","subject":"[PATCH 8/9] t6423: note improved ort handling with untracked files","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-10-23T16:01:23Z","receivedAt":"2020-10-23T16:01:45Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nSimilar to the previous commit, since the \"recursive\" backend relies on\nunpack_trees() to check if unstaged or untracked files would be\noverwritten by a merge, and unpack_trees() does not understand renames\n-- it has false positives and false negatives.  Once it has run, since\nit updates as it goes, merge-recursive then has to handle completing the\nmerge as best it can despite extra changes in the working copy.\nHowever, this is not just an issue for dirty files, but also for\nuntracked files because directory renames can cause file contents to\nneed to be written to a location that was not tracked on either side of\nhistory.\n\nSince the \"ort\" backend does the complete merge inmemory, and only\nupdates the index and working copy as a post-processing step, if there\nare untracked files in the way it can simply abort the merge much like\ncheckout does.\n\nUpdate t6423 to reflect the better merge abilities and expectations for\nort, while still leaving the best-case-as-good-as-recursive-can-do\nexpectations there for the recursive backend so we retain its stability\nuntil we are ready to deprecate and remove it.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n t/t6423-merge-rename-directories.sh | 195 ++++++++++++++++++----------\n 1 file changed, 124 insertions(+), 71 deletions(-)\n\ndiff --git a/t/t6423-merge-rename-directories.sh b/t/t6423-merge-rename-directories.sh\nindex 32e6925ca4..db694a6316 100755\n--- a/t/t6423-merge-rename-directories.sh\n+++ b/t/t6423-merge-rename-directories.sh\n@@ -3214,6 +3214,7 @@ test_expect_success '10a: Overwrite untracked with normal rename/delete' '\n \t\techo important >z/d &&\n \n \t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&\n+\t\ttest_path_is_missing .git/MERGE_HEAD &&\n \t\ttest_i18ngrep \"The following untracked working tree files would be overwritten by merge\" err &&\n \n \t\tgit ls-files -s >out &&\n@@ -3283,21 +3284,34 @@ test_expect_success '10b: Overwrite untracked with dir rename + delete' '\n \t\techo contents >y/e &&\n \n \t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&\n-\t\ttest_i18ngrep \"CONFLICT (rename/delete).*Version B\\^0 of y/d left in tree at y/d~B\\^0\" out &&\n-\t\ttest_i18ngrep \"Error: Refusing to lose untracked file at y/e; writing to y/e~B\\^0 instead\" out &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_path_is_missing .git/MERGE_HEAD &&\n+\t\t\ttest_i18ngrep \"error: The following untracked working tree files would be overwritten by merge\" err &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 3 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 2 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 5 out &&\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 0 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 5 out\n+\t\telse\n+\t\t\ttest_i18ngrep \"CONFLICT (rename/delete).*Version B\\^0 of y/d left in tree at y/d~B\\^0\" out &&\n+\t\t\ttest_i18ngrep \"Error: Refusing to lose untracked file at y/e; writing to y/e~B\\^0 instead\" out &&\n \n-\t\tgit rev-parse >actual \\\n-\t\t\t:0:y/b :3:y/d :3:y/e &&\n-\t\tgit rev-parse >expect \\\n-\t\t\tO:z/b  O:z/c  B:z/e &&\n-\t\ttest_cmp expect actual &&\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 5 out &&\n+\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:y/b :3:y/d :3:y/e &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\tO:z/b  O:z/c  B:z/e &&\n+\t\t\ttest_cmp expect actual\n+\t\tfi &&\n \n \t\techo very >expect &&\n \t\ttest_cmp expect y/c &&\n@@ -3360,25 +3374,38 @@ test_expect_success '10c1: Overwrite untracked with dir rename/rename(1to2)' '\n \t\techo important >y/c &&\n \n \t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&\n-\t\ttest_i18ngrep \"CONFLICT (rename/rename)\" out &&\n-\t\ttest_i18ngrep \"Refusing to lose untracked file at y/c; adding as y/c~B\\^0 instead\" out &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_path_is_missing .git/MERGE_HEAD &&\n+\t\t\ttest_i18ngrep \"error: The following untracked working tree files would be overwritten by merge\" err &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 6 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 3 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 4 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 0 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 3 out\n+\t\telse\n+\t\t\ttest_i18ngrep \"CONFLICT (rename/rename)\" out &&\n+\t\t\ttest_i18ngrep \"Refusing to lose untracked file at y/c; adding as y/c~B\\^0 instead\" out &&\n \n-\t\tgit rev-parse >actual \\\n-\t\t\t:0:y/a :0:y/b :0:x/d :1:x/c :2:w/c :3:y/c &&\n-\t\tgit rev-parse >expect \\\n-\t\t\t O:z/a  O:z/b  O:x/d  O:x/c  O:x/c  O:x/c &&\n-\t\ttest_cmp expect actual &&\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 6 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 3 out &&\n \n-\t\tgit hash-object y/c~B^0 >actual &&\n-\t\tgit rev-parse O:x/c >expect &&\n-\t\ttest_cmp expect actual &&\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:y/a :0:y/b :0:x/d :1:x/c :2:w/c :3:y/c &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t O:z/a  O:z/b  O:x/d  O:x/c  O:x/c  O:x/c &&\n+\t\t\ttest_cmp expect actual &&\n+\n+\t\t\tgit hash-object y/c~B^0 >actual &&\n+\t\t\tgit rev-parse O:x/c >expect &&\n+\t\t\ttest_cmp expect actual\n+\t\tfi &&\n \n \t\techo important >expect &&\n \t\ttest_cmp expect y/c\n@@ -3398,25 +3425,38 @@ test_expect_success '10c2: Overwrite untracked with dir rename/rename(1to2), oth\n \t\techo important >y/c &&\n \n \t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive A^0 >out 2>err &&\n-\t\ttest_i18ngrep \"CONFLICT (rename/rename)\" out &&\n-\t\ttest_i18ngrep \"Refusing to lose untracked file at y/c; adding as y/c~HEAD instead\" out &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_path_is_missing .git/MERGE_HEAD &&\n+\t\t\ttest_i18ngrep \"error: The following untracked working tree files would be overwritten by merge\" err &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 6 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 3 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 4 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 0 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 3 out\n+\t\telse\n+\t\t\ttest_i18ngrep \"CONFLICT (rename/rename)\" out &&\n+\t\t\ttest_i18ngrep \"Refusing to lose untracked file at y/c; adding as y/c~HEAD instead\" out &&\n \n-\t\tgit rev-parse >actual \\\n-\t\t\t:0:y/a :0:y/b :0:x/d :1:x/c :3:w/c :2:y/c &&\n-\t\tgit rev-parse >expect \\\n-\t\t\t O:z/a  O:z/b  O:x/d  O:x/c  O:x/c  O:x/c &&\n-\t\ttest_cmp expect actual &&\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 6 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 3 out &&\n \n-\t\tgit hash-object y/c~HEAD >actual &&\n-\t\tgit rev-parse O:x/c >expect &&\n-\t\ttest_cmp expect actual &&\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:y/a :0:y/b :0:x/d :1:x/c :3:w/c :2:y/c &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t O:z/a  O:z/b  O:x/d  O:x/c  O:x/c  O:x/c &&\n+\t\t\ttest_cmp expect actual &&\n+\n+\t\t\tgit hash-object y/c~HEAD >actual &&\n+\t\t\tgit rev-parse O:x/c >expect &&\n+\t\t\ttest_cmp expect actual\n+\t\tfi &&\n \n \t\techo important >expect &&\n \t\ttest_cmp expect y/c\n@@ -3474,37 +3514,50 @@ test_expect_success '10d: Delete untracked with dir rename/rename(2to1)' '\n \t\techo important >y/wham &&\n \n \t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&\n-\t\ttest_i18ngrep \"CONFLICT (rename/rename)\" out &&\n-\t\ttest_i18ngrep \"Refusing to lose untracked file at y/wham\" out &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_path_is_missing .git/MERGE_HEAD &&\n+\t\t\ttest_i18ngrep \"error: The following untracked working tree files would be overwritten by merge\" err &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 6 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 2 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 6 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 0 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 3 out\n+\t\telse\n+\t\t\ttest_i18ngrep \"CONFLICT (rename/rename)\" out &&\n+\t\t\ttest_i18ngrep \"Refusing to lose untracked file at y/wham\" out &&\n \n-\t\tgit rev-parse >actual \\\n-\t\t\t:0:y/a :0:y/b :0:y/d :0:y/e :2:y/wham :3:y/wham &&\n-\t\tgit rev-parse >expect \\\n-\t\t\t O:z/a  O:z/b  O:x/d  O:x/e  O:z/c     O:x/f &&\n-\t\ttest_cmp expect actual &&\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 6 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 3 out &&\n+\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:y/a :0:y/b :0:y/d :0:y/e :2:y/wham :3:y/wham &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t O:z/a  O:z/b  O:x/d  O:x/e  O:z/c     O:x/f &&\n+\t\t\ttest_cmp expect actual &&\n \n-\t\ttest_must_fail git rev-parse :1:y/wham &&\n+\t\t\ttest_must_fail git rev-parse :1:y/wham &&\n \n-\t\techo important >expect &&\n-\t\ttest_cmp expect y/wham &&\n+\t\t\t# Test that two-way merge in y/wham~merged is as expected\n+\t\t\tgit cat-file -p :2:y/wham >expect &&\n+\t\t\tgit cat-file -p :3:y/wham >other &&\n+\t\t\t>empty &&\n+\t\t\ttest_must_fail git merge-file \\\n+\t\t\t\t-L \"HEAD\" \\\n+\t\t\t\t-L \"\" \\\n+\t\t\t\t-L \"B^0\" \\\n+\t\t\t\texpect empty other &&\n+\t\t\ttest_cmp expect y/wham~merged\n+\t\tfi &&\n \n-\t\t# Test that the two-way merge in y/wham~merged is as expected\n-\t\tgit cat-file -p :2:y/wham >expect &&\n-\t\tgit cat-file -p :3:y/wham >other &&\n-\t\t>empty &&\n-\t\ttest_must_fail git merge-file \\\n-\t\t\t-L \"HEAD\" \\\n-\t\t\t-L \"\" \\\n-\t\t\t-L \"B^0\" \\\n-\t\t\texpect empty other &&\n-\t\ttest_cmp expect y/wham~merged\n+\t\techo important >expect &&\n+\t\ttest_cmp expect y/wham\n \t)\n '\n \n-- \ngitgitgadget\n\n"},{"id":"408260","messageId":"xmqqr1pohos4.fsf@gitster.c.googlers.com","threadId":"54492","inReplyTo":"a8d4825a323d5c1e7b2dc1edc8621c51c030ae1e.1603468885.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 1/9] t/: new helper for tests that pass with ort but fail with recursive","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-10-23T16:48:11Z","receivedAt":"2020-10-23T16:48:17Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"Elijah Newren via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n\n> From: Elijah Newren <newren@gmail.com>\n>\n> There are a number of tests that the \"recursive\" backend does not handle\n> correctly but which the redesign in \"ort\" will.  Add a new helper in\n> lib-merge.sh for selecting a different test expectation based on the\n> setting of GIT_TEST_MERGE_ALGORITHM, and use it in various testcases to\n> document which ones we expect to fail under recursive but pass under\n> ort.\n>\n> Signed-off-by: Elijah Newren <newren@gmail.com>\n> ---\n>  t/lib-merge.sh                         | 15 +++++++++++++++\n>  t/t6416-recursive-corner-cases.sh      | 11 ++++++-----\n>  t/t6422-merge-rename-corner-cases.sh   |  7 ++++---\n>  t/t6423-merge-rename-directories.sh    | 13 +++++++------\n>  t/t6426-merge-skip-unneeded-updates.sh |  3 ++-\n>  t/t6430-merge-recursive.sh             |  3 ++-\n>  6 files changed, 36 insertions(+), 16 deletions(-)\n>  create mode 100644 t/lib-merge.sh\n>\n> diff --git a/t/lib-merge.sh b/t/lib-merge.sh\n> new file mode 100644\n> index 0000000000..fac2bc5919\n> --- /dev/null\n> +++ b/t/lib-merge.sh\n> @@ -0,0 +1,15 @@\n> +# Helper functions used by merge tests.\n> +\n> +test_expect_merge_algorithm () {\n> +\tstatus_for_recursive=$1\n> +\tshift\n> +\tstatus_for_ort=$1\n> +\tshift\n\nSmaller than minor, but I'd find\n\n\tstatus_for_recursive=$1 status_for_ort=$2\n\tshift 2\n\neasier to see that which one is for which by matching the order in\nwhich the calling sites, e.g.\n\n\ttest_expect_merge_algorithm success failure \\\n\t\there comes the commands being tested\n\nlists them.\n\n> +\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n> +\tthen\n> +\t\ttest_expect_${status_for_ort} \"$@\"\n> +\telse\n> +\t\ttest_expect_${status_for_recursive} \"$@\"\n> +\tfi\n\nI expect this to be purely transitory, so it is fine.  If not,\nsomething along the lines of ...\n\n\teval test_expect='$'status_for_\"$GIT_TEST_MERGE_ALGORITHM\"\n\t$test_expect \"$@\"\n\n... might be what I would suggest, though ;-).\n\nAnd the users are just too pleasant to see, with full of \"failure\nsucess\", which is the second best outcome we want to see ;-)\n\n> +test_expect_merge_algorithm failure success 'check symlink mo...\n> +test_expect_merge_algorithm failure success 'check symlink ad...\n> +test_expect_merge_algorithm failure success 'check submodule ...\n> +test_expect_merge_algorithm failure success 'check submodule ...\n> +test_expect_merge_algorithm failure success 'check conflictin...\n> +test_expect_merge_algorithm failure success 'rad-check: renam...\n> +test_expect_merge_algorithm failure success 'rrdd-check: rena...\n> +test_expect_merge_algorithm failure success 'mod6-check: chai...\n> +test_expect_merge_algorithm failure success '6b1: Same rename...\n> +test_expect_merge_algorithm failure success '6b2: Same rename...\n> +test_expect_merge_algorithm failure success '10e: Does git co...\n> +test_expect_merge_algorithm failure success '12b1: Moving two...\n> +test_expect_merge_algorithm failure success '12c1: Moving one...\n> +test_expect_merge_algorithm failure success '12f: Trivial dir...\n> +test_expect_merge_algorithm failure success '4a: Change on A,...\n> +test_expect_merge_algorithm failure success 'merge-recursive ...\n"},{"id":"408261","messageId":"CABPp-BEtBWktGB0ksfk5YLhVDfmUJ-QxUMiYtMANL1KhXd8qTA@mail.gmail.com","threadId":"54492","inReplyTo":"xmqqr1pohos4.fsf@gitster.c.googlers.com","subject":"Re: [PATCH 1/9] t/: new helper for tests that pass with ort but fail with recursive","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-10-23T17:25:54Z","receivedAt":"2020-10-23T17:26:08Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Fri, Oct 23, 2020 at 9:48 AM Junio C Hamano <gitster@pobox.com> wrote:\n>\n> \"Elijah Newren via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n>\n> > From: Elijah Newren <newren@gmail.com>\n> >\n> > There are a number of tests that the \"recursive\" backend does not handle\n> > correctly but which the redesign in \"ort\" will.  Add a new helper in\n> > lib-merge.sh for selecting a different test expectation based on the\n> > setting of GIT_TEST_MERGE_ALGORITHM, and use it in various testcases to\n> > document which ones we expect to fail under recursive but pass under\n> > ort.\n> >\n> > Signed-off-by: Elijah Newren <newren@gmail.com>\n> > ---\n> >  t/lib-merge.sh                         | 15 +++++++++++++++\n> >  t/t6416-recursive-corner-cases.sh      | 11 ++++++-----\n> >  t/t6422-merge-rename-corner-cases.sh   |  7 ++++---\n> >  t/t6423-merge-rename-directories.sh    | 13 +++++++------\n> >  t/t6426-merge-skip-unneeded-updates.sh |  3 ++-\n> >  t/t6430-merge-recursive.sh             |  3 ++-\n> >  6 files changed, 36 insertions(+), 16 deletions(-)\n> >  create mode 100644 t/lib-merge.sh\n> >\n> > diff --git a/t/lib-merge.sh b/t/lib-merge.sh\n> > new file mode 100644\n> > index 0000000000..fac2bc5919\n> > --- /dev/null\n> > +++ b/t/lib-merge.sh\n> > @@ -0,0 +1,15 @@\n> > +# Helper functions used by merge tests.\n> > +\n> > +test_expect_merge_algorithm () {\n> > +     status_for_recursive=$1\n> > +     shift\n> > +     status_for_ort=$1\n> > +     shift\n>\n> Smaller than minor, but I'd find\n>\n>         status_for_recursive=$1 status_for_ort=$2\n>         shift 2\n>\n> easier to see that which one is for which by matching the order in\n> which the calling sites, e.g.\n>\n>         test_expect_merge_algorithm success failure \\\n>                 here comes the commands being tested\n>\n> lists them.\n\nI can fix that up.\n\n>\n> > +     if test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n> > +     then\n> > +             test_expect_${status_for_ort} \"$@\"\n> > +     else\n> > +             test_expect_${status_for_recursive} \"$@\"\n> > +     fi\n>\n> I expect this to be purely transitory, so it is fine.  If not,\n> something along the lines of ...\n>\n>         eval test_expect='$'status_for_\"$GIT_TEST_MERGE_ALGORITHM\"\n>         $test_expect \"$@\"\n>\n> ... might be what I would suggest, though ;-).\n\nI also expect it to be transitory, but how long that transition is\ndepends more on how long it takes for others to become comfortable\nwith removing merge-recursive.c once merge-ort.c is in place.  I\nsuspect at a minimum it's a cycle or two after ort becomes the default\n(which at a minimum would come a cycle or two after ort is finished\nand available).  If for some reason folks don't eventually become\ncomfortable with removing merge-recursive, then we might need to\nrevisit.\n\n> And the users are just too pleasant to see, with full of \"failure\n> sucess\", which is the second best outcome we want to see ;-)\n>\n> > +test_expect_merge_algorithm failure success 'check symlink mo...\n> > +test_expect_merge_algorithm failure success 'check symlink ad...\n> > +test_expect_merge_algorithm failure success 'check submodule ...\n> > +test_expect_merge_algorithm failure success 'check submodule ...\n> > +test_expect_merge_algorithm failure success 'check conflictin...\n> > +test_expect_merge_algorithm failure success 'rad-check: renam...\n> > +test_expect_merge_algorithm failure success 'rrdd-check: rena...\n> > +test_expect_merge_algorithm failure success 'mod6-check: chai...\n> > +test_expect_merge_algorithm failure success '6b1: Same rename...\n> > +test_expect_merge_algorithm failure success '6b2: Same rename...\n> > +test_expect_merge_algorithm failure success '10e: Does git co...\n> > +test_expect_merge_algorithm failure success '12b1: Moving two...\n> > +test_expect_merge_algorithm failure success '12c1: Moving one...\n> > +test_expect_merge_algorithm failure success '12f: Trivial dir...\n> > +test_expect_merge_algorithm failure success '4a: Change on A,...\n> > +test_expect_merge_algorithm failure success 'merge-recursive ...\n\n:-)\n"},{"id":"408265","messageId":"CABPp-BEhjecB7_juP3cSuF7MUHKbPXqAxKgKstPZw2ezHXputw@mail.gmail.com","threadId":"54492","inReplyTo":"9394d526f1425fcf6b8865b53b737ba81c11dd80.1603468885.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 2/9] merge tests: expect improved directory/file conflict handling in ort","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-10-23T17:40:28Z","receivedAt":"2020-10-23T17:40:42Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Fri, Oct 23, 2020 at 9:01 AM Elijah Newren via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> From: Elijah Newren <newren@gmail.com>\n>\n> merge-recursive.c is built on the idea of running unpack_trees() and\n> then \"doing minor touch-ups\" to get the result.  Unfortunately,\n> unpack_trees() was run in an update-as-it-goes mode, leading\n> merge-recursive.c to follow suit and end up with an immediate evaluation\n> and fix-it-up-as-you-go design.  Some things like directory/file\n> conflicts are not well representable in the index data structure, and\n> required special extra code to handle.  But then when it was discovered\n> that rename/delete conflicts could also be involved in directory/file\n> conflicts, the special directory/file conflict handling code had to be\n> copied to the rename/delete codepath.  ...and then it had to be copied\n> for modify/delete, and for rename/rename(1to2) conflicts, ...and yet it\n> still missed some.  Further, when it was discovered that there were also\n> file/submodule conflicts and submodule/directory conflicts, we needed to\n> copy the special submodule handling code to all the special cases\n> throughout the codebase.\n>\n> And then it was discovered that our handling of directory/file conflicts\n> was suboptimal because it would create untracked files to store the\n> contents of the conflicting file, which would not be cleaned up if\n> someone were to run a 'git merge --abort' or 'git rebase --abort'.  It\n> was also difficult or scary to try to add or remove the index entries\n> corresponding to these files given the directory/file conflict in the\n> index.  But changing merge-recursive.c to handle these correctly was a\n> royal pain because there were so many sites in the code with similar but\n> not identical code for handling directory/file/submodule conflicts that\n> would all need to be updated.\n>\n> I have worked hard to push all directory/file/submodule conflict\n> handling in merge-ort through a single codepath, and avoid creating\n> untracked files for storing tracked content (it does record things at\n> alternate paths, but makes sure they have higher-order stages in the\n> index).\n>\n> Since updating merge-recursive is too much work and we don't want to\n> destabilize it, instead update the testsuite to have different\n> expectations for relevant directory/file/submodule conflict tests.\n>\n> Signed-off-by: Elijah Newren <newren@gmail.com>\n\nPerhaps I should also mention that these changes to directory/file\nconflict handling were discussed previously in the thread at\nhttps://lore.kernel.org/git/xmqqbmabcuhf.fsf@gitster-ct.c.googlers.com/.\nI just never got around to a complete implementation within\nmerge-recursive.c, but did implement it in merge-ort.c\n\nI still haven't gotten around to fixing up git-mv and git-rm as\nsuggested by Junio in that thread; but at least I've finally gotten\nthe merge machinery side written...\n"},{"id":"408270","messageId":"CABPp-BGsrMX8brBq4ckhMVmXS7+1A9uaieJfYc3k3mBT4+5xVg@mail.gmail.com","threadId":"54492","inReplyTo":"CABPp-BEtBWktGB0ksfk5YLhVDfmUJ-QxUMiYtMANL1KhXd8qTA@mail.gmail.com","subject":"Re: [PATCH 1/9] t/: new helper for tests that pass with ort but fail with recursive","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-10-23T18:27:24Z","receivedAt":"2020-10-23T18:27:38Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"One more comment...\n\nOn Fri, Oct 23, 2020 at 10:25 AM Elijah Newren <newren@gmail.com> wrote:\n>\n> On Fri, Oct 23, 2020 at 9:48 AM Junio C Hamano <gitster@pobox.com> wrote:\n> >\n> > \"Elijah Newren via GitGitGadget\" <gitgitgadget@gmail.com> writes:\n> >\n\n> > And the users are just too pleasant to see, with full of \"failure\n> > sucess\", which is the second best outcome we want to see ;-)\n> >\n> > > +test_expect_merge_algorithm failure success 'check symlink mo...\n> > > +test_expect_merge_algorithm failure success 'check symlink ad...\n> > > +test_expect_merge_algorithm failure success 'check submodule ...\n> > > +test_expect_merge_algorithm failure success 'check submodule ...\n> > > +test_expect_merge_algorithm failure success 'check conflictin...\n> > > +test_expect_merge_algorithm failure success 'rad-check: renam...\n> > > +test_expect_merge_algorithm failure success 'rrdd-check: rena...\n> > > +test_expect_merge_algorithm failure success 'mod6-check: chai...\n> > > +test_expect_merge_algorithm failure success '6b1: Same rename...\n> > > +test_expect_merge_algorithm failure success '6b2: Same rename...\n> > > +test_expect_merge_algorithm failure success '10e: Does git co...\n> > > +test_expect_merge_algorithm failure success '12b1: Moving two...\n> > > +test_expect_merge_algorithm failure success '12c1: Moving one...\n> > > +test_expect_merge_algorithm failure success '12f: Trivial dir...\n> > > +test_expect_merge_algorithm failure success '4a: Change on A,...\n> > > +test_expect_merge_algorithm failure success 'merge-recursive ...\n>\n> :-)\n\nActually, there are another 12 submodule-related tests that pass under\nort but not under recursive, spread across t3512, t3513, t5572, t6437,\nand t6438.  I didn't (yet) apply the same change there, so they all\nshow up as \"TODO passed\" if you check out the 'ort' branch of my repo\nand run the tests with GIT_TEST_MERGE_ALGORITHM=ort.  I delayed\nmarking them as expecting success under ort because I suspect that\nnearby tests should also pass but are just coded too stringently.\n(For example, perhaps they expected a directory/submodule conflict to\nresult in all files within the conflicting directory to be renamed out\nof the way instead of expecting the submodule to be moved aside --\nmoving the submodule aside results in massively less rename handling\npressure and is an easier way to make sure that the files under the\nconflicting directory aren't written into and over entries within the\nsubmodule.)\n\nI was hoping to get a submodule expert to look over those tests and\nprovide some opinions...\n"},{"id":"408280","messageId":"CABPp-BHJyVbXp1bnN4uBMAgfx8i_4hCksAQbEjc_BG+1J+4xXw@mail.gmail.com","threadId":"54492","inReplyTo":"2659d1cb987735ec123ca7a82ed7e058e4d6bef0.1603468885.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 9/9] t6423: add more details about direct resolution of directories","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-10-23T20:12:43Z","receivedAt":"2020-10-23T20:12:56Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Fri, Oct 23, 2020 at 9:01 AM Elijah Newren via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> From: Elijah Newren <newren@gmail.com>\n>\n> Signed-off-by: Elijah Newren <newren@gmail.com>\n> ---\n>  t/t6423-merge-rename-directories.sh | 37 ++++++++++++++++-------------\n>  1 file changed, 21 insertions(+), 16 deletions(-)\n\nWhoops, I had meant for this last patch to be kept local for now and\nonly send it in after adding more of the merge-ort implementation.  To\nmake matters worse, it's slightly out of date with what I have on my\n'ort' branch.  Oh, well, I guess it doesn't hurt...at least not if I\nget the up-to-date version of the changes.  I'll include those in v2,\nalong with the small change Junio highlighted for patch 1, but wait a\nfew days for more feedback to come in on this series.\n"},{"id":"408290","messageId":"20201024104910.GA15823@danh.dev","threadId":"54492","inReplyTo":"a8d4825a323d5c1e7b2dc1edc8621c51c030ae1e.1603468885.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 1/9] t/: new helper for tests that pass with ort but fail with recursive","fromName":"Đoàn Trần Công Danh","fromEmail":"congdanhqx@gmail.com","sentAt":"2020-10-24T10:49:10Z","receivedAt":"2020-10-24T10:49:18Z","isPatch":true,"sender":{"key":"congdanhqx@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42673067?v=4"},"body":"On 2020-10-23 16:01:16+0000, Elijah Newren via GitGitGadget <gitgitgadget@gmail.com> wrote:\n> +test_expect_merge_algorithm () {\n> +\tstatus_for_recursive=$1\n> +\tshift\n> +\tstatus_for_ort=$1\n> +\tshift\n> +\n> +\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n> +\tthen\n> +\t\ttest_expect_${status_for_ort} \"$@\"\n> +\telse\n> +\t\ttest_expect_${status_for_recursive} \"$@\"\n> -test_expect_failure 'check symlink modify/modify' '\n> +test_expect_merge_algorithm failure success 'check symlink modify/modify' '\n\nI find this series of \"failure success\" hard to decode without\nunderstanding what it would be, then I need to keep rememberring which\nstatus is corresponding with with algorithm.\n\nPerhaps this patch is a bit easier to read. This is largely based on\nyour patch. (I haven't read other patches, yet).\n\nWhat do you think?\n\n-------------8<------------\nFrom: =?UTF-8?q?=C4=90o=C3=A0n=20Tr=E1=BA=A7n=20C=C3=B4ng=20Danh?=\n <congdanhqx@gmail.com>\nDate: Sat, 24 Oct 2020 17:41:02 +0700\nSubject: [PATCH] t/: new helper for testing merge that allow failure for some\n algorithm\n\nThere are a number of tests that the \"recursive\" backend does not handle\ncorrectly but which the redesign in \"ort\" will.\n\nAdd a new helper in lib-merge.sh for selecting a different test expectation\nbased on the setting of GIT_TEST_MERGE_ALGORITHM, and use it in various\ntestcases to document that we expect them to be success by default\nbut failure with certain algorithm.\n\nSigned-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>\n---\n t/lib-merge.sh                         | 19 +++++++++++++++++++\n t/t6416-recursive-corner-cases.sh      | 11 ++++++-----\n t/t6422-merge-rename-corner-cases.sh   |  7 ++++---\n t/t6423-merge-rename-directories.sh    | 13 +++++++------\n t/t6426-merge-skip-unneeded-updates.sh |  3 ++-\n t/t6430-merge-recursive.sh             |  3 ++-\n 6 files changed, 40 insertions(+), 16 deletions(-)\n create mode 100644 t/lib-merge.sh\n\ndiff --git a/t/lib-merge.sh b/t/lib-merge.sh\nnew file mode 100644\nindex 0000000000..efd8b9615c\n--- /dev/null\n+++ b/t/lib-merge.sh\n@@ -0,0 +1,19 @@\n+# Helper functions used by merge tests.\n+\n+test_expect_merge_success() {\n+\texception=\"$1\"\n+\t: \"${GIT_TEST_MERGE_ALGORITHM:=recursive}\"\n+\tcase \",$exception,\" in\n+\t*,$GIT_TEST_MERGE_ALGORITHM=failure,*)\n+\t\tshift\n+\t\ttest_expect_failure \"$@\" ;;\n+\t*,$GIT_TEST_MERGE_ALGORITHM=*)\n+\t\tBUG \"exception must be failure only\" ;;\n+\t*=failure,)\n+\t\tshift\n+\t\ttest_expect_success \"$@\" ;;\n+\t*)\n+\t\t# No exception\n+\t\ttest_expect_success \"$@\" ;;\n+\tesac\n+}\ndiff --git a/t/t6416-recursive-corner-cases.sh b/t/t6416-recursive-corner-cases.sh\nindex fd98989b14..d13c1afb4a 100755\n--- a/t/t6416-recursive-corner-cases.sh\n+++ b/t/t6416-recursive-corner-cases.sh\n@@ -3,6 +3,7 @@\n test_description='recursive merge corner cases involving criss-cross merges'\n \n . ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-merge.sh\n \n #\n #  L1  L2\n@@ -1069,7 +1070,7 @@ test_expect_success 'setup symlink modify/modify' '\n \t)\n '\n \n-test_expect_failure 'check symlink modify/modify' '\n+test_expect_merge_success recursive=failure 'check symlink modify/modify' '\n \t(\n \t\tcd symlink-modify-modify &&\n \n@@ -1135,7 +1136,7 @@ test_expect_success 'setup symlink add/add' '\n \t)\n '\n \n-test_expect_failure 'check symlink add/add' '\n+test_expect_merge_success recursive=failure 'check symlink add/add' '\n \t(\n \t\tcd symlink-add-add &&\n \n@@ -1223,7 +1224,7 @@ test_expect_success 'setup submodule modify/modify' '\n \t)\n '\n \n-test_expect_failure 'check submodule modify/modify' '\n+test_expect_merge_success recursive=failure 'check submodule modify/modify' '\n \t(\n \t\tcd submodule-modify-modify &&\n \n@@ -1311,7 +1312,7 @@ test_expect_success 'setup submodule add/add' '\n \t)\n '\n \n-test_expect_failure 'check submodule add/add' '\n+test_expect_merge_success recursive=failure 'check submodule add/add' '\n \t(\n \t\tcd submodule-add-add &&\n \n@@ -1386,7 +1387,7 @@ test_expect_success 'setup conflicting entry types (submodule vs symlink)' '\n \t)\n '\n \n-test_expect_failure 'check conflicting entry types (submodule vs symlink)' '\n+test_expect_merge_success recursive=failure 'check conflicting entry types (submodule vs symlink)' '\n \t(\n \t\tcd submodule-symlink-add-add &&\n \ndiff --git a/t/t6422-merge-rename-corner-cases.sh b/t/t6422-merge-rename-corner-cases.sh\nindex 3375eaf4e7..0c8eb4df8a 100755\n--- a/t/t6422-merge-rename-corner-cases.sh\n+++ b/t/t6422-merge-rename-corner-cases.sh\n@@ -4,6 +4,7 @@ test_description=\"recursive merge corner cases w/ renames but not criss-crosses\"\n # t6036 has corner cases that involve both criss-cross merges and renames\n \n . ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-merge.sh\n \n test_setup_rename_delete_untracked () {\n \ttest_create_repo rename-delete-untracked &&\n@@ -878,7 +879,7 @@ test_setup_rad () {\n \t)\n }\n \n-test_expect_failure 'rad-check: rename/add/delete conflict' '\n+test_expect_merge_success recursive=failure 'rad-check: rename/add/delete conflict' '\n \ttest_setup_rad &&\n \t(\n \t\tcd rad &&\n@@ -951,7 +952,7 @@ test_setup_rrdd () {\n \t)\n }\n \n-test_expect_failure 'rrdd-check: rename/rename(2to1)/delete/delete conflict' '\n+test_expect_merge_success recursive=failure 'rrdd-check: rename/rename(2to1)/delete/delete conflict' '\n \ttest_setup_rrdd &&\n \t(\n \t\tcd rrdd &&\n@@ -1040,7 +1041,7 @@ test_setup_mod6 () {\n \t)\n }\n \n-test_expect_failure 'mod6-check: chains of rename/rename(1to2) and rename/rename(2to1)' '\n+test_expect_merge_success recursive=failure 'mod6-check: chains of rename/rename(1to2) and rename/rename(2to1)' '\n \ttest_setup_mod6 &&\n \t(\n \t\tcd mod6 &&\ndiff --git a/t/t6423-merge-rename-directories.sh b/t/t6423-merge-rename-directories.sh\nindex 06b46af765..249fbb6853 100755\n--- a/t/t6423-merge-rename-directories.sh\n+++ b/t/t6423-merge-rename-directories.sh\n@@ -26,6 +26,7 @@ test_description=\"recursive merge with directory renames\"\n #                     files that might be renamed into each other's paths.)\n \n . ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-merge.sh\n \n \n ###########################################################################\n@@ -1339,7 +1340,7 @@ test_setup_6b1 () {\n \t)\n }\n \n-test_expect_failure '6b1: Same renames done on both sides, plus another rename' '\n+test_expect_merge_success recursive=failure '6b1: Same renames done on both sides, plus another rename' '\n \ttest_setup_6b1 &&\n \t(\n \t\tcd 6b1 &&\n@@ -1412,7 +1413,7 @@ test_setup_6b2 () {\n \t)\n }\n \n-test_expect_failure '6b2: Same rename done on both sides' '\n+test_expect_merge_success recursive=failure '6b2: Same rename done on both sides' '\n \ttest_setup_6b2 &&\n \t(\n \t\tcd 6b2 &&\n@@ -3471,7 +3472,7 @@ test_setup_10e () {\n \t)\n }\n \n-test_expect_failure '10e: Does git complain about untracked file that is not really in the way?' '\n+test_expect_merge_success recursive=failure '10e: Does git complain about untracked file that is not really in the way?' '\n \ttest_setup_10e &&\n \t(\n \t\tcd 10e &&\n@@ -4104,7 +4105,7 @@ test_setup_12b1 () {\n \t)\n }\n \n-test_expect_failure '12b1: Moving two directory hierarchies into each other' '\n+test_expect_merge_success recursive=failure '12b1: Moving two directory hierarchies into each other' '\n \ttest_setup_12b1 &&\n \t(\n \t\tcd 12b1 &&\n@@ -4272,7 +4273,7 @@ test_setup_12c1 () {\n \t)\n }\n \n-test_expect_failure '12c1: Moving one directory hierarchy into another w/ content merge' '\n+test_expect_merge_success recursive=failure '12c1: Moving one directory hierarchy into another w/ content merge' '\n \ttest_setup_12c1 &&\n \t(\n \t\tcd 12c1 &&\n@@ -4632,7 +4633,7 @@ test_setup_12f () {\n \t)\n }\n \n-test_expect_failure '12f: Trivial directory resolve, caching, all kinds of fun' '\n+test_expect_merge_success recursive=failure '12f: Trivial directory resolve, caching, all kinds of fun' '\n \ttest_setup_12f &&\n \t(\n \t\tcd 12f &&\ndiff --git a/t/t6426-merge-skip-unneeded-updates.sh b/t/t6426-merge-skip-unneeded-updates.sh\nindex 699813671c..8510d4da8b 100755\n--- a/t/t6426-merge-skip-unneeded-updates.sh\n+++ b/t/t6426-merge-skip-unneeded-updates.sh\n@@ -23,6 +23,7 @@ test_description=\"merge cases\"\n #                     files that might be renamed into each other's paths.)\n \n . ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-merge.sh\n \n \n ###########################################################################\n@@ -666,7 +667,7 @@ test_setup_4a () {\n #   correct requires doing the merge in-memory first, then realizing that no\n #   updates to the file are necessary, and thus that we can just leave the path\n #   alone.\n-test_expect_failure '4a: Change on A, change on B subset of A, dirty mods present' '\n+test_expect_merge_success recursive=failure '4a: Change on A, change on B subset of A, dirty mods present' '\n \ttest_setup_4a &&\n \t(\n \t\tcd 4a &&\ndiff --git a/t/t6430-merge-recursive.sh b/t/t6430-merge-recursive.sh\nindex a328260d42..4795a7abd0 100755\n--- a/t/t6430-merge-recursive.sh\n+++ b/t/t6430-merge-recursive.sh\n@@ -3,6 +3,7 @@\n test_description='merge-recursive backend test'\n \n . ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-merge.sh\n \n test_expect_success 'setup 1' '\n \n@@ -641,7 +642,7 @@ test_expect_success 'merge-recursive copy vs. rename' '\n \ttest_cmp expected actual\n '\n \n-test_expect_failure 'merge-recursive rename vs. rename/symlink' '\n+test_expect_merge_success recursive=failure 'merge-recursive rename vs. rename/symlink' '\n \n \tgit checkout -f rename &&\n \tgit merge rename-ln &&\n-- \n2.29.0.rc1\n\n"},{"id":"408294","messageId":"CABPp-BFuQ44O79OFGnNKLNNXi8d1f5AA5ApOkox4QrEocG7QrQ@mail.gmail.com","threadId":"54492","inReplyTo":"2aa44c1f13ac1fd70167770f7749611eadc396d4.1603468885.git.gitgitgadget@gmail.com","subject":"Re: [PATCH 6/9] merge tests: expect slight differences in output for recursive vs. ort","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-10-24T16:06:00Z","receivedAt":"2020-10-24T16:06:16Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Fri, Oct 23, 2020 at 9:01 AM Elijah Newren via GitGitGadget\n<gitgitgadget@gmail.com> wrote:\n>\n> diff --git a/t/t7602-merge-octopus-many.sh b/t/t7602-merge-octopus-many.sh\n> index 6abe441ae3..b205b5619e 100755\n> --- a/t/t7602-merge-octopus-many.sh\n> +++ b/t/t7602-merge-octopus-many.sh\n> @@ -77,6 +77,10 @@ Merge made by the 'recursive' strategy.\n>  EOF\n>\n>  test_expect_success 'merge reduces irrelevant remote heads' '\n> +       if test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n> +       then\n> +               sed -i'' s/recursive/ort/ expected\n> +       fi &&\n>         GIT_MERGE_VERBOSITY=0 git merge c4 c5 >actual &&\n>         test_i18ncmp expected actual\n>  '\n\nI've got a portability fix for this local hunk that I'll include along\nwith fixes for other feedback.  (I could have sworn I had this fixed\nbefore I sent it out, but I guess I sent an older version somehow?)\n"},{"id":"408295","messageId":"CABPp-BHgJrQMNEm7-y7nStVjcAedsNKH+bHNM9V34netTN+NTQ@mail.gmail.com","threadId":"54492","inReplyTo":"20201024104910.GA15823@danh.dev","subject":"Re: [PATCH 1/9] t/: new helper for tests that pass with ort but fail with recursive","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-10-24T16:53:18Z","receivedAt":"2020-10-24T16:53:32Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Sat, Oct 24, 2020 at 3:49 AM Đoàn Trần Công Danh\n<congdanhqx@gmail.com> wrote:\n>\n> On 2020-10-23 16:01:16+0000, Elijah Newren via GitGitGadget <gitgitgadget@gmail.com> wrote:\n> > +test_expect_merge_algorithm () {\n> > +     status_for_recursive=$1\n> > +     shift\n> > +     status_for_ort=$1\n> > +     shift\n> > +\n> > +     if test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n> > +     then\n> > +             test_expect_${status_for_ort} \"$@\"\n> > +     else\n> > +             test_expect_${status_for_recursive} \"$@\"\n> > -test_expect_failure 'check symlink modify/modify' '\n> > +test_expect_merge_algorithm failure success 'check symlink modify/modify' '\n>\n> I find this series of \"failure success\" hard to decode without\n> understanding what it would be, then I need to keep rememberring which\n> status is corresponding with with algorithm.\n>\n> Perhaps this patch is a bit easier to read. This is largely based on\n> your patch. (I haven't read other patches, yet).\n>\n> What do you think?\n\nIt is easier to read and I think something along these lines would\nmake a lot of sense if this weren't a transient change (the idea is to\neventually drop the recursive backend in favor of ort, and then these\ncan all switch to just using test_expect_success).  Maybe it still\nmakes sense to make further changes here anyway, but if we do go this\nroute, there are 1-2 things we can/should change:\n\nFirst, while a lot of my contributions aren't that important, and the\nnew test_expect_* function certainly falls in that category, one of\nthe driving goals behind a new merge algorithm was fixing up edge and\ncorner cases that were just too problematic in the recursive backend.\nThus, the patch where I get to flip the test expectation is one that I\ncare about more than most out of the (I'm guessing on this number)\n100+ patches that will be part of this new merge algorithm.  Having\nyou take over ownership of that patch thus isn't right; we should\ninstead keep my original patch and apply your suggested changes on top\n(or have a patch from you introducing a new function first, and then\nhave a patch from me using it to flip test expectations on top).\n\nSecond, I think that lines like\n    test_expect_merge_success recursive=failure ...\nread like a contradiction and are also confusing.  I think it'd be\nbetter if it read something like\n    test_expect_merge recursive=failure ort=success ...\nor something along those lines.\n\n\n> -------------8<------------\n> From: =?UTF-8?q?=C4=90o=C3=A0n=20Tr=E1=BA=A7n=20C=C3=B4ng=20Danh?=\n>  <congdanhqx@gmail.com>\n> Date: Sat, 24 Oct 2020 17:41:02 +0700\n> Subject: [PATCH] t/: new helper for testing merge that allow failure for some\n>  algorithm\n>\n> There are a number of tests that the \"recursive\" backend does not handle\n> correctly but which the redesign in \"ort\" will.\n>\n> Add a new helper in lib-merge.sh for selecting a different test expectation\n> based on the setting of GIT_TEST_MERGE_ALGORITHM, and use it in various\n> testcases to document that we expect them to be success by default\n> but failure with certain algorithm.\n>\n> Signed-off-by: Đoàn Trần Công Danh <congdanhqx@gmail.com>\n> ---\n>  t/lib-merge.sh                         | 19 +++++++++++++++++++\n>  t/t6416-recursive-corner-cases.sh      | 11 ++++++-----\n>  t/t6422-merge-rename-corner-cases.sh   |  7 ++++---\n>  t/t6423-merge-rename-directories.sh    | 13 +++++++------\n>  t/t6426-merge-skip-unneeded-updates.sh |  3 ++-\n>  t/t6430-merge-recursive.sh             |  3 ++-\n>  6 files changed, 40 insertions(+), 16 deletions(-)\n>  create mode 100644 t/lib-merge.sh\n>\n> diff --git a/t/lib-merge.sh b/t/lib-merge.sh\n> new file mode 100644\n> index 0000000000..efd8b9615c\n> --- /dev/null\n> +++ b/t/lib-merge.sh\n> @@ -0,0 +1,19 @@\n> +# Helper functions used by merge tests.\n> +\n> +test_expect_merge_success() {\n> +       exception=\"$1\"\n> +       : \"${GIT_TEST_MERGE_ALGORITHM:=recursive}\"\n> +       case \",$exception,\" in\n> +       *,$GIT_TEST_MERGE_ALGORITHM=failure,*)\n> +               shift\n> +               test_expect_failure \"$@\" ;;\n> +       *,$GIT_TEST_MERGE_ALGORITHM=*)\n> +               BUG \"exception must be failure only\" ;;\n> +       *=failure,)\n> +               shift\n> +               test_expect_success \"$@\" ;;\n> +       *)\n> +               # No exception\n> +               test_expect_success \"$@\" ;;\n> +       esac\n> +}\n> diff --git a/t/t6416-recursive-corner-cases.sh b/t/t6416-recursive-corner-cases.sh\n> index fd98989b14..d13c1afb4a 100755\n> --- a/t/t6416-recursive-corner-cases.sh\n> +++ b/t/t6416-recursive-corner-cases.sh\n> @@ -3,6 +3,7 @@\n>  test_description='recursive merge corner cases involving criss-cross merges'\n>\n>  . ./test-lib.sh\n> +. \"$TEST_DIRECTORY\"/lib-merge.sh\n>\n>  #\n>  #  L1  L2\n> @@ -1069,7 +1070,7 @@ test_expect_success 'setup symlink modify/modify' '\n>         )\n>  '\n>\n> -test_expect_failure 'check symlink modify/modify' '\n> +test_expect_merge_success recursive=failure 'check symlink modify/modify' '\n>         (\n>                 cd symlink-modify-modify &&\n>\n> @@ -1135,7 +1136,7 @@ test_expect_success 'setup symlink add/add' '\n>         )\n>  '\n>\n> -test_expect_failure 'check symlink add/add' '\n> +test_expect_merge_success recursive=failure 'check symlink add/add' '\n>         (\n>                 cd symlink-add-add &&\n>\n> @@ -1223,7 +1224,7 @@ test_expect_success 'setup submodule modify/modify' '\n>         )\n>  '\n>\n> -test_expect_failure 'check submodule modify/modify' '\n> +test_expect_merge_success recursive=failure 'check submodule modify/modify' '\n>         (\n>                 cd submodule-modify-modify &&\n>\n> @@ -1311,7 +1312,7 @@ test_expect_success 'setup submodule add/add' '\n>         )\n>  '\n>\n> -test_expect_failure 'check submodule add/add' '\n> +test_expect_merge_success recursive=failure 'check submodule add/add' '\n>         (\n>                 cd submodule-add-add &&\n>\n> @@ -1386,7 +1387,7 @@ test_expect_success 'setup conflicting entry types (submodule vs symlink)' '\n>         )\n>  '\n>\n> -test_expect_failure 'check conflicting entry types (submodule vs symlink)' '\n> +test_expect_merge_success recursive=failure 'check conflicting entry types (submodule vs symlink)' '\n>         (\n>                 cd submodule-symlink-add-add &&\n>\n> diff --git a/t/t6422-merge-rename-corner-cases.sh b/t/t6422-merge-rename-corner-cases.sh\n> index 3375eaf4e7..0c8eb4df8a 100755\n> --- a/t/t6422-merge-rename-corner-cases.sh\n> +++ b/t/t6422-merge-rename-corner-cases.sh\n> @@ -4,6 +4,7 @@ test_description=\"recursive merge corner cases w/ renames but not criss-crosses\"\n>  # t6036 has corner cases that involve both criss-cross merges and renames\n>\n>  . ./test-lib.sh\n> +. \"$TEST_DIRECTORY\"/lib-merge.sh\n>\n>  test_setup_rename_delete_untracked () {\n>         test_create_repo rename-delete-untracked &&\n> @@ -878,7 +879,7 @@ test_setup_rad () {\n>         )\n>  }\n>\n> -test_expect_failure 'rad-check: rename/add/delete conflict' '\n> +test_expect_merge_success recursive=failure 'rad-check: rename/add/delete conflict' '\n>         test_setup_rad &&\n>         (\n>                 cd rad &&\n> @@ -951,7 +952,7 @@ test_setup_rrdd () {\n>         )\n>  }\n>\n> -test_expect_failure 'rrdd-check: rename/rename(2to1)/delete/delete conflict' '\n> +test_expect_merge_success recursive=failure 'rrdd-check: rename/rename(2to1)/delete/delete conflict' '\n>         test_setup_rrdd &&\n>         (\n>                 cd rrdd &&\n> @@ -1040,7 +1041,7 @@ test_setup_mod6 () {\n>         )\n>  }\n>\n> -test_expect_failure 'mod6-check: chains of rename/rename(1to2) and rename/rename(2to1)' '\n> +test_expect_merge_success recursive=failure 'mod6-check: chains of rename/rename(1to2) and rename/rename(2to1)' '\n>         test_setup_mod6 &&\n>         (\n>                 cd mod6 &&\n> diff --git a/t/t6423-merge-rename-directories.sh b/t/t6423-merge-rename-directories.sh\n> index 06b46af765..249fbb6853 100755\n> --- a/t/t6423-merge-rename-directories.sh\n> +++ b/t/t6423-merge-rename-directories.sh\n> @@ -26,6 +26,7 @@ test_description=\"recursive merge with directory renames\"\n>  #                     files that might be renamed into each other's paths.)\n>\n>  . ./test-lib.sh\n> +. \"$TEST_DIRECTORY\"/lib-merge.sh\n>\n>\n>  ###########################################################################\n> @@ -1339,7 +1340,7 @@ test_setup_6b1 () {\n>         )\n>  }\n>\n> -test_expect_failure '6b1: Same renames done on both sides, plus another rename' '\n> +test_expect_merge_success recursive=failure '6b1: Same renames done on both sides, plus another rename' '\n>         test_setup_6b1 &&\n>         (\n>                 cd 6b1 &&\n> @@ -1412,7 +1413,7 @@ test_setup_6b2 () {\n>         )\n>  }\n>\n> -test_expect_failure '6b2: Same rename done on both sides' '\n> +test_expect_merge_success recursive=failure '6b2: Same rename done on both sides' '\n>         test_setup_6b2 &&\n>         (\n>                 cd 6b2 &&\n> @@ -3471,7 +3472,7 @@ test_setup_10e () {\n>         )\n>  }\n>\n> -test_expect_failure '10e: Does git complain about untracked file that is not really in the way?' '\n> +test_expect_merge_success recursive=failure '10e: Does git complain about untracked file that is not really in the way?' '\n>         test_setup_10e &&\n>         (\n>                 cd 10e &&\n> @@ -4104,7 +4105,7 @@ test_setup_12b1 () {\n>         )\n>  }\n>\n> -test_expect_failure '12b1: Moving two directory hierarchies into each other' '\n> +test_expect_merge_success recursive=failure '12b1: Moving two directory hierarchies into each other' '\n>         test_setup_12b1 &&\n>         (\n>                 cd 12b1 &&\n> @@ -4272,7 +4273,7 @@ test_setup_12c1 () {\n>         )\n>  }\n>\n> -test_expect_failure '12c1: Moving one directory hierarchy into another w/ content merge' '\n> +test_expect_merge_success recursive=failure '12c1: Moving one directory hierarchy into another w/ content merge' '\n>         test_setup_12c1 &&\n>         (\n>                 cd 12c1 &&\n> @@ -4632,7 +4633,7 @@ test_setup_12f () {\n>         )\n>  }\n>\n> -test_expect_failure '12f: Trivial directory resolve, caching, all kinds of fun' '\n> +test_expect_merge_success recursive=failure '12f: Trivial directory resolve, caching, all kinds of fun' '\n>         test_setup_12f &&\n>         (\n>                 cd 12f &&\n> diff --git a/t/t6426-merge-skip-unneeded-updates.sh b/t/t6426-merge-skip-unneeded-updates.sh\n> index 699813671c..8510d4da8b 100755\n> --- a/t/t6426-merge-skip-unneeded-updates.sh\n> +++ b/t/t6426-merge-skip-unneeded-updates.sh\n> @@ -23,6 +23,7 @@ test_description=\"merge cases\"\n>  #                     files that might be renamed into each other's paths.)\n>\n>  . ./test-lib.sh\n> +. \"$TEST_DIRECTORY\"/lib-merge.sh\n>\n>\n>  ###########################################################################\n> @@ -666,7 +667,7 @@ test_setup_4a () {\n>  #   correct requires doing the merge in-memory first, then realizing that no\n>  #   updates to the file are necessary, and thus that we can just leave the path\n>  #   alone.\n> -test_expect_failure '4a: Change on A, change on B subset of A, dirty mods present' '\n> +test_expect_merge_success recursive=failure '4a: Change on A, change on B subset of A, dirty mods present' '\n>         test_setup_4a &&\n>         (\n>                 cd 4a &&\n> diff --git a/t/t6430-merge-recursive.sh b/t/t6430-merge-recursive.sh\n> index a328260d42..4795a7abd0 100755\n> --- a/t/t6430-merge-recursive.sh\n> +++ b/t/t6430-merge-recursive.sh\n> @@ -3,6 +3,7 @@\n>  test_description='merge-recursive backend test'\n>\n>  . ./test-lib.sh\n> +. \"$TEST_DIRECTORY\"/lib-merge.sh\n>\n>  test_expect_success 'setup 1' '\n>\n> @@ -641,7 +642,7 @@ test_expect_success 'merge-recursive copy vs. rename' '\n>         test_cmp expected actual\n>  '\n>\n> -test_expect_failure 'merge-recursive rename vs. rename/symlink' '\n> +test_expect_merge_success recursive=failure 'merge-recursive rename vs. rename/symlink' '\n>\n>         git checkout -f rename &&\n>         git merge rename-ln &&\n> --\n> 2.29.0.rc1\n"},{"id":"408348","messageId":"20201025134905.GB15823@danh.dev","threadId":"54492","inReplyTo":"CABPp-BHgJrQMNEm7-y7nStVjcAedsNKH+bHNM9V34netTN+NTQ@mail.gmail.com","subject":"Re: [PATCH 1/9] t/: new helper for tests that pass with ort but fail with recursive","fromName":"Đoàn Trần Công Danh","fromEmail":"congdanhqx@gmail.com","sentAt":"2020-10-25T13:49:05Z","receivedAt":"2020-10-25T13:49:11Z","isPatch":true,"sender":{"key":"congdanhqx@gmail.com","avatar":"https://avatars.githubusercontent.com/u/42673067?v=4"},"body":"On 2020-10-24 09:53:18-0700, Elijah Newren <newren@gmail.com> wrote:\n> On Sat, Oct 24, 2020 at 3:49 AM Đoàn Trần Công Danh\n> <congdanhqx@gmail.com> wrote:\n> >\n> > On 2020-10-23 16:01:16+0000, Elijah Newren via GitGitGadget <gitgitgadget@gmail.com> wrote:\n> > > +test_expect_merge_algorithm () {\n> > > +     status_for_recursive=$1\n> > > +     shift\n> > > +     status_for_ort=$1\n> > > +     shift\n> > > +\n> > > +     if test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n> > > +     then\n> > > +             test_expect_${status_for_ort} \"$@\"\n> > > +     else\n> > > +             test_expect_${status_for_recursive} \"$@\"\n> > > -test_expect_failure 'check symlink modify/modify' '\n> > > +test_expect_merge_algorithm failure success 'check symlink modify/modify' '\n> >\n> > I find this series of \"failure success\" hard to decode without\n> > understanding what it would be, then I need to keep rememberring which\n> > status is corresponding with with algorithm.\n> >\n> > Perhaps this patch is a bit easier to read. This is largely based on\n> > your patch. (I haven't read other patches, yet).\n> >\n> > What do you think?\n> \n> It is easier to read and I think something along these lines would\n> make a lot of sense if this weren't a transient change (the idea is to\n> eventually drop the recursive backend in favor of ort, and then these\n> can all switch to just using test_expect_success).  Maybe it still\n> makes sense to make further changes here anyway, but if we do go this\n> route, there are 1-2 things we can/should change:\n> \n> First, while a lot of my contributions aren't that important, and the\n\nMine aren't that important, either\n\n> new test_expect_* function certainly falls in that category, one of\n> the driving goals behind a new merge algorithm was fixing up edge and\n> corner cases that were just too problematic in the recursive backend.\n> Thus, the patch where I get to flip the test expectation is one that I\n> care about more than most out of the (I'm guessing on this number)\n\nMake sense.\n\n> 100+ patches that will be part of this new merge algorithm.  Having\n> you take over ownership of that patch thus isn't right; we should\n> instead keep my original patch and apply your suggested changes on top\n> (or have a patch from you introducing a new function first, and then\n> have a patch from me using it to flip test expectations on top).\n\nYou can take back the ownership, the patch was based on yours, anyway.\n\nI wrote like that since I need to rewrite part of the message to match\nwith my changes ;)\n\nNo need to generate extra noise of additional patch.\n\n> Second, I think that lines like\n>     test_expect_merge_success recursive=failure ...\n> read like a contradiction and are also confusing.  I think it'd be\n> better if it read something like\n>     test_expect_merge recursive=failure ort=success ...\n> or something along those lines.\n\nWhen I wrote the patch, I was expecting something like\n\n\ttest_expect_merge_success recursive=failure,other=failure ...\n\nin order to merge all algorithm into single parameters.\n\nHow about something like:\n\n\ttest_expect_merge_success exception=recursive,other ...\n\nNot that we have \"other\" algorithm to begin with.\n\nThanks,\n-- Danh\n"},{"id":"408397","messageId":"CABPp-BEmJA92tDymypgJqGmi=eMsvU+eP=KeTKvKcJEvFVztEA@mail.gmail.com","threadId":"54492","inReplyTo":"20201025134905.GB15823@danh.dev","subject":"Re: [PATCH 1/9] t/: new helper for tests that pass with ort but fail with recursive","fromName":"Elijah Newren","fromEmail":"newren@gmail.com","sentAt":"2020-10-26T14:56:59Z","receivedAt":"2020-10-26T14:57:13Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"On Sun, Oct 25, 2020 at 6:49 AM Đoàn Trần Công Danh\n<congdanhqx@gmail.com> wrote:\n>\n> On 2020-10-24 09:53:18-0700, Elijah Newren <newren@gmail.com> wrote:\n> > On Sat, Oct 24, 2020 at 3:49 AM Đoàn Trần Công Danh\n> > <congdanhqx@gmail.com> wrote:\n> > >\n> > > On 2020-10-23 16:01:16+0000, Elijah Newren via GitGitGadget <gitgitgadget@gmail.com> wrote:\n> > > > +test_expect_merge_algorithm () {\n> > > > +     status_for_recursive=$1\n> > > > +     shift\n> > > > +     status_for_ort=$1\n> > > > +     shift\n> > > > +\n> > > > +     if test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n> > > > +     then\n> > > > +             test_expect_${status_for_ort} \"$@\"\n> > > > +     else\n> > > > +             test_expect_${status_for_recursive} \"$@\"\n> > > > -test_expect_failure 'check symlink modify/modify' '\n> > > > +test_expect_merge_algorithm failure success 'check symlink modify/modify' '\n> > >\n> > > I find this series of \"failure success\" hard to decode without\n> > > understanding what it would be, then I need to keep rememberring which\n> > > status is corresponding with with algorithm.\n> > >\n> > > Perhaps this patch is a bit easier to read. This is largely based on\n> > > your patch. (I haven't read other patches, yet).\n> > >\n> > > What do you think?\n> >\n> > It is easier to read and I think something along these lines would\n> > make a lot of sense if this weren't a transient change (the idea is to\n> > eventually drop the recursive backend in favor of ort, and then these\n> > can all switch to just using test_expect_success).  Maybe it still\n> > makes sense to make further changes here anyway, but if we do go this\n> > route, there are 1-2 things we can/should change:\n> >\n> > First, while a lot of my contributions aren't that important, and the\n>\n> Mine aren't that important, either\n>\n> > new test_expect_* function certainly falls in that category, one of\n> > the driving goals behind a new merge algorithm was fixing up edge and\n> > corner cases that were just too problematic in the recursive backend.\n> > Thus, the patch where I get to flip the test expectation is one that I\n> > care about more than most out of the (I'm guessing on this number)\n>\n> Make sense.\n>\n> > 100+ patches that will be part of this new merge algorithm.  Having\n> > you take over ownership of that patch thus isn't right; we should\n> > instead keep my original patch and apply your suggested changes on top\n> > (or have a patch from you introducing a new function first, and then\n> > have a patch from me using it to flip test expectations on top).\n>\n> You can take back the ownership, the patch was based on yours, anyway.\n>\n> I wrote like that since I need to rewrite part of the message to match\n> with my changes ;)\n>\n> No need to generate extra noise of additional patch.\n\nJust to be clear, others have made suggestions like yours in the past\nwhere they've taken over ownership of a patch in a series and I've\nbeen totally fine with it.  Your suggestion to do the same would have\nbeen fine here, but I'm just kinda attached to being able to flip the\ntest expectation for these tests; I've been working towards it for a\n_long_ time.\n\nI think an extra patch, attributed to you, actually makes the most sense here.\n\n> > Second, I think that lines like\n> >     test_expect_merge_success recursive=failure ...\n> > read like a contradiction and are also confusing.  I think it'd be\n> > better if it read something like\n> >     test_expect_merge recursive=failure ort=success ...\n> > or something along those lines.\n>\n> When I wrote the patch, I was expecting something like\n>\n>         test_expect_merge_success recursive=failure,other=failure ...\n>\n> in order to merge all algorithm into single parameters.\n>\n> How about something like:\n>\n>         test_expect_merge_success exception=recursive,other ...\n>\n> Not that we have \"other\" algorithm to begin with.\n\nSure, sounds great.  I wouldn't spend any time trying to make it work\nwith a 3rd backend, though.  The goal is to have two merge backends\nonly long enough for people to become comfortable with the new backend\nand discover any unknown issues with it that we can fix, then we'll\nrip it out the old \"recursive\" backend and we'll translate any\nrequests for \"recursive\" to mean \"ort\".  We'll also rip the\ntest_expect_merge_success() function out since it'll be unneeded (so\nefforts towards future proofing of that function will be wasted).\nThen years will go by before another merge backend comes along, if one\never does.\n"},{"id":"408413","messageId":"c5350fd0aef44e5d7658ae1082d745a6a148cc73.1603731704.git.gitgitgadget@gmail.com","threadId":"54492","inReplyTo":"pull.769.v2.git.1603731704.gitgitgadget@gmail.com","subject":"[PATCH v2 7/9] t6423, t6436: note improved ort handling with dirty files","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-10-26T17:01:42Z","receivedAt":"2020-10-26T17:02:43Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nThe \"recursive\" backend relies on unpack_trees() to check if unstaged\nchanges would be overwritten by a merge, but unpack_trees() does not\nunderstand renames -- and once it returns, it has already written many\nupdates to the working tree and index.  As such, \"recursive\" had to do a\nspecial 4-way merge where it would need to also treat the working copy\nas an extra source of differences that we had to carefully avoid\noverwriting and resulting in moving files to new locations to avoid\nconflicts.\n\nThe \"ort\" backend, by contrast, does the complete merge inmemory, and\nonly updates the index and working copy as a post-processing step.  If\nthere are dirty files in the way, it can simply abort the merge.\n\nUpdate t6423 and t6436 to reflect the better merge abilities and\nexpectations we have for ort, while still leaving the\nbest-case-as-good-as-recursive-can-do expectations there for the\nrecursive backend so we retain its stability until we are ready to\ndeprecate and remove it.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n t/t6423-merge-rename-directories.sh | 266 ++++++++++++++++------------\n t/t6436-merge-overwrite.sh          |  18 +-\n 2 files changed, 165 insertions(+), 119 deletions(-)\n\ndiff --git a/t/t6423-merge-rename-directories.sh b/t/t6423-merge-rename-directories.sh\nindex 7e32626913..32e6925ca4 100755\n--- a/t/t6423-merge-rename-directories.sh\n+++ b/t/t6423-merge-rename-directories.sh\n@@ -3634,28 +3634,35 @@ test_expect_success '11a: Avoid losing dirty contents with simple rename' '\n \t\techo stuff >>z/c &&\n \n \t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&\n-\t\ttest_i18ngrep \"Refusing to lose dirty file at z/c\" out &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_path_is_missing .git/MERGE_HEAD &&\n+\t\t\ttest_i18ngrep \"error: Your local changes to the following files would be overwritten by merge\" err\n+\t\telse\n+\t\t\ttest_i18ngrep \"Refusing to lose dirty file at z/c\" out &&\n \n-\t\ttest_seq 1 10 >expected &&\n-\t\techo stuff >>expected &&\n-\t\ttest_cmp expected z/c &&\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 3 out &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 2 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 1 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 4 out &&\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:z/a :2:z/c &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t O:z/a  B:z/b &&\n+\t\t\ttest_cmp expect actual &&\n \n-\t\tgit rev-parse >actual \\\n-\t\t\t:0:z/a :2:z/c &&\n-\t\tgit rev-parse >expect \\\n-\t\t\t O:z/a  B:z/b &&\n-\t\ttest_cmp expect actual &&\n+\t\t\tgit hash-object z/c~HEAD >actual &&\n+\t\t\tgit rev-parse B:z/b >expect &&\n+\t\t\ttest_cmp expect actual\n+\t\tfi &&\n+\n+\t\ttest_seq 1 10 >expected &&\n+\t\techo stuff >>expected &&\n+\t\ttest_cmp expected z/c\n \n-\t\tgit hash-object z/c~HEAD >actual &&\n-\t\tgit rev-parse B:z/b >expect &&\n-\t\ttest_cmp expect actual\n \t)\n '\n \n@@ -3706,32 +3713,39 @@ test_expect_success '11b: Avoid losing dirty file involved in directory rename'\n \t\tgit checkout A^0 &&\n \t\techo stuff >>z/c &&\n \n-\t\tgit -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&\n-\t\ttest_i18ngrep \"Refusing to lose dirty file at z/c\" out &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&\n+\t\t\ttest_path_is_missing .git/MERGE_HEAD &&\n+\t\t\ttest_i18ngrep \"error: Your local changes to the following files would be overwritten by merge\" err\n+\t\telse\n+\t\t\tgit -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&\n+\t\t\ttest_i18ngrep \"Refusing to lose dirty file at z/c\" out &&\n \n-\t\tgrep -q stuff z/c &&\n-\t\ttest_seq 1 10 >expected &&\n-\t\techo stuff >>expected &&\n-\t\ttest_cmp expected z/c &&\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 0 out &&\n+\t\t\tgit ls-files -m >out &&\n+\t\t\ttest_line_count = 0 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 3 out &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 3 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 0 out &&\n-\t\tgit ls-files -m >out &&\n-\t\ttest_line_count = 0 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 4 out &&\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:x/b :0:y/a :0:y/c &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t O:x/b  O:z/a  B:x/c &&\n+\t\t\ttest_cmp expect actual &&\n \n-\t\tgit rev-parse >actual \\\n-\t\t\t:0:x/b :0:y/a :0:y/c &&\n-\t\tgit rev-parse >expect \\\n-\t\t\t O:x/b  O:z/a  B:x/c &&\n-\t\ttest_cmp expect actual &&\n+\t\t\tgit hash-object y/c >actual &&\n+\t\t\tgit rev-parse B:x/c >expect &&\n+\t\t\ttest_cmp expect actual\n+\t\tfi &&\n \n-\t\tgit hash-object y/c >actual &&\n-\t\tgit rev-parse B:x/c >expect &&\n-\t\ttest_cmp expect actual\n+\t\tgrep -q stuff z/c &&\n+\t\ttest_seq 1 10 >expected &&\n+\t\techo stuff >>expected &&\n+\t\ttest_cmp expected z/c\n \t)\n '\n \n@@ -3783,7 +3797,13 @@ test_expect_success '11c: Avoid losing not-uptodate with rename + D/F conflict'\n \t\techo stuff >>y/c &&\n \n \t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&\n-\t\ttest_i18ngrep \"following files would be overwritten by merge\" err &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_path_is_missing .git/MERGE_HEAD &&\n+\t\t\ttest_i18ngrep \"error: Your local changes to the following files would be overwritten by merge\" err\n+\t\telse\n+\t\t\ttest_i18ngrep \"following files would be overwritten by merge\" err\n+\t\tfi &&\n \n \t\tgrep -q stuff y/c &&\n \t\ttest_seq 1 10 >expected &&\n@@ -3851,29 +3871,35 @@ test_expect_success '11d: Avoid losing not-uptodate with rename + D/F conflict'\n \t\techo stuff >>z/c &&\n \n \t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&\n-\t\ttest_i18ngrep \"Refusing to lose dirty file at z/c\" out &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_path_is_missing .git/MERGE_HEAD &&\n+\t\t\ttest_i18ngrep \"error: Your local changes to the following files would be overwritten by merge\" err\n+\t\telse\n+\t\t\ttest_i18ngrep \"Refusing to lose dirty file at z/c\" out &&\n \n-\t\tgrep -q stuff z/c &&\n-\t\ttest_seq 1 10 >expected &&\n-\t\techo stuff >>expected &&\n-\t\ttest_cmp expected z/c &&\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 4 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 4 out &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 4 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 1 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 5 out &&\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:x/b :0:y/a :0:y/c/d :3:y/c &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t O:x/b  O:z/a  B:y/c/d  B:x/c &&\n+\t\t\ttest_cmp expect actual &&\n \n-\t\tgit rev-parse >actual \\\n-\t\t\t:0:x/b :0:y/a :0:y/c/d :3:y/c &&\n-\t\tgit rev-parse >expect \\\n-\t\t\t O:x/b  O:z/a  B:y/c/d  B:x/c &&\n-\t\ttest_cmp expect actual &&\n+\t\t\tgit hash-object y/c~HEAD >actual &&\n+\t\t\tgit rev-parse B:x/c >expect &&\n+\t\t\ttest_cmp expect actual\n+\t\tfi &&\n \n-\t\tgit hash-object y/c~HEAD >actual &&\n-\t\tgit rev-parse B:x/c >expect &&\n-\t\ttest_cmp expect actual\n+\t\tgrep -q stuff z/c &&\n+\t\ttest_seq 1 10 >expected &&\n+\t\techo stuff >>expected &&\n+\t\ttest_cmp expected z/c\n \t)\n '\n \n@@ -3931,37 +3957,43 @@ test_expect_success '11e: Avoid deleting not-uptodate with dir rename/rename(1to\n \t\techo mods >>y/c &&\n \n \t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&\n-\t\ttest_i18ngrep \"CONFLICT (rename/rename)\" out &&\n-\t\ttest_i18ngrep \"Refusing to lose dirty file at y/c\" out &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_path_is_missing .git/MERGE_HEAD &&\n+\t\t\ttest_i18ngrep \"error: Your local changes to the following files would be overwritten by merge\" err\n+\t\telse\n+\t\t\ttest_i18ngrep \"CONFLICT (rename/rename)\" out &&\n+\t\t\ttest_i18ngrep \"Refusing to lose dirty file at y/c\" out &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 7 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 4 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 7 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 4 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 3 out &&\n+\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:y/a :0:y/b :0:x/d :1:x/c :2:w/c :2:y/c :3:y/c &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t O:z/a  O:z/b  O:x/d  O:x/c  O:x/c  A:y/c  O:x/c &&\n+\t\t\ttest_cmp expect actual &&\n+\n+\t\t\t# See if y/c~merged has expected contents; requires manually\n+\t\t\t# doing the expected file merge\n+\t\t\tgit cat-file -p A:y/c >c1 &&\n+\t\t\tgit cat-file -p B:z/c >c2 &&\n+\t\t\t>empty &&\n+\t\t\ttest_must_fail git merge-file \\\n+\t\t\t\t-L \"HEAD\" \\\n+\t\t\t\t-L \"\" \\\n+\t\t\t\t-L \"B^0\" \\\n+\t\t\t\tc1 empty c2 &&\n+\t\t\ttest_cmp c1 y/c~merged\n+\t\tfi &&\n \n \t\techo different >expected &&\n \t\techo mods >>expected &&\n-\t\ttest_cmp expected y/c &&\n-\n-\t\tgit rev-parse >actual \\\n-\t\t\t:0:y/a :0:y/b :0:x/d :1:x/c :2:w/c :2:y/c :3:y/c &&\n-\t\tgit rev-parse >expect \\\n-\t\t\t O:z/a  O:z/b  O:x/d  O:x/c  O:x/c  A:y/c  O:x/c &&\n-\t\ttest_cmp expect actual &&\n-\n-\t\t# See if y/c~merged has expected contents; requires manually\n-\t\t# doing the expected file merge\n-\t\tgit cat-file -p A:y/c >c1 &&\n-\t\tgit cat-file -p B:z/c >c2 &&\n-\t\t>empty &&\n-\t\ttest_must_fail git merge-file \\\n-\t\t\t-L \"HEAD\" \\\n-\t\t\t-L \"\" \\\n-\t\t\t-L \"B^0\" \\\n-\t\t\tc1 empty c2 &&\n-\t\ttest_cmp c1 y/c~merged\n+\t\ttest_cmp expected y/c\n \t)\n '\n \n@@ -4014,38 +4046,44 @@ test_expect_success '11f: Avoid deleting not-uptodate with dir rename/rename(2to\n \t\techo important >>y/wham &&\n \n \t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&\n-\t\ttest_i18ngrep \"CONFLICT (rename/rename)\" out &&\n-\t\ttest_i18ngrep \"Refusing to lose dirty file at y/wham\" out &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_path_is_missing .git/MERGE_HEAD &&\n+\t\t\ttest_i18ngrep \"error: Your local changes to the following files would be overwritten by merge\" err\n+\t\telse\n+\t\t\ttest_i18ngrep \"CONFLICT (rename/rename)\" out &&\n+\t\t\ttest_i18ngrep \"Refusing to lose dirty file at y/wham\" out &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 4 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 2 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 4 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 3 out &&\n \n-\t\ttest_seq 1 10 >expected &&\n-\t\techo important >>expected &&\n-\t\ttest_cmp expected y/wham &&\n+\t\t\ttest_must_fail git rev-parse :1:y/wham &&\n \n-\t\ttest_must_fail git rev-parse :1:y/wham &&\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:y/a :0:y/b :2:y/wham :3:y/wham &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t O:z/a  O:z/b  O:x/c     O:x/d &&\n+\t\t\ttest_cmp expect actual &&\n \n-\t\tgit rev-parse >actual \\\n-\t\t\t:0:y/a :0:y/b :2:y/wham :3:y/wham &&\n-\t\tgit rev-parse >expect \\\n-\t\t\t O:z/a  O:z/b  O:x/c     O:x/d &&\n-\t\ttest_cmp expect actual &&\n+\t\t\t# Test that two-way merge in y/wham~merged is as expected\n+\t\t\tgit cat-file -p :2:y/wham >expect &&\n+\t\t\tgit cat-file -p :3:y/wham >other &&\n+\t\t\t>empty &&\n+\t\t\ttest_must_fail git merge-file \\\n+\t\t\t\t-L \"HEAD\" \\\n+\t\t\t\t-L \"\" \\\n+\t\t\t\t-L \"B^0\" \\\n+\t\t\t\texpect empty other &&\n+\t\t\ttest_cmp expect y/wham~merged\n+\t\tfi &&\n \n-\t\t# Test that the two-way merge in y/wham~merged is as expected\n-\t\tgit cat-file -p :2:y/wham >expect &&\n-\t\tgit cat-file -p :3:y/wham >other &&\n-\t\t>empty &&\n-\t\ttest_must_fail git merge-file \\\n-\t\t\t-L \"HEAD\" \\\n-\t\t\t-L \"\" \\\n-\t\t\t-L \"B^0\" \\\n-\t\t\texpect empty other &&\n-\t\ttest_cmp expect y/wham~merged\n+\t\ttest_seq 1 10 >expected &&\n+\t\techo important >>expected &&\n+\t\ttest_cmp expected y/wham\n \t)\n '\n \ndiff --git a/t/t6436-merge-overwrite.sh b/t/t6436-merge-overwrite.sh\nindex dd8ab7ede1..dd9376842f 100755\n--- a/t/t6436-merge-overwrite.sh\n+++ b/t/t6436-merge-overwrite.sh\n@@ -97,11 +97,19 @@ test_expect_success 'will not overwrite unstaged changes in renamed file' '\n \tgit mv c1.c other.c &&\n \tgit commit -m rename &&\n \tcp important other.c &&\n-\ttest_must_fail git merge c1a >out &&\n-\ttest_i18ngrep \"Refusing to lose dirty file at other.c\" out &&\n-\ttest_path_is_file other.c~HEAD &&\n-\ttest $(git hash-object other.c~HEAD) = $(git rev-parse c1a:c1.c) &&\n-\ttest_cmp important other.c\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\ttest_must_fail git merge c1a >out 2>err &&\n+\t\ttest_i18ngrep \"would be overwritten by merge\" err &&\n+\t\ttest_cmp important other.c &&\n+\t\ttest_path_is_missing .git/MERGE_HEAD\n+\telse\n+\t\ttest_must_fail git merge c1a >out &&\n+\t\ttest_i18ngrep \"Refusing to lose dirty file at other.c\" out &&\n+\t\ttest_path_is_file other.c~HEAD &&\n+\t\ttest $(git hash-object other.c~HEAD) = $(git rev-parse c1a:c1.c) &&\n+\t\ttest_cmp important other.c\n+\tfi\n '\n \n test_expect_success 'will not overwrite untracked subtree' '\n-- \ngitgitgadget\n\n"},{"id":"408414","messageId":"6e308768ff925eb4858be3247976526b21c3a464.1603731704.git.gitgitgadget@gmail.com","threadId":"54492","inReplyTo":"pull.769.v2.git.1603731704.gitgitgadget@gmail.com","subject":"[PATCH v2 9/9] t6423: add more details about direct resolution of directories","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-10-26T17:01:44Z","receivedAt":"2020-10-26T17:02:45Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n t/t6423-merge-rename-directories.sh | 39 +++++++++++++++++------------\n 1 file changed, 23 insertions(+), 16 deletions(-)\n\ndiff --git a/t/t6423-merge-rename-directories.sh b/t/t6423-merge-rename-directories.sh\nindex db694a6316..4ab133f489 100755\n--- a/t/t6423-merge-rename-directories.sh\n+++ b/t/t6423-merge-rename-directories.sh\n@@ -4725,20 +4725,22 @@ test_expect_success '12e: Rename/merge subdir into the root, variant 2' '\n #              folder/subdir/newsubdir/e_Merge2\n #              folder/subdir/tweaked/{h,Makefile_SUB_Merge1,newfile.py}\n #              folder/unchanged/<LOTS OF FILES>\n-#\n-# Notes: This testcase happens to exercise lots of the\n-#        optimization-specific codepaths in merge-ort, and also\n-#        demonstrated a failing of the directory rename detection algorithm\n-#        in merge-recursive; newfile.c should not get pushed into\n-#        folder/subdir/newsubdir/, yet merge-recursive put it there because\n-#        the rename of dir/subdir/{a,b,c,d} -> folder/subdir/{a,b,c,d}\n-#        looks like\n-#            dir/ -> folder/,\n-#        whereas the rename of dir/subdir/e -> folder/subdir/newsubdir/e\n-#        looks like\n-#            dir/subdir/ -> folder/subdir/newsubdir/\n-#        and if we note that newfile.c is found in dir/subdir/, we might\n-#        overlook the dir/ -> folder/ rule that has more weight.\n+# Things being checked here:\n+#   1. dir/subdir/newfile.c does not get pushed into folder/subdir/newsubdir/.\n+#      dir/subdir/{a,b,c,d} -> folder/subdir/{a,b,c,d} looks like\n+#          dir/ -> folder/,\n+#      whereas dir/subdir/e -> folder/subdir/newsubdir/e looks like\n+#          dir/subdir/ -> folder/subdir/newsubdir/\n+#      and if we note that newfile.c is found in dir/subdir/, we might overlook\n+#      the dir/ -> folder/ rule that has more weight.  Older git versions did\n+#      this.\n+#   2. The code to do trivial directory resolves.  Note that\n+#      dir/subdir/unchanged/ is unchanged and can be deleted, and files in the\n+#      new folder/subdir/unchanged/ are not needed as a target to any renames.\n+#      Thus, in the second collect_merge_info_callback() we can just resolve\n+#      these two directories trivially without recursing.)\n+#   3. Exercising the codepaths for caching renames and deletes from one cherry\n+#      pick and re-applying them in the subsequent one.\n \n test_setup_12f () {\n \ttest_create_repo 12f &&\n@@ -4803,7 +4805,7 @@ test_expect_merge_algorithm failure success '12f: Trivial directory resolve, cac\n \t\tgit checkout A^0 &&\n \t\tgit branch Bmod B &&\n \n-\t\tgit -c merge.directoryRenames=true rebase A Bmod &&\n+\t\tGIT_TRACE2_PERF=\"$(pwd)/trace.output\" git -c merge.directoryRenames=true rebase A Bmod &&\n \n \t\techo Checking the pick of B1... &&\n \n@@ -4884,7 +4886,12 @@ test_expect_merge_algorithm failure success '12f: Trivial directory resolve, cac\n \t\ttest_seq  2 12 >e_Merge2 &&\n \t\tgit hash-object e_Merge2 >expect &&\n \t\tgit rev-parse Bmod:folder/subdir/newsubdir/e >actual &&\n-\t\ttest_cmp expect actual\n+\t\ttest_cmp expect actual &&\n+\n+\t\tgrep region_enter.*collect_merge_info trace.output >collect &&\n+\t\ttest_line_count = 4 collect &&\n+\t\tgrep region_enter.*process_entries$ trace.output >process &&\n+\t\ttest_line_count = 2 process\n \t)\n '\n \n-- \ngitgitgadget\n"},{"id":"408415","messageId":"6fd224247d9ccc1e6283a1e5a2c5678a1a0699b6.1603731704.git.gitgitgadget@gmail.com","threadId":"54492","inReplyTo":"pull.769.v2.git.1603731704.gitgitgadget@gmail.com","subject":"[PATCH v2 8/9] t6423: note improved ort handling with untracked files","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-10-26T17:01:43Z","receivedAt":"2020-10-26T17:02:48Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nSimilar to the previous commit, since the \"recursive\" backend relies on\nunpack_trees() to check if unstaged or untracked files would be\noverwritten by a merge, and unpack_trees() does not understand renames\n-- it has false positives and false negatives.  Once it has run, since\nit updates as it goes, merge-recursive then has to handle completing the\nmerge as best it can despite extra changes in the working copy.\nHowever, this is not just an issue for dirty files, but also for\nuntracked files because directory renames can cause file contents to\nneed to be written to a location that was not tracked on either side of\nhistory.\n\nSince the \"ort\" backend does the complete merge inmemory, and only\nupdates the index and working copy as a post-processing step, if there\nare untracked files in the way it can simply abort the merge much like\ncheckout does.\n\nUpdate t6423 to reflect the better merge abilities and expectations for\nort, while still leaving the best-case-as-good-as-recursive-can-do\nexpectations there for the recursive backend so we retain its stability\nuntil we are ready to deprecate and remove it.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n t/t6423-merge-rename-directories.sh | 195 ++++++++++++++++++----------\n 1 file changed, 124 insertions(+), 71 deletions(-)\n\ndiff --git a/t/t6423-merge-rename-directories.sh b/t/t6423-merge-rename-directories.sh\nindex 32e6925ca4..db694a6316 100755\n--- a/t/t6423-merge-rename-directories.sh\n+++ b/t/t6423-merge-rename-directories.sh\n@@ -3214,6 +3214,7 @@ test_expect_success '10a: Overwrite untracked with normal rename/delete' '\n \t\techo important >z/d &&\n \n \t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&\n+\t\ttest_path_is_missing .git/MERGE_HEAD &&\n \t\ttest_i18ngrep \"The following untracked working tree files would be overwritten by merge\" err &&\n \n \t\tgit ls-files -s >out &&\n@@ -3283,21 +3284,34 @@ test_expect_success '10b: Overwrite untracked with dir rename + delete' '\n \t\techo contents >y/e &&\n \n \t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&\n-\t\ttest_i18ngrep \"CONFLICT (rename/delete).*Version B\\^0 of y/d left in tree at y/d~B\\^0\" out &&\n-\t\ttest_i18ngrep \"Error: Refusing to lose untracked file at y/e; writing to y/e~B\\^0 instead\" out &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_path_is_missing .git/MERGE_HEAD &&\n+\t\t\ttest_i18ngrep \"error: The following untracked working tree files would be overwritten by merge\" err &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 3 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 2 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 5 out &&\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 0 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 5 out\n+\t\telse\n+\t\t\ttest_i18ngrep \"CONFLICT (rename/delete).*Version B\\^0 of y/d left in tree at y/d~B\\^0\" out &&\n+\t\t\ttest_i18ngrep \"Error: Refusing to lose untracked file at y/e; writing to y/e~B\\^0 instead\" out &&\n \n-\t\tgit rev-parse >actual \\\n-\t\t\t:0:y/b :3:y/d :3:y/e &&\n-\t\tgit rev-parse >expect \\\n-\t\t\tO:z/b  O:z/c  B:z/e &&\n-\t\ttest_cmp expect actual &&\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 5 out &&\n+\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:y/b :3:y/d :3:y/e &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\tO:z/b  O:z/c  B:z/e &&\n+\t\t\ttest_cmp expect actual\n+\t\tfi &&\n \n \t\techo very >expect &&\n \t\ttest_cmp expect y/c &&\n@@ -3360,25 +3374,38 @@ test_expect_success '10c1: Overwrite untracked with dir rename/rename(1to2)' '\n \t\techo important >y/c &&\n \n \t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&\n-\t\ttest_i18ngrep \"CONFLICT (rename/rename)\" out &&\n-\t\ttest_i18ngrep \"Refusing to lose untracked file at y/c; adding as y/c~B\\^0 instead\" out &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_path_is_missing .git/MERGE_HEAD &&\n+\t\t\ttest_i18ngrep \"error: The following untracked working tree files would be overwritten by merge\" err &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 6 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 3 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 4 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 0 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 3 out\n+\t\telse\n+\t\t\ttest_i18ngrep \"CONFLICT (rename/rename)\" out &&\n+\t\t\ttest_i18ngrep \"Refusing to lose untracked file at y/c; adding as y/c~B\\^0 instead\" out &&\n \n-\t\tgit rev-parse >actual \\\n-\t\t\t:0:y/a :0:y/b :0:x/d :1:x/c :2:w/c :3:y/c &&\n-\t\tgit rev-parse >expect \\\n-\t\t\t O:z/a  O:z/b  O:x/d  O:x/c  O:x/c  O:x/c &&\n-\t\ttest_cmp expect actual &&\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 6 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 3 out &&\n \n-\t\tgit hash-object y/c~B^0 >actual &&\n-\t\tgit rev-parse O:x/c >expect &&\n-\t\ttest_cmp expect actual &&\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:y/a :0:y/b :0:x/d :1:x/c :2:w/c :3:y/c &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t O:z/a  O:z/b  O:x/d  O:x/c  O:x/c  O:x/c &&\n+\t\t\ttest_cmp expect actual &&\n+\n+\t\t\tgit hash-object y/c~B^0 >actual &&\n+\t\t\tgit rev-parse O:x/c >expect &&\n+\t\t\ttest_cmp expect actual\n+\t\tfi &&\n \n \t\techo important >expect &&\n \t\ttest_cmp expect y/c\n@@ -3398,25 +3425,38 @@ test_expect_success '10c2: Overwrite untracked with dir rename/rename(1to2), oth\n \t\techo important >y/c &&\n \n \t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive A^0 >out 2>err &&\n-\t\ttest_i18ngrep \"CONFLICT (rename/rename)\" out &&\n-\t\ttest_i18ngrep \"Refusing to lose untracked file at y/c; adding as y/c~HEAD instead\" out &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_path_is_missing .git/MERGE_HEAD &&\n+\t\t\ttest_i18ngrep \"error: The following untracked working tree files would be overwritten by merge\" err &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 6 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 3 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 4 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 0 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 3 out\n+\t\telse\n+\t\t\ttest_i18ngrep \"CONFLICT (rename/rename)\" out &&\n+\t\t\ttest_i18ngrep \"Refusing to lose untracked file at y/c; adding as y/c~HEAD instead\" out &&\n \n-\t\tgit rev-parse >actual \\\n-\t\t\t:0:y/a :0:y/b :0:x/d :1:x/c :3:w/c :2:y/c &&\n-\t\tgit rev-parse >expect \\\n-\t\t\t O:z/a  O:z/b  O:x/d  O:x/c  O:x/c  O:x/c &&\n-\t\ttest_cmp expect actual &&\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 6 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 3 out &&\n \n-\t\tgit hash-object y/c~HEAD >actual &&\n-\t\tgit rev-parse O:x/c >expect &&\n-\t\ttest_cmp expect actual &&\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:y/a :0:y/b :0:x/d :1:x/c :3:w/c :2:y/c &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t O:z/a  O:z/b  O:x/d  O:x/c  O:x/c  O:x/c &&\n+\t\t\ttest_cmp expect actual &&\n+\n+\t\t\tgit hash-object y/c~HEAD >actual &&\n+\t\t\tgit rev-parse O:x/c >expect &&\n+\t\t\ttest_cmp expect actual\n+\t\tfi &&\n \n \t\techo important >expect &&\n \t\ttest_cmp expect y/c\n@@ -3474,37 +3514,50 @@ test_expect_success '10d: Delete untracked with dir rename/rename(2to1)' '\n \t\techo important >y/wham &&\n \n \t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out 2>err &&\n-\t\ttest_i18ngrep \"CONFLICT (rename/rename)\" out &&\n-\t\ttest_i18ngrep \"Refusing to lose untracked file at y/wham\" out &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_path_is_missing .git/MERGE_HEAD &&\n+\t\t\ttest_i18ngrep \"error: The following untracked working tree files would be overwritten by merge\" err &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 6 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 2 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 6 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 0 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 3 out\n+\t\telse\n+\t\t\ttest_i18ngrep \"CONFLICT (rename/rename)\" out &&\n+\t\t\ttest_i18ngrep \"Refusing to lose untracked file at y/wham\" out &&\n \n-\t\tgit rev-parse >actual \\\n-\t\t\t:0:y/a :0:y/b :0:y/d :0:y/e :2:y/wham :3:y/wham &&\n-\t\tgit rev-parse >expect \\\n-\t\t\t O:z/a  O:z/b  O:x/d  O:x/e  O:z/c     O:x/f &&\n-\t\ttest_cmp expect actual &&\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 6 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 3 out &&\n+\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:y/a :0:y/b :0:y/d :0:y/e :2:y/wham :3:y/wham &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t O:z/a  O:z/b  O:x/d  O:x/e  O:z/c     O:x/f &&\n+\t\t\ttest_cmp expect actual &&\n \n-\t\ttest_must_fail git rev-parse :1:y/wham &&\n+\t\t\ttest_must_fail git rev-parse :1:y/wham &&\n \n-\t\techo important >expect &&\n-\t\ttest_cmp expect y/wham &&\n+\t\t\t# Test that two-way merge in y/wham~merged is as expected\n+\t\t\tgit cat-file -p :2:y/wham >expect &&\n+\t\t\tgit cat-file -p :3:y/wham >other &&\n+\t\t\t>empty &&\n+\t\t\ttest_must_fail git merge-file \\\n+\t\t\t\t-L \"HEAD\" \\\n+\t\t\t\t-L \"\" \\\n+\t\t\t\t-L \"B^0\" \\\n+\t\t\t\texpect empty other &&\n+\t\t\ttest_cmp expect y/wham~merged\n+\t\tfi &&\n \n-\t\t# Test that the two-way merge in y/wham~merged is as expected\n-\t\tgit cat-file -p :2:y/wham >expect &&\n-\t\tgit cat-file -p :3:y/wham >other &&\n-\t\t>empty &&\n-\t\ttest_must_fail git merge-file \\\n-\t\t\t-L \"HEAD\" \\\n-\t\t\t-L \"\" \\\n-\t\t\t-L \"B^0\" \\\n-\t\t\texpect empty other &&\n-\t\ttest_cmp expect y/wham~merged\n+\t\techo important >expect &&\n+\t\ttest_cmp expect y/wham\n \t)\n '\n \n-- \ngitgitgadget\n\n"},{"id":"408416","messageId":"4f32450b085c921219b4639572e8fc2d5150b719.1603731704.git.gitgitgadget@gmail.com","threadId":"54492","inReplyTo":"pull.769.v2.git.1603731704.gitgitgadget@gmail.com","subject":"[PATCH v2 6/9] merge tests: expect slight differences in output for recursive vs. ort","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-10-26T17:01:41Z","receivedAt":"2020-10-26T17:02:53Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nThe ort merge strategy has some slight differences in commit\ndescriptions (shortened hashes), stdout vs stderr, and in conflict\nmessages.  Also, builtin/merge.c reports usage of \"ort\" as \"Merge made\nby the 'ort' strategy\" -- while it is meant as a drop in replacement for\n\"recursive\" it is not yet treated as though it is recursive.  Update the\ntestcases to expect different output for the different merge backends.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n t/t6402-merge-rename.sh       | 14 ++++++++++++--\n t/t6437-submodule-merge.sh    | 25 +++++++++++++++++++++----\n t/t7602-merge-octopus-many.sh |  6 ++++++\n 3 files changed, 39 insertions(+), 6 deletions(-)\n\ndiff --git a/t/t6402-merge-rename.sh b/t/t6402-merge-rename.sh\nindex 47d4434d64..3f64f62224 100755\n--- a/t/t6402-merge-rename.sh\n+++ b/t/t6402-merge-rename.sh\n@@ -320,7 +320,12 @@ test_expect_success 'Rename+D/F conflict; renamed file merges but dir in way' '\n \n \ttest_i18ngrep \"CONFLICT (modify/delete): dir/file-in-the-way\" output &&\n \ttest_i18ngrep \"Auto-merging dir\" output &&\n-\ttest_i18ngrep \"Adding as dir~HEAD instead\" output &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\ttest_i18ngrep \"moving it to dir~HEAD instead\" output\n+\telse\n+\t\ttest_i18ngrep \"Adding as dir~HEAD instead\" output\n+\tfi &&\n \n \ttest 3 -eq \"$(git ls-files -u | wc -l)\" &&\n \ttest 2 -eq \"$(git ls-files -u dir/file-in-the-way | wc -l)\" &&\n@@ -342,7 +347,12 @@ test_expect_success 'Same as previous, but merged other way' '\n \t! grep \"error: refusing to lose untracked file at\" errors &&\n \ttest_i18ngrep \"CONFLICT (modify/delete): dir/file-in-the-way\" output &&\n \ttest_i18ngrep \"Auto-merging dir\" output &&\n-\ttest_i18ngrep \"Adding as dir~renamed-file-has-no-conflicts instead\" output &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\ttest_i18ngrep \"moving it to dir~renamed-file-has-no-conflicts instead\" output\n+\telse\n+\t\ttest_i18ngrep \"Adding as dir~renamed-file-has-no-conflicts instead\" output\n+\tfi &&\n \n \ttest 3 -eq \"$(git ls-files -u | wc -l)\" &&\n \ttest 2 -eq \"$(git ls-files -u dir/file-in-the-way | wc -l)\" &&\ndiff --git a/t/t6437-submodule-merge.sh b/t/t6437-submodule-merge.sh\nindex 6a1e5f8232..3ead2b726f 100755\n--- a/t/t6437-submodule-merge.sh\n+++ b/t/t6437-submodule-merge.sh\n@@ -127,7 +127,12 @@ test_expect_success 'merging should conflict for non fast-forward' '\n \t git checkout -b test-nonforward b &&\n \t (cd sub &&\n \t  git rev-parse sub-d > ../expect) &&\n-\t test_must_fail git merge c 2> actual  &&\n+\t  if test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t  then\n+\t\ttest_must_fail git merge c >actual\n+\t  else\n+\t\ttest_must_fail git merge c 2> actual\n+\t  fi &&\n \t grep $(cat expect) actual > /dev/null &&\n \t git reset --hard)\n '\n@@ -138,9 +143,21 @@ test_expect_success 'merging should fail for ambiguous common parent' '\n \t(cd sub &&\n \t git checkout -b ambiguous sub-b &&\n \t git merge sub-c &&\n-\t git rev-parse sub-d > ../expect1 &&\n-\t git rev-parse ambiguous > ../expect2) &&\n-\ttest_must_fail git merge c 2> actual &&\n+\t if test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t then\n+\t\tgit rev-parse --short sub-d >../expect1 &&\n+\t\tgit rev-parse --short ambiguous >../expect2\n+\t else\n+\t\tgit rev-parse sub-d > ../expect1 &&\n+\t\tgit rev-parse ambiguous > ../expect2\n+\t fi\n+\t ) &&\n+\t if test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t then\n+\t\ttest_must_fail git merge c >actual\n+\t else\n+\t\ttest_must_fail git merge c 2> actual\n+\t fi &&\n \tgrep $(cat expect1) actual > /dev/null &&\n \tgrep $(cat expect2) actual > /dev/null &&\n \tgit reset --hard)\ndiff --git a/t/t7602-merge-octopus-many.sh b/t/t7602-merge-octopus-many.sh\nindex 6abe441ae3..13859ec859 100755\n--- a/t/t7602-merge-octopus-many.sh\n+++ b/t/t7602-merge-octopus-many.sh\n@@ -77,6 +77,12 @@ Merge made by the 'recursive' strategy.\n EOF\n \n test_expect_success 'merge reduces irrelevant remote heads' '\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\tmv expected expected.tmp &&\n+\t\tsed s/recursive/ort/ expected.tmp >expected &&\n+\t\trm expected.tmp\n+\tfi &&\n \tGIT_MERGE_VERBOSITY=0 git merge c4 c5 >actual &&\n \ttest_i18ncmp expected actual\n '\n-- \ngitgitgadget\n\n"},{"id":"408417","messageId":"e8a7d6ac813b2d1c29c3cca6fc1ea27cb6f48a40.1603731704.git.gitgitgadget@gmail.com","threadId":"54492","inReplyTo":"pull.769.v2.git.1603731704.gitgitgadget@gmail.com","subject":"[PATCH v2 5/9] t6423: expect improved conflict markers labels in the ort backend","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-10-26T17:01:40Z","receivedAt":"2020-10-26T17:02:54Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nConflict markers carry an extra annotation of the form\n   REF-OR-COMMIT:FILENAME\nto help distinguish where the content is coming from, with the :FILENAME\npiece being left off if it is the same for both sides of history (thus\nonly renames with content conflicts carry that part of the annotation).\nHowever, there were cases where the :FILENAME annotation was\naccidentally left off, due to merge-recursive's\nevery-codepath-needs-a-copy-of-all-special-case-code format.\n\nUpdate a few tests to have the correct :FILENAME extension on relevant\npaths with the ort backend, while leaving the expectation for\nmerge-recursive the same to avoid destabilizing it.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n t/t6423-merge-rename-directories.sh | 38 +++++++++++++++++++++--------\n 1 file changed, 28 insertions(+), 10 deletions(-)\n\ndiff --git a/t/t6423-merge-rename-directories.sh b/t/t6423-merge-rename-directories.sh\nindex f9a3f24039..7e32626913 100755\n--- a/t/t6423-merge-rename-directories.sh\n+++ b/t/t6423-merge-rename-directories.sh\n@@ -302,11 +302,20 @@ test_expect_success '1d: Directory renames cause a rename/rename(2to1) conflict'\n \t\tgit cat-file -p :2:x/wham >expect &&\n \t\tgit cat-file -p :3:x/wham >other &&\n \t\t>empty &&\n-\t\ttest_must_fail git merge-file \\\n-\t\t\t-L \"HEAD\" \\\n-\t\t\t-L \"\" \\\n-\t\t\t-L \"B^0\" \\\n-\t\t\texpect empty other &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_must_fail git merge-file \\\n+\t\t\t\t-L \"HEAD:y/wham\" \\\n+\t\t\t\t-L \"\" \\\n+\t\t\t\t-L \"B^0:z/wham\" \\\n+\t\t\t\texpect empty other\n+\t\telse\n+\t\t\ttest_must_fail git merge-file \\\n+\t\t\t\t-L \"HEAD\" \\\n+\t\t\t\t-L \"\" \\\n+\t\t\t\t-L \"B^0\" \\\n+\t\t\t\texpect empty other\n+\t\tfi &&\n \t\ttest_cmp expect x/wham\n \t)\n '\n@@ -1823,11 +1832,20 @@ test_expect_success '7b: rename/rename(2to1), but only due to transitive rename'\n \t\tgit cat-file -p :2:y/d >expect &&\n \t\tgit cat-file -p :3:y/d >other &&\n \t\t>empty &&\n-\t\ttest_must_fail git merge-file \\\n-\t\t\t-L \"HEAD\" \\\n-\t\t\t-L \"\" \\\n-\t\t\t-L \"B^0\" \\\n-\t\t\texpect empty other &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_must_fail git merge-file \\\n+\t\t\t\t-L \"HEAD:y/d\" \\\n+\t\t\t\t-L \"\" \\\n+\t\t\t\t-L \"B^0:z/d\" \\\n+\t\t\t\texpect empty other\n+\t\telse\n+\t\t\ttest_must_fail git merge-file \\\n+\t\t\t\t-L \"HEAD\" \\\n+\t\t\t\t-L \"\" \\\n+\t\t\t\t-L \"B^0\" \\\n+\t\t\t\texpect empty other\n+\t\tfi &&\n \t\ttest_cmp expect y/d\n \t)\n '\n-- \ngitgitgadget\n\n"},{"id":"408418","messageId":"6e47fa19f84a2017cad728aaa8170fb23aca45c7.1603731704.git.gitgitgadget@gmail.com","threadId":"54492","inReplyTo":"pull.769.v2.git.1603731704.gitgitgadget@gmail.com","subject":"[PATCH v2 4/9] t6404, t6423: expect improved rename/delete handling in ort backend","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-10-26T17:01:39Z","receivedAt":"2020-10-26T17:02:56Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nWhen a file is renamed and has content conflicts, merge-recursive does\nnot have some stages for the old filename and some stages for the new\nfilename in the index; instead it copies all the stages corresponding to\nthe old filename over to the corresponding locations for the new\nfilename, so that there are three higher order stages all corresponding\nto the new filename.  Doing things this way makes it easier for the user\nto access the different versions and to resolve the conflict (no need to\nmanually 'git rm' the old version as well as 'git add' the new one).\n\nrename/deletes should be handled similarly -- there should be two stages\nfor the renamed file rather than just one.  We do not want to\ndestabilize merge-recursive right now, so instead update relevant tests\nto have different expectations depending on whether the \"recursive\" or\n\"ort\" merge strategies are in use.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n t/t6404-recursive-merge.sh          | 14 +++++-\n t/t6423-merge-rename-directories.sh | 70 ++++++++++++++++++++---------\n 2 files changed, 62 insertions(+), 22 deletions(-)\n\ndiff --git a/t/t6404-recursive-merge.sh b/t/t6404-recursive-merge.sh\nindex 332cfc53fd..b1c3d4dda4 100755\n--- a/t/t6404-recursive-merge.sh\n+++ b/t/t6404-recursive-merge.sh\n@@ -118,12 +118,22 @@ test_expect_success 'mark rename/delete as unmerged' '\n \ttest_tick &&\n \tgit commit -m rename &&\n \ttest_must_fail git merge delete &&\n-\ttest 1 = $(git ls-files --unmerged | wc -l) &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\ttest 2 = $(git ls-files --unmerged | wc -l)\n+\telse\n+\t\ttest 1 = $(git ls-files --unmerged | wc -l)\n+\tfi &&\n \tgit rev-parse --verify :2:a2 &&\n \ttest_must_fail git rev-parse --verify :3:a2 &&\n \tgit checkout -f delete &&\n \ttest_must_fail git merge rename &&\n-\ttest 1 = $(git ls-files --unmerged | wc -l) &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\ttest 2 = $(git ls-files --unmerged | wc -l)\n+\telse\n+\t\ttest 1 = $(git ls-files --unmerged | wc -l)\n+\tfi &&\n \ttest_must_fail git rev-parse --verify :2:a2 &&\n \tgit rev-parse --verify :3:a2\n '\ndiff --git a/t/t6423-merge-rename-directories.sh b/t/t6423-merge-rename-directories.sh\nindex 5ea77564d7..f9a3f24039 100755\n--- a/t/t6423-merge-rename-directories.sh\n+++ b/t/t6423-merge-rename-directories.sh\n@@ -1271,17 +1271,32 @@ test_expect_success '6a: Tricky rename/delete' '\n \t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&\n \t\ttest_i18ngrep \"CONFLICT (rename/delete).*z/c.*y/c\" out &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 2 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 1 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 1 out &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 1 out &&\n \n-\t\tgit rev-parse >actual \\\n-\t\t\t:0:y/b :3:y/c &&\n-\t\tgit rev-parse >expect \\\n-\t\t\t O:z/b  O:z/c &&\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:y/b :1:y/c :3:y/c &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t O:z/b  O:z/c  O:z/c\n+\t\telse\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:y/b :3:y/c &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t O:z/b  O:z/c\n+\t\tfi &&\n \t\ttest_cmp expect actual\n \t)\n '\n@@ -1934,17 +1949,32 @@ test_expect_success '7d: transitive rename involved in rename/delete; how is it\n \t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&\n \t\ttest_i18ngrep \"CONFLICT (rename/delete).*x/d.*y/d\" out &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 3 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 1 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 1 out &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 4 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 1 out &&\n \n-\t\tgit rev-parse >actual \\\n-\t\t\t:0:y/b :0:y/c :3:y/d &&\n-\t\tgit rev-parse >expect \\\n-\t\t\t O:z/b  O:z/c  O:x/d &&\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:y/b :0:y/c :1:y/d :3:y/d &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t O:z/b  O:z/c  O:x/d  O:x/d\n+\t\telse\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:y/b :0:y/c :3:y/d &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t O:z/b  O:z/c  O:x/d\n+\t\tfi &&\n \t\ttest_cmp expect actual\n \t)\n '\n-- \ngitgitgadget\n\n"},{"id":"408419","messageId":"f27f12e8e50e56c010c29caa00296475d4de205b.1603731704.git.gitgitgadget@gmail.com","threadId":"54492","inReplyTo":"pull.769.v2.git.1603731704.gitgitgadget@gmail.com","subject":"[PATCH v2 2/9] merge tests: expect improved directory/file conflict handling in ort","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-10-26T17:01:37Z","receivedAt":"2020-10-26T17:02:57Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nmerge-recursive.c is built on the idea of running unpack_trees() and\nthen \"doing minor touch-ups\" to get the result.  Unfortunately,\nunpack_trees() was run in an update-as-it-goes mode, leading\nmerge-recursive.c to follow suit and end up with an immediate evaluation\nand fix-it-up-as-you-go design.  Some things like directory/file\nconflicts are not well representable in the index data structure, and\nrequired special extra code to handle.  But then when it was discovered\nthat rename/delete conflicts could also be involved in directory/file\nconflicts, the special directory/file conflict handling code had to be\ncopied to the rename/delete codepath.  ...and then it had to be copied\nfor modify/delete, and for rename/rename(1to2) conflicts, ...and yet it\nstill missed some.  Further, when it was discovered that there were also\nfile/submodule conflicts and submodule/directory conflicts, we needed to\ncopy the special submodule handling code to all the special cases\nthroughout the codebase.\n\nAnd then it was discovered that our handling of directory/file conflicts\nwas suboptimal because it would create untracked files to store the\ncontents of the conflicting file, which would not be cleaned up if\nsomeone were to run a 'git merge --abort' or 'git rebase --abort'.  It\nwas also difficult or scary to try to add or remove the index entries\ncorresponding to these files given the directory/file conflict in the\nindex.  But changing merge-recursive.c to handle these correctly was a\nroyal pain because there were so many sites in the code with similar but\nnot identical code for handling directory/file/submodule conflicts that\nwould all need to be updated.\n\nI have worked hard to push all directory/file/submodule conflict\nhandling in merge-ort through a single codepath, and avoid creating\nuntracked files for storing tracked content (it does record things at\nalternate paths, but makes sure they have higher-order stages in the\nindex).\n\nSince updating merge-recursive is too much work and we don't want to\ndestabilize it, instead update the testsuite to have different\nexpectations for relevant directory/file/submodule conflict tests.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n t/t6400-merge-df.sh                  |  14 +-\n t/t6402-merge-rename.sh              | 108 ++++++++++++----\n t/t6416-recursive-corner-cases.sh    | 185 +++++++++++++++++++--------\n t/t6422-merge-rename-corner-cases.sh |  30 +++--\n t/t6423-merge-rename-directories.sh  |  53 +++++---\n t/t7610-mergetool.sh                 |  32 ++++-\n 6 files changed, 314 insertions(+), 108 deletions(-)\n\ndiff --git a/t/t6400-merge-df.sh b/t/t6400-merge-df.sh\nindex f1b84617af..9da0838216 100755\n--- a/t/t6400-merge-df.sh\n+++ b/t/t6400-merge-df.sh\n@@ -81,7 +81,12 @@ test_expect_success 'modify/delete + directory/file conflict' '\n \n \ttest 5 -eq $(git ls-files -s | wc -l) &&\n \ttest 4 -eq $(git ls-files -u | wc -l) &&\n-\ttest 1 -eq $(git ls-files -o | wc -l) &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\ttest 0 -eq $(git ls-files -o | wc -l)\n+\telse\n+\t\ttest 1 -eq $(git ls-files -o | wc -l)\n+\tfi &&\n \n \ttest_path_is_file letters/file &&\n \ttest_path_is_file letters.txt &&\n@@ -97,7 +102,12 @@ test_expect_success 'modify/delete + directory/file conflict; other way' '\n \n \ttest 5 -eq $(git ls-files -s | wc -l) &&\n \ttest 4 -eq $(git ls-files -u | wc -l) &&\n-\ttest 1 -eq $(git ls-files -o | wc -l) &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\ttest 0 -eq $(git ls-files -o | wc -l)\n+\telse\n+\t\ttest 1 -eq $(git ls-files -o | wc -l)\n+\tfi &&\n \n \ttest_path_is_file letters/file &&\n \ttest_path_is_file letters.txt &&\ndiff --git a/t/t6402-merge-rename.sh b/t/t6402-merge-rename.sh\nindex bbbba3dcbf..47d4434d64 100755\n--- a/t/t6402-merge-rename.sh\n+++ b/t/t6402-merge-rename.sh\n@@ -397,7 +397,12 @@ test_expect_success 'Rename+D/F conflict; renamed file cannot merge and dir in t\n \ttest_must_fail git merge --strategy=recursive dir-in-way &&\n \n \ttest 5 -eq \"$(git ls-files -u | wc -l)\" &&\n-\ttest 3 -eq \"$(git ls-files -u dir | grep -v file-in-the-way | wc -l)\" &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\ttest 3 -eq \"$(git ls-files -u dir~HEAD | wc -l)\"\n+\telse\n+\t\ttest 3 -eq \"$(git ls-files -u dir | grep -v file-in-the-way | wc -l)\"\n+\tfi &&\n \ttest 2 -eq \"$(git ls-files -u dir/file-in-the-way | wc -l)\" &&\n \n \ttest_must_fail git diff --quiet &&\n@@ -415,7 +420,12 @@ test_expect_success 'Same as previous, but merged other way' '\n \ttest_must_fail git merge --strategy=recursive renamed-file-has-conflicts &&\n \n \ttest 5 -eq \"$(git ls-files -u | wc -l)\" &&\n-\ttest 3 -eq \"$(git ls-files -u dir | grep -v file-in-the-way | wc -l)\" &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\ttest 3 -eq \"$(git ls-files -u dir~renamed-file-has-conflicts | wc -l)\"\n+\telse\n+\t\ttest 3 -eq \"$(git ls-files -u dir | grep -v file-in-the-way | wc -l)\"\n+\tfi &&\n \ttest 2 -eq \"$(git ls-files -u dir/file-in-the-way | wc -l)\" &&\n \n \ttest_must_fail git diff --quiet &&\n@@ -471,7 +481,12 @@ test_expect_success 'both rename source and destination involved in D/F conflict\n \tgit checkout -q rename-dest^0 &&\n \ttest_must_fail git merge --strategy=recursive source-conflict &&\n \n-\ttest 1 -eq \"$(git ls-files -u | wc -l)\" &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\ttest 2 -eq \"$(git ls-files -u | wc -l)\"\n+\telse\n+\t\ttest 1 -eq \"$(git ls-files -u | wc -l)\"\n+\tfi &&\n \n \ttest_must_fail git diff --quiet &&\n \n@@ -505,34 +520,63 @@ test_expect_success 'setup pair rename to parent of other (D/F conflicts)' '\n \tgit commit -m \"Rename one/file -> two\"\n '\n \n-test_expect_success 'pair rename to parent of other (D/F conflicts) w/ untracked dir' '\n-\tgit checkout -q rename-one^0 &&\n-\tmkdir one &&\n-\ttest_must_fail git merge --strategy=recursive rename-two &&\n+if test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+then\n+\ttest_expect_success 'pair rename to parent of other (D/F conflicts) w/ untracked dir' '\n+\t\tgit checkout -q rename-one^0 &&\n+\t\tmkdir one &&\n+\t\ttest_must_fail git merge --strategy=recursive rename-two &&\n \n-\ttest 2 -eq \"$(git ls-files -u | wc -l)\" &&\n-\ttest 1 -eq \"$(git ls-files -u one | wc -l)\" &&\n-\ttest 1 -eq \"$(git ls-files -u two | wc -l)\" &&\n+\t\ttest 4 -eq \"$(git ls-files -u | wc -l)\" &&\n+\t\ttest 2 -eq \"$(git ls-files -u one | wc -l)\" &&\n+\t\ttest 2 -eq \"$(git ls-files -u two | wc -l)\" &&\n \n-\ttest_must_fail git diff --quiet &&\n+\t\ttest_must_fail git diff --quiet &&\n \n-\ttest 4 -eq $(find . | grep -v .git | wc -l) &&\n+\t\ttest 3 -eq $(find . | grep -v .git | wc -l) &&\n \n-\ttest_path_is_dir one &&\n-\ttest_path_is_file one~rename-two &&\n-\ttest_path_is_file two &&\n-\ttest \"other\" = $(cat one~rename-two) &&\n-\ttest \"stuff\" = $(cat two)\n-'\n+\t\ttest_path_is_file one &&\n+\t\ttest_path_is_file two &&\n+\t\ttest \"other\" = $(cat one) &&\n+\t\ttest \"stuff\" = $(cat two)\n+\t'\n+else\n+\ttest_expect_success 'pair rename to parent of other (D/F conflicts) w/ untracked dir' '\n+\t\tgit checkout -q rename-one^0 &&\n+\t\tmkdir one &&\n+\t\ttest_must_fail git merge --strategy=recursive rename-two &&\n+\n+\t\ttest 2 -eq \"$(git ls-files -u | wc -l)\" &&\n+\t\ttest 1 -eq \"$(git ls-files -u one | wc -l)\" &&\n+\t\ttest 1 -eq \"$(git ls-files -u two | wc -l)\" &&\n+\n+\t\ttest_must_fail git diff --quiet &&\n+\n+\t\ttest 4 -eq $(find . | grep -v .git | wc -l) &&\n+\n+\t\ttest_path_is_dir one &&\n+\t\ttest_path_is_file one~rename-two &&\n+\t\ttest_path_is_file two &&\n+\t\ttest \"other\" = $(cat one~rename-two) &&\n+\t\ttest \"stuff\" = $(cat two)\n+\t'\n+fi\n \n test_expect_success 'pair rename to parent of other (D/F conflicts) w/ clean start' '\n \tgit reset --hard &&\n \tgit clean -fdqx &&\n \ttest_must_fail git merge --strategy=recursive rename-two &&\n \n-\ttest 2 -eq \"$(git ls-files -u | wc -l)\" &&\n-\ttest 1 -eq \"$(git ls-files -u one | wc -l)\" &&\n-\ttest 1 -eq \"$(git ls-files -u two | wc -l)\" &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\ttest 4 -eq \"$(git ls-files -u | wc -l)\" &&\n+\t\ttest 2 -eq \"$(git ls-files -u one | wc -l)\" &&\n+\t\ttest 2 -eq \"$(git ls-files -u two | wc -l)\"\n+\telse\n+\t\ttest 2 -eq \"$(git ls-files -u | wc -l)\" &&\n+\t\ttest 1 -eq \"$(git ls-files -u one | wc -l)\" &&\n+\t\ttest 1 -eq \"$(git ls-files -u two | wc -l)\"\n+\tfi &&\n \n \ttest_must_fail git diff --quiet &&\n \n@@ -572,12 +616,22 @@ test_expect_success 'check handling of differently renamed file with D/F conflic\n \tgit checkout -q first-rename^0 &&\n \ttest_must_fail git merge --strategy=recursive second-rename &&\n \n-\ttest 5 -eq \"$(git ls-files -s | wc -l)\" &&\n-\ttest 3 -eq \"$(git ls-files -u | wc -l)\" &&\n-\ttest 1 -eq \"$(git ls-files -u one | wc -l)\" &&\n-\ttest 1 -eq \"$(git ls-files -u two | wc -l)\" &&\n-\ttest 1 -eq \"$(git ls-files -u original | wc -l)\" &&\n-\ttest 2 -eq \"$(git ls-files -o | wc -l)\" &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\ttest 5 -eq \"$(git ls-files -s | wc -l)\" &&\n+\t\ttest 3 -eq \"$(git ls-files -u | wc -l)\" &&\n+\t\ttest 1 -eq \"$(git ls-files -u one~HEAD | wc -l)\" &&\n+\t\ttest 1 -eq \"$(git ls-files -u two~second-rename | wc -l)\" &&\n+\t\ttest 1 -eq \"$(git ls-files -u original | wc -l)\" &&\n+\t\ttest 0 -eq \"$(git ls-files -o | wc -l)\"\n+\telse\n+\t\ttest 5 -eq \"$(git ls-files -s | wc -l)\" &&\n+\t\ttest 3 -eq \"$(git ls-files -u | wc -l)\" &&\n+\t\ttest 1 -eq \"$(git ls-files -u one | wc -l)\" &&\n+\t\ttest 1 -eq \"$(git ls-files -u two | wc -l)\" &&\n+\t\ttest 1 -eq \"$(git ls-files -u original | wc -l)\" &&\n+\t\ttest 2 -eq \"$(git ls-files -o | wc -l)\"\n+\tfi &&\n \n \ttest_path_is_file one/file &&\n \ttest_path_is_file two/file &&\ndiff --git a/t/t6416-recursive-corner-cases.sh b/t/t6416-recursive-corner-cases.sh\nindex 8b3a4fc843..0317e83970 100755\n--- a/t/t6416-recursive-corner-cases.sh\n+++ b/t/t6416-recursive-corner-cases.sh\n@@ -538,9 +538,15 @@ test_expect_success 'setup differently handled merges of directory/file conflict\n \n \t\tgit checkout B^0 &&\n \t\ttest_must_fail git merge C^0 &&\n-\t\tgit clean -fd &&\n-\t\tgit rm -rf a/ &&\n-\t\tgit rm a &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\tgit rm -rf a/ &&\n+\t\t\tgit rm a~HEAD\n+\t\telse\n+\t\t\tgit clean -fd &&\n+\t\t\tgit rm -rf a/ &&\n+\t\t\tgit rm a\n+\t\tfi &&\n \t\tgit cat-file -p B:a >a2 &&\n \t\tgit add a2 &&\n \t\tgit commit -m D2 &&\n@@ -559,7 +565,12 @@ test_expect_success 'setup differently handled merges of directory/file conflict\n \n \t\tgit checkout C^0 &&\n \t\ttest_must_fail git merge B^0 &&\n-\t\tgit clean -fd &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\tgit rm a~B^0\n+\t\telse\n+\t\t\tgit clean -fd\n+\t\tfi &&\n \t\tgit rm -rf a/ &&\n \t\ttest_write_lines 1 2 3 4 5 6 7 8 >a &&\n \t\tgit add a &&\n@@ -568,9 +579,15 @@ test_expect_success 'setup differently handled merges of directory/file conflict\n \n \t\tgit checkout C^0 &&\n \t\ttest_must_fail git merge B^0 &&\n-\t\tgit clean -fd &&\n-\t\tgit rm -rf a/ &&\n-\t\tgit rm a &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\tgit rm -rf a/ &&\n+\t\t\tgit rm a~B^0\n+\t\telse\n+\t\t\tgit clean -fd &&\n+\t\t\tgit rm -rf a/ &&\n+\t\t\tgit rm a\n+\t\tfi &&\n \t\ttest_write_lines 1 2 3 4 5 6 7 8 >a2 &&\n \t\tgit add a2 &&\n \t\tgit commit -m E4 &&\n@@ -588,18 +605,34 @@ test_expect_success 'merge of D1 & E1 fails but has appropriate contents' '\n \n \t\ttest_must_fail git merge -s recursive E1^0 &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 2 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 1 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 1 out &&\n-\n-\t\tgit rev-parse >expect    \\\n-\t\t\tA:ignore-me  B:a &&\n-\t\tgit rev-parse   >actual   \\\n-\t\t\t:0:ignore-me :2:a &&\n-\t\ttest_cmp expect actual\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\n+\t\t\tgit rev-parse >expect    \\\n+\t\t\t\tA:ignore-me  B:a  D1:a &&\n+\t\t\tgit rev-parse   >actual   \\\n+\t\t\t\t:0:ignore-me :1:a :2:a &&\n+\t\t\ttest_cmp expect actual\n+\t\telse\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\n+\t\t\tgit rev-parse >expect    \\\n+\t\t\t\tA:ignore-me  B:a &&\n+\t\t\tgit rev-parse   >actual   \\\n+\t\t\t\t:0:ignore-me :2:a &&\n+\t\t\ttest_cmp expect actual\n+\t\tfi\n \t)\n '\n \n@@ -613,18 +646,34 @@ test_expect_success 'merge of E1 & D1 fails but has appropriate contents' '\n \n \t\ttest_must_fail git merge -s recursive D1^0 &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 2 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 1 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 1 out &&\n-\n-\t\tgit rev-parse >expect    \\\n-\t\t\tA:ignore-me  B:a &&\n-\t\tgit rev-parse   >actual   \\\n-\t\t\t:0:ignore-me :3:a &&\n-\t\ttest_cmp expect actual\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\n+\t\t\tgit rev-parse >expect    \\\n+\t\t\t\tA:ignore-me  B:a  D1:a &&\n+\t\t\tgit rev-parse   >actual   \\\n+\t\t\t\t:0:ignore-me :1:a :3:a &&\n+\t\t\ttest_cmp expect actual\n+\t\telse\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\n+\t\t\tgit rev-parse >expect    \\\n+\t\t\t\tA:ignore-me  B:a &&\n+\t\t\tgit rev-parse   >actual   \\\n+\t\t\t\t:0:ignore-me :3:a &&\n+\t\t\ttest_cmp expect actual\n+\t\tfi\n \t)\n '\n \n@@ -638,17 +687,32 @@ test_expect_success 'merge of D1 & E2 fails but has appropriate contents' '\n \n \t\ttest_must_fail git merge -s recursive E2^0 &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 4 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 3 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 2 out &&\n-\n-\t\tgit rev-parse >expect    \\\n-\t\t\tB:a   E2:a/file  C:a/file   A:ignore-me &&\n-\t\tgit rev-parse   >actual   \\\n-\t\t\t:2:a  :3:a/file  :1:a/file  :0:ignore-me &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 5 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 4 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\n+\t\t\tgit rev-parse >expect    \\\n+\t\t\t\tB:a       D1:a      E2:a/file  C:a/file   A:ignore-me &&\n+\t\t\tgit rev-parse   >actual   \\\n+\t\t\t\t:1:a~HEAD :2:a~HEAD :3:a/file  :1:a/file  :0:ignore-me\n+\t\telse\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 4 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\n+\t\t\tgit rev-parse >expect    \\\n+\t\t\t\tB:a    E2:a/file  C:a/file   A:ignore-me &&\n+\t\t\tgit rev-parse   >actual   \\\n+\t\t\t\t:2:a   :3:a/file  :1:a/file  :0:ignore-me\n+\t\tfi &&\n \t\ttest_cmp expect actual &&\n \n \t\ttest_path_is_file a~HEAD\n@@ -665,17 +729,32 @@ test_expect_success 'merge of E2 & D1 fails but has appropriate contents' '\n \n \t\ttest_must_fail git merge -s recursive D1^0 &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 4 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 3 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 2 out &&\n-\n-\t\tgit rev-parse >expect    \\\n-\t\t\tB:a   E2:a/file  C:a/file   A:ignore-me &&\n-\t\tgit rev-parse   >actual   \\\n-\t\t\t:3:a  :2:a/file  :1:a/file  :0:ignore-me &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 5 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 4 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\n+\t\t\tgit rev-parse >expect    \\\n+\t\t\t\tB:a       D1:a      E2:a/file  C:a/file   A:ignore-me &&\n+\t\t\tgit rev-parse   >actual   \\\n+\t\t\t\t:1:a~D1^0 :3:a~D1^0 :2:a/file  :1:a/file  :0:ignore-me\n+\t\telse\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 4 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 3 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\n+\t\t\tgit rev-parse >expect    \\\n+\t\t\t\tB:a   E2:a/file  C:a/file   A:ignore-me &&\n+\t\t\tgit rev-parse   >actual   \\\n+\t\t\t\t:3:a  :2:a/file  :1:a/file  :0:ignore-me\n+\t\tfi &&\n \t\ttest_cmp expect actual &&\n \n \t\ttest_path_is_file a~D1^0\ndiff --git a/t/t6422-merge-rename-corner-cases.sh b/t/t6422-merge-rename-corner-cases.sh\nindex 58729593ba..78bfaf17f0 100755\n--- a/t/t6422-merge-rename-corner-cases.sh\n+++ b/t/t6422-merge-rename-corner-cases.sh\n@@ -313,15 +313,18 @@ test_expect_success 'rename/directory conflict + clean content merge' '\n \t\tgit ls-files -u >out &&\n \t\ttest_line_count = 1 out &&\n \t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 2 out &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_line_count = 1 out\n+\t\telse\n+\t\t\ttest_line_count = 2 out\n+\t\tfi &&\n \n \t\techo 0 >expect &&\n \t\tgit cat-file -p base:file >>expect &&\n \t\techo 7 >>expect &&\n \t\ttest_cmp expect newfile~HEAD &&\n \n-\t\ttest $(git rev-parse :2:newfile) = $(git hash-object expect) &&\n-\n \t\ttest_path_is_file newfile/realfile &&\n \t\ttest_path_is_file newfile~HEAD\n \t)\n@@ -344,7 +347,12 @@ test_expect_success 'rename/directory conflict + content merge conflict' '\n \t\tgit ls-files -u >out &&\n \t\ttest_line_count = 3 out &&\n \t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 2 out &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_line_count = 1 out\n+\t\telse\n+\t\t\ttest_line_count = 2 out\n+\t\tfi &&\n \n \t\tgit cat-file -p left-conflict:newfile >left &&\n \t\tgit cat-file -p base:file    >base &&\n@@ -356,10 +364,16 @@ test_expect_success 'rename/directory conflict + content merge conflict' '\n \t\t\tleft base right &&\n \t\ttest_cmp left newfile~HEAD &&\n \n-\t\tgit rev-parse >expect                                 \\\n-\t\t\tbase:file   left-conflict:newfile  right:file &&\n-\t\tgit rev-parse >actual                                 \\\n-\t\t\t:1:newfile  :2:newfile             :3:newfile &&\n+\t\tgit rev-parse >expect   \\\n+\t\t\tbase:file       left-conflict:newfile right:file &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:1:newfile~HEAD :2:newfile~HEAD :3:newfile~HEAD\n+\t\telse\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:1:newfile      :2:newfile      :3:newfile\n+\t\tfi &&\n \t\ttest_cmp expect actual &&\n \n \t\ttest_path_is_file newfile/realfile &&\ndiff --git a/t/t6423-merge-rename-directories.sh b/t/t6423-merge-rename-directories.sh\nindex 807a424a52..5ea77564d7 100755\n--- a/t/t6423-merge-rename-directories.sh\n+++ b/t/t6423-merge-rename-directories.sh\n@@ -1177,10 +1177,18 @@ test_expect_success '5d: Directory/file/file conflict due to directory rename' '\n \t\tgit ls-files -u >out &&\n \t\ttest_line_count = 1 out &&\n \t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 2 out &&\n-\n-\t\tgit rev-parse >actual \\\n-\t\t\t:0:y/b :0:y/c :0:z/d :0:y/f :2:y/d :0:y/d/e &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\ttest_line_count = 1 out &&\n+\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t    :0:y/b :0:y/c :0:z/d :0:y/f :2:y/d~HEAD :0:y/d/e\n+\t\telse\n+\t\t\ttest_line_count = 2 out &&\n+\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t    :0:y/b :0:y/c :0:z/d :0:y/f :2:y/d      :0:y/d/e\n+\t\tfi &&\n \t\tgit rev-parse >expect \\\n \t\t\t O:z/b  O:z/c  B:z/d  B:z/f  A:y/d  B:y/d/e &&\n \t\ttest_cmp expect actual &&\n@@ -2017,17 +2025,32 @@ test_expect_success '7e: transitive rename in rename/delete AND dirs in the way'\n \t\ttest_must_fail git -c merge.directoryRenames=true merge -s recursive B^0 >out &&\n \t\ttest_i18ngrep \"CONFLICT (rename/delete).*x/d.*y/d\" out &&\n \n-\t\tgit ls-files -s >out &&\n-\t\ttest_line_count = 5 out &&\n-\t\tgit ls-files -u >out &&\n-\t\ttest_line_count = 1 out &&\n-\t\tgit ls-files -o >out &&\n-\t\ttest_line_count = 2 out &&\n-\n-\t\tgit rev-parse >actual \\\n-\t\t\t:0:x/d/f :0:y/d/g :0:y/b :0:y/c :3:y/d &&\n-\t\tgit rev-parse >expect \\\n-\t\t\t A:x/d/f  A:y/d/g  O:z/b  O:z/c  O:x/d &&\n+\t\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\t\tthen\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 6 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:x/d/f :0:y/d/g :0:y/b :0:y/c :1:y/d~B^0 :3:y/d~B^0 &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t A:x/d/f  A:y/d/g  O:z/b  O:z/c  O:x/d      O:x/d\n+\t\telse\n+\t\t\tgit ls-files -s >out &&\n+\t\t\ttest_line_count = 5 out &&\n+\t\t\tgit ls-files -u >out &&\n+\t\t\ttest_line_count = 1 out &&\n+\t\t\tgit ls-files -o >out &&\n+\t\t\ttest_line_count = 2 out &&\n+\n+\t\t\tgit rev-parse >actual \\\n+\t\t\t\t:0:x/d/f :0:y/d/g :0:y/b :0:y/c :3:y/d &&\n+\t\t\tgit rev-parse >expect \\\n+\t\t\t\t A:x/d/f  A:y/d/g  O:z/b  O:z/c  O:x/d\n+\t\tfi &&\n \t\ttest_cmp expect actual &&\n \n \t\tgit hash-object y/d~B^0 >actual &&\ndiff --git a/t/t7610-mergetool.sh b/t/t7610-mergetool.sh\nindex ad288ddc69..70afdd06fa 100755\n--- a/t/t7610-mergetool.sh\n+++ b/t/t7610-mergetool.sh\n@@ -532,7 +532,14 @@ test_expect_success 'file vs modified submodule' '\n \tyes \"\" | git mergetool file1 file2 spaced\\ name subdir/file3 &&\n \tyes \"\" | git mergetool both &&\n \tyes \"d\" | git mergetool file11 file12 &&\n-\tyes \"l\" | git mergetool submod &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\tyes \"c\" | git mergetool submod~HEAD &&\n+\t\tgit rm submod &&\n+\t\tgit mv submod~HEAD submod\n+\telse\n+\t\tyes \"l\" | git mergetool submod\n+\tfi &&\n \tgit submodule update -N &&\n \techo \"not a submodule\" >expect &&\n \ttest_cmp expect submod &&\n@@ -549,7 +556,15 @@ test_expect_success 'file vs modified submodule' '\n \tyes \"\" | git mergetool file1 file2 spaced\\ name subdir/file3 &&\n \tyes \"\" | git mergetool both &&\n \tyes \"d\" | git mergetool file11 file12 &&\n-\tyes \"r\" | git mergetool submod &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\tmv submod submod.orig &&\n+\t\tgit rm --cached submod &&\n+\t\tyes \"c\" | git mergetool submod~test19 &&\n+\t\tgit mv submod~test19 submod\n+\telse\n+\t\tyes \"r\" | git mergetool submod\n+\tfi &&\n \ttest -d submod.orig &&\n \tgit submodule update -N &&\n \techo \"not a submodule\" >expect &&\n@@ -567,6 +582,10 @@ test_expect_success 'file vs modified submodule' '\n \tyes \"\" | git mergetool both &&\n \tyes \"d\" | git mergetool file11 file12 &&\n \tyes \"l\" | git mergetool submod &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\tyes \"d\" | git mergetool submod~test19\n+\tfi &&\n \techo \"master submodule\" >expect &&\n \ttest_cmp expect submod/bar &&\n \tgit submodule update -N &&\n@@ -664,7 +683,14 @@ test_expect_success 'directory vs modified submodule' '\n \ttest_must_fail git merge master &&\n \ttest -n \"$(git ls-files -u)\" &&\n \ttest ! -e submod.orig &&\n-\tyes \"r\" | git mergetool submod &&\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\tyes \"r\" | git mergetool submod~master &&\n+\t\tgit mv submod submod.orig &&\n+\t\tgit mv submod~master submod\n+\telse\n+\t\tyes \"r\" | git mergetool submod\n+\tfi &&\n \ttest -d submod.orig &&\n \techo \"not a submodule\" >expect &&\n \ttest_cmp expect submod.orig/file16 &&\n-- \ngitgitgadget\n\n"},{"id":"408420","messageId":"f5d32952629e58074032e5c736b7f0405d935f5d.1603731704.git.gitgitgadget@gmail.com","threadId":"54492","inReplyTo":"pull.769.v2.git.1603731704.gitgitgadget@gmail.com","subject":"[PATCH v2 1/9] t/: new helper for tests that pass with ort but fail with recursive","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-10-26T17:01:36Z","receivedAt":"2020-10-26T17:02:59Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nThere are a number of tests that the \"recursive\" backend does not handle\ncorrectly but which the redesign in \"ort\" will.  Add a new helper in\nlib-merge.sh for selecting a different test expectation based on the\nsetting of GIT_TEST_MERGE_ALGORITHM, and use it in various testcases to\ndocument which ones we expect to fail under recursive but pass under\nort.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n t/lib-merge.sh                         | 13 +++++++++++++\n t/t6416-recursive-corner-cases.sh      | 11 ++++++-----\n t/t6422-merge-rename-corner-cases.sh   |  7 ++++---\n t/t6423-merge-rename-directories.sh    | 13 +++++++------\n t/t6426-merge-skip-unneeded-updates.sh |  3 ++-\n t/t6430-merge-recursive.sh             |  3 ++-\n 6 files changed, 34 insertions(+), 16 deletions(-)\n create mode 100644 t/lib-merge.sh\n\ndiff --git a/t/lib-merge.sh b/t/lib-merge.sh\nnew file mode 100644\nindex 0000000000..8734ebfc17\n--- /dev/null\n+++ b/t/lib-merge.sh\n@@ -0,0 +1,13 @@\n+# Helper functions used by merge tests.\n+\n+test_expect_merge_algorithm () {\n+\tstatus_for_recursive=$1 status_for_ort=$2\n+\tshift 2\n+\n+\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n+\tthen\n+\t\ttest_expect_${status_for_ort} \"$@\"\n+\telse\n+\t\ttest_expect_${status_for_recursive} \"$@\"\n+\tfi\n+}\ndiff --git a/t/t6416-recursive-corner-cases.sh b/t/t6416-recursive-corner-cases.sh\nindex fd98989b14..8b3a4fc843 100755\n--- a/t/t6416-recursive-corner-cases.sh\n+++ b/t/t6416-recursive-corner-cases.sh\n@@ -3,6 +3,7 @@\n test_description='recursive merge corner cases involving criss-cross merges'\n \n . ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-merge.sh\n \n #\n #  L1  L2\n@@ -1069,7 +1070,7 @@ test_expect_success 'setup symlink modify/modify' '\n \t)\n '\n \n-test_expect_failure 'check symlink modify/modify' '\n+test_expect_merge_algorithm failure success 'check symlink modify/modify' '\n \t(\n \t\tcd symlink-modify-modify &&\n \n@@ -1135,7 +1136,7 @@ test_expect_success 'setup symlink add/add' '\n \t)\n '\n \n-test_expect_failure 'check symlink add/add' '\n+test_expect_merge_algorithm failure success 'check symlink add/add' '\n \t(\n \t\tcd symlink-add-add &&\n \n@@ -1223,7 +1224,7 @@ test_expect_success 'setup submodule modify/modify' '\n \t)\n '\n \n-test_expect_failure 'check submodule modify/modify' '\n+test_expect_merge_algorithm failure success 'check submodule modify/modify' '\n \t(\n \t\tcd submodule-modify-modify &&\n \n@@ -1311,7 +1312,7 @@ test_expect_success 'setup submodule add/add' '\n \t)\n '\n \n-test_expect_failure 'check submodule add/add' '\n+test_expect_merge_algorithm failure success 'check submodule add/add' '\n \t(\n \t\tcd submodule-add-add &&\n \n@@ -1386,7 +1387,7 @@ test_expect_success 'setup conflicting entry types (submodule vs symlink)' '\n \t)\n '\n \n-test_expect_failure 'check conflicting entry types (submodule vs symlink)' '\n+test_expect_merge_algorithm failure success 'check conflicting entry types (submodule vs symlink)' '\n \t(\n \t\tcd submodule-symlink-add-add &&\n \ndiff --git a/t/t6422-merge-rename-corner-cases.sh b/t/t6422-merge-rename-corner-cases.sh\nindex 3375eaf4e7..58729593ba 100755\n--- a/t/t6422-merge-rename-corner-cases.sh\n+++ b/t/t6422-merge-rename-corner-cases.sh\n@@ -4,6 +4,7 @@ test_description=\"recursive merge corner cases w/ renames but not criss-crosses\"\n # t6036 has corner cases that involve both criss-cross merges and renames\n \n . ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-merge.sh\n \n test_setup_rename_delete_untracked () {\n \ttest_create_repo rename-delete-untracked &&\n@@ -878,7 +879,7 @@ test_setup_rad () {\n \t)\n }\n \n-test_expect_failure 'rad-check: rename/add/delete conflict' '\n+test_expect_merge_algorithm failure success 'rad-check: rename/add/delete conflict' '\n \ttest_setup_rad &&\n \t(\n \t\tcd rad &&\n@@ -951,7 +952,7 @@ test_setup_rrdd () {\n \t)\n }\n \n-test_expect_failure 'rrdd-check: rename/rename(2to1)/delete/delete conflict' '\n+test_expect_merge_algorithm failure success 'rrdd-check: rename/rename(2to1)/delete/delete conflict' '\n \ttest_setup_rrdd &&\n \t(\n \t\tcd rrdd &&\n@@ -1040,7 +1041,7 @@ test_setup_mod6 () {\n \t)\n }\n \n-test_expect_failure 'mod6-check: chains of rename/rename(1to2) and rename/rename(2to1)' '\n+test_expect_merge_algorithm failure success 'mod6-check: chains of rename/rename(1to2) and rename/rename(2to1)' '\n \ttest_setup_mod6 &&\n \t(\n \t\tcd mod6 &&\ndiff --git a/t/t6423-merge-rename-directories.sh b/t/t6423-merge-rename-directories.sh\nindex 06b46af765..807a424a52 100755\n--- a/t/t6423-merge-rename-directories.sh\n+++ b/t/t6423-merge-rename-directories.sh\n@@ -26,6 +26,7 @@ test_description=\"recursive merge with directory renames\"\n #                     files that might be renamed into each other's paths.)\n \n . ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-merge.sh\n \n \n ###########################################################################\n@@ -1339,7 +1340,7 @@ test_setup_6b1 () {\n \t)\n }\n \n-test_expect_failure '6b1: Same renames done on both sides, plus another rename' '\n+test_expect_merge_algorithm failure success '6b1: Same renames done on both sides, plus another rename' '\n \ttest_setup_6b1 &&\n \t(\n \t\tcd 6b1 &&\n@@ -1412,7 +1413,7 @@ test_setup_6b2 () {\n \t)\n }\n \n-test_expect_failure '6b2: Same rename done on both sides' '\n+test_expect_merge_algorithm failure success '6b2: Same rename done on both sides' '\n \ttest_setup_6b2 &&\n \t(\n \t\tcd 6b2 &&\n@@ -3471,7 +3472,7 @@ test_setup_10e () {\n \t)\n }\n \n-test_expect_failure '10e: Does git complain about untracked file that is not really in the way?' '\n+test_expect_merge_algorithm failure success '10e: Does git complain about untracked file that is not really in the way?' '\n \ttest_setup_10e &&\n \t(\n \t\tcd 10e &&\n@@ -4104,7 +4105,7 @@ test_setup_12b1 () {\n \t)\n }\n \n-test_expect_failure '12b1: Moving two directory hierarchies into each other' '\n+test_expect_merge_algorithm failure success '12b1: Moving two directory hierarchies into each other' '\n \ttest_setup_12b1 &&\n \t(\n \t\tcd 12b1 &&\n@@ -4272,7 +4273,7 @@ test_setup_12c1 () {\n \t)\n }\n \n-test_expect_failure '12c1: Moving one directory hierarchy into another w/ content merge' '\n+test_expect_merge_algorithm failure success '12c1: Moving one directory hierarchy into another w/ content merge' '\n \ttest_setup_12c1 &&\n \t(\n \t\tcd 12c1 &&\n@@ -4632,7 +4633,7 @@ test_setup_12f () {\n \t)\n }\n \n-test_expect_failure '12f: Trivial directory resolve, caching, all kinds of fun' '\n+test_expect_merge_algorithm failure success '12f: Trivial directory resolve, caching, all kinds of fun' '\n \ttest_setup_12f &&\n \t(\n \t\tcd 12f &&\ndiff --git a/t/t6426-merge-skip-unneeded-updates.sh b/t/t6426-merge-skip-unneeded-updates.sh\nindex 699813671c..d7eeee4310 100755\n--- a/t/t6426-merge-skip-unneeded-updates.sh\n+++ b/t/t6426-merge-skip-unneeded-updates.sh\n@@ -23,6 +23,7 @@ test_description=\"merge cases\"\n #                     files that might be renamed into each other's paths.)\n \n . ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-merge.sh\n \n \n ###########################################################################\n@@ -666,7 +667,7 @@ test_setup_4a () {\n #   correct requires doing the merge in-memory first, then realizing that no\n #   updates to the file are necessary, and thus that we can just leave the path\n #   alone.\n-test_expect_failure '4a: Change on A, change on B subset of A, dirty mods present' '\n+test_expect_merge_algorithm failure success '4a: Change on A, change on B subset of A, dirty mods present' '\n \ttest_setup_4a &&\n \t(\n \t\tcd 4a &&\ndiff --git a/t/t6430-merge-recursive.sh b/t/t6430-merge-recursive.sh\nindex a328260d42..9c08e63af2 100755\n--- a/t/t6430-merge-recursive.sh\n+++ b/t/t6430-merge-recursive.sh\n@@ -3,6 +3,7 @@\n test_description='merge-recursive backend test'\n \n . ./test-lib.sh\n+. \"$TEST_DIRECTORY\"/lib-merge.sh\n \n test_expect_success 'setup 1' '\n \n@@ -641,7 +642,7 @@ test_expect_success 'merge-recursive copy vs. rename' '\n \ttest_cmp expected actual\n '\n \n-test_expect_failure 'merge-recursive rename vs. rename/symlink' '\n+test_expect_merge_algorithm failure success 'merge-recursive rename vs. rename/symlink' '\n \n \tgit checkout -f rename &&\n \tgit merge rename-ln &&\n-- \ngitgitgadget\n\n"},{"id":"408421","messageId":"pull.769.v2.git.1603731704.gitgitgadget@gmail.com","threadId":"54492","inReplyTo":"pull.769.git.1603468885.gitgitgadget@gmail.com","subject":"[PATCH v2 0/9] Support both merge backends in the testsuite, via environment variable","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-10-26T17:01:35Z","receivedAt":"2020-10-26T17:03:01Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"This patch series builds on top of en/dir-rename-tests. It can be applied\nindependent of my \"new merge-ort\" API series I submitted a couple days\nago[1], but this series uses the same environment variable as patch 4 of\nthat series.\n\nAs promised, here is a series that makes the testsuite changes needed to\nsimultaneously support both merge backends, keyed off a\nGIT_TEST_MERGE_ALGORITHM environment variable setting.\n\nNOTE: The tests do not yet pass with GIT_TEST_MERGE_ALGORITHM=ort, because I\nhaven't submitted the implementation of the merge-ort functions -- yet. I\nfigured they are useful as a high level overview of the differences in\nbehavior between the two backends, and thus am providing these before the\nimplementation.\n\nChanges since v1:\n\n * Minor tweak to test_expect_merge_algorithm() suggested by Junio\n * Updated a test for portability\n * I had meant to leave the final patch, patch 9, out of the submission.\n   But, since I submitted it, update it to match my local version of that\n   test with one additional thing checked in the result.\n\n[1] \nhttps://lore.kernel.org/git/pull.895.git.git.1603286555.gitgitgadget@gmail.com/\n\nElijah Newren (9):\n  t/: new helper for tests that pass with ort but fail with recursive\n  merge tests: expect improved directory/file conflict handling in ort\n  t6416: correct expectation for rename/rename(1to2) + directory/file\n  t6404, t6423: expect improved rename/delete handling in ort backend\n  t6423: expect improved conflict markers labels in the ort backend\n  merge tests: expect slight differences in output for recursive vs. ort\n  t6423, t6436: note improved ort handling with dirty files\n  t6423: note improved ort handling with untracked files\n  t6423: add more details about direct resolution of directories\n\n t/lib-merge.sh                         |  13 +\n t/t6400-merge-df.sh                    |  14 +-\n t/t6402-merge-rename.sh                | 122 ++++-\n t/t6404-recursive-merge.sh             |  14 +-\n t/t6416-recursive-corner-cases.sh      | 200 ++++---\n t/t6422-merge-rename-corner-cases.sh   |  37 +-\n t/t6423-merge-rename-directories.sh    | 706 +++++++++++++++----------\n t/t6426-merge-skip-unneeded-updates.sh |   3 +-\n t/t6430-merge-recursive.sh             |   3 +-\n t/t6436-merge-overwrite.sh             |  18 +-\n t/t6437-submodule-merge.sh             |  25 +-\n t/t7602-merge-octopus-many.sh          |   6 +\n t/t7610-mergetool.sh                   |  32 +-\n 13 files changed, 807 insertions(+), 386 deletions(-)\n create mode 100644 t/lib-merge.sh\n\n\nbase-commit: c64432aacda9054459ce550eca95929897c301bd\nPublished-As: https://github.com/gitgitgadget/git/releases/tag/pr-769%2Fnewren%2Ftests-support-both-merge-backends-v2\nFetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-769/newren/tests-support-both-merge-backends-v2\nPull-Request: https://github.com/gitgitgadget/git/pull/769\n\nRange-diff vs v1:\n\n  1:  a8d4825a32 !  1:  f5d3295262 t/: new helper for tests that pass with ort but fail with recursive\n     @@ t/lib-merge.sh (new)\n      +# Helper functions used by merge tests.\n      +\n      +test_expect_merge_algorithm () {\n     -+\tstatus_for_recursive=$1\n     -+\tshift\n     -+\tstatus_for_ort=$1\n     -+\tshift\n     ++\tstatus_for_recursive=$1 status_for_ort=$2\n     ++\tshift 2\n      +\n      +\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n      +\tthen\n  2:  9394d526f1 =  2:  f27f12e8e5 merge tests: expect improved directory/file conflict handling in ort\n  3:  1eae84b787 =  3:  38919982c4 t6416: correct expectation for rename/rename(1to2) + directory/file\n  4:  554feb2aa7 =  4:  6e47fa19f8 t6404, t6423: expect improved rename/delete handling in ort backend\n  5:  5bead7fa0d =  5:  e8a7d6ac81 t6423: expect improved conflict markers labels in the ort backend\n  6:  2aa44c1f13 !  6:  4f32450b08 merge tests: expect slight differences in output for recursive vs. ort\n     @@ t/t7602-merge-octopus-many.sh: Merge made by the 'recursive' strategy.\n       test_expect_success 'merge reduces irrelevant remote heads' '\n      +\tif test \"$GIT_TEST_MERGE_ALGORITHM\" = ort\n      +\tthen\n     -+\t\tsed -i'' s/recursive/ort/ expected\n     ++\t\tmv expected expected.tmp &&\n     ++\t\tsed s/recursive/ort/ expected.tmp >expected &&\n     ++\t\trm expected.tmp\n      +\tfi &&\n       \tGIT_MERGE_VERBOSITY=0 git merge c4 c5 >actual &&\n       \ttest_i18ncmp expected actual\n  7:  9d46cc1ef3 =  7:  c5350fd0ae t6423, t6436: note improved ort handling with dirty files\n  8:  436577106e =  8:  6fd224247d t6423: note improved ort handling with untracked files\n  9:  2659d1cb98 !  9:  6e308768ff t6423: add more details about direct resolution of directories\n     @@ t/t6423-merge-rename-directories.sh: test_expect_merge_algorithm failure success\n      +\t\ttest_cmp expect actual &&\n      +\n      +\t\tgrep region_enter.*collect_merge_info trace.output >collect &&\n     -+\t\ttest_line_count = 4 collect\n     ++\t\ttest_line_count = 4 collect &&\n     ++\t\tgrep region_enter.*process_entries$ trace.output >process &&\n     ++\t\ttest_line_count = 2 process\n       \t)\n       '\n       \n\n-- \ngitgitgadget\n"},{"id":"408422","messageId":"38919982c41f02edbdb62a6fac794bba597584e5.1603731704.git.gitgitgadget@gmail.com","threadId":"54492","inReplyTo":"pull.769.v2.git.1603731704.gitgitgadget@gmail.com","subject":"[PATCH v2 3/9] t6416: correct expectation for rename/rename(1to2) + directory/file","fromName":"Elijah Newren via GitGitGadget","fromEmail":"gitgitgadget@gmail.com","sentAt":"2020-10-26T17:01:38Z","receivedAt":"2020-10-26T17:03:03Z","isPatch":true,"sender":{"key":"newren@gmail.com","avatar":"https://avatars.githubusercontent.com/u/5455730?v=4"},"body":"From: Elijah Newren <newren@gmail.com>\n\nWhen files are renamed and modified, we need to do three-way content\nmerges to get the appropriate content in the right location.  When we\nhave a rename/rename(1to2) conflict (both sides rename the same file,\nbut differently), that merged content should be placed in each of the\ntwo resulting files.  merge-recursive handled that fine when that was\nall that was involved, but when one or more of the two resulting files\nwere ALSO involved in a directory/file conflict, it failed to propagate\nthe merged content to that file.  Unfortunately, the one test in t6416\nthat touched on this combination of cases had been coded to not expect\nthe merged contents to be present.\n\nFix the test to check for the right behavior, and record how the\ndifferent merge backends will be expected to handle it.\n\nSigned-off-by: Elijah Newren <newren@gmail.com>\n---\n t/t6416-recursive-corner-cases.sh | 4 ++--\n 1 file changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/t/t6416-recursive-corner-cases.sh b/t/t6416-recursive-corner-cases.sh\nindex 0317e83970..887c2195a9 100755\n--- a/t/t6416-recursive-corner-cases.sh\n+++ b/t/t6416-recursive-corner-cases.sh\n@@ -786,7 +786,7 @@ test_expect_success 'merge of D1 & E3 succeeds' '\n \t)\n '\n \n-test_expect_success 'merge of D1 & E4 notifies user a and a2 are related' '\n+test_expect_merge_algorithm failure success 'merge of D1 & E4 puts merge of a and a2 in both a and a2' '\n \ttest_when_finished \"git -C directory-file reset --hard\" &&\n \ttest_when_finished \"git -C directory-file clean -fdqx\" &&\n \t(\n@@ -804,7 +804,7 @@ test_expect_success 'merge of D1 & E4 notifies user a and a2 are related' '\n \t\ttest_line_count = 1 out &&\n \n \t\tgit rev-parse >expect                  \\\n-\t\t\tA:ignore-me  B:a   D1:a  E4:a2 &&\n+\t\t\tA:ignore-me  B:a   E4:a2  E4:a2 &&\n \t\tgit rev-parse   >actual                \\\n \t\t\t:0:ignore-me :1:a~Temporary\\ merge\\ branch\\ 2  :2:a  :3:a2 &&\n \t\ttest_cmp expect actual\n-- \ngitgitgadget\n\n"},{"id":"408427","messageId":"xmqq3620g9xl.fsf@gitster.c.googlers.com","threadId":"54492","inReplyTo":"CABPp-BEmJA92tDymypgJqGmi=eMsvU+eP=KeTKvKcJEvFVztEA@mail.gmail.com","subject":"Re: [PATCH 1/9] t/: new helper for tests that pass with ort but fail with recursive","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-10-26T17:43:18Z","receivedAt":"2020-10-26T17:43:23Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Elijah Newren <newren@gmail.com> writes:\n\n>> When I wrote the patch, I was expecting something like\n>>\n>>         test_expect_merge_success recursive=failure,other=failure ...\n>>\n>> in order to merge all algorithm into single parameters.\n>>\n>> How about something like:\n>>\n>>         test_expect_merge_success exception=recursive,other ...\n>>\n>> Not that we have \"other\" algorithm to begin with.\n>\n> Sure, sounds great.  I wouldn't spend any time trying to make it work\n> with a 3rd backend, though.\n\nYup.  I'd appreciate if the lines become a bit shorter while at it,\nthough.\n\n    test_merge_both [<exception>] '<title>' '\n\t<body>\n    '\n\nthat expects success unless otherwise told, and <exception> like\n\"failure=recursive\" can be used to tell us to expect differently,\nwould work well?\n"}]}