{"thread":{"id":"617","subject":"[PATCH] Add the merge test Linus called \"test script from hell\".","startedAt":"2005-05-14T08:46:46Z","lastAt":"2005-05-14T08:46:46Z","messageCount":1,"participants":["Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"3293","messageId":"7vbr7e42kp.fsf@assigned-by-dhcp.cox.net","threadId":"617","inReplyTo":null,"subject":"[PATCH] Add the merge test Linus called \"test script from hell\".","fromName":"Junio C Hamano","fromEmail":"junkio@cox.net","sentAt":"2005-05-14T08:46:46Z","receivedAt":"2005-05-14T08:46:46Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"This is an adaptation to the test framework of a historic test\nthat was used before three way merge form of read-tree was\nintroduced, and subsequently used to validate the read-tree -m\nmerge works correctly.  It covers all the tricky cases known\nback then and also have been updated to cover conflicting\nfiles/directories cases since then.\n\nSigned-off-by: Junio C Hamano <junkio@cox.net>\n---\n\nt/t0700-read-tree.sh |  313 +++++++++++++++++++++++++++++++++++++++++++++++++++\n1 files changed, 313 insertions(+)\nt/t0700-read-tree.sh (. --> 100755)\n\n--- a/t/t0700-read-tree.sh\n+++ b/t/t0700-read-tree.sh\n@@ -0,0 +1,313 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2005 Junio C Hamano\n+#\n+\n+test_description='Three way merge with read-tree -m\n+\n+This test tries three-way merge with read-tree -m\n+\n+There is one ancestor (called O for Original) and two branches A\n+and B derived from it.  We want to do a 3-way merge between A and\n+B, using O as the common ancestor.\n+\n+    merge A O B\n+\n+Decisions are made by comparing contents of O, A and B pathname\n+by pathname.  The result is determined by the following guiding\n+principle:\n+\n+ - If only A does something to it and B does not touch it, take\n+   whatever A does.\n+\n+ - If only B does something to it and A does not touch it, take\n+   whatever B does.\n+\n+ - If both A and B does something but in the same way, take\n+   whatever they do.\n+\n+ - If A and B does something but different things, we need a\n+   3-way merge:\n+\n+   - We cannot do anything about the following cases:\n+\n+     * O does not have it.  A and B both must be adding to the\n+       same path independently.\n+\n+     * A deletes it.  B must be modifying.\n+\n+   - Otherwise, A and B are modifying.  Run 3-way merge.\n+\n+First, the case matrix.\n+\n+ - Vertical axis is for A'\\''s actions.\n+ - Horizontal axis is for B'\\''s actions.\n+\n+.----------------------------------------------------------------.\n+| A        B | No Action  |   Delete   |   Modify   |    Add     |\n+|------------+------------+------------+------------+------------|\n+| No Action  |            |            |            |            |\n+|            | select O   | delete     | select B   | select B   |\n+|            |            |            |            |            |\n+|------------+------------+------------+------------+------------|\n+| Delete     |            |            | ********** |    can     |\n+|            | delete     | delete     | merge      |    not     |\n+|            |            |            |            |  happen    |\n+|------------+------------+------------+------------+------------|\n+| Modify     |            | ********** | ?????????? |    can     |\n+|            | select A   | merge      | select A=B |    not     |\n+|            |            |            | merge      |  happen    |\n+|------------+------------+------------+------------+------------|\n+| Add        |            |    can     |    can     | ?????????? |\n+|            | select A   |    not     |    not     | select A=B |\n+|            |            |  happen    |  happen    | merge      |\n+.----------------------------------------------------------------.\n+\n+In addition:\n+\n+ SS: a special case of MM, where A and B makes the same modification.\n+ LL: a special case of AA, where A and B creates the same file.\n+ TT: a special case of MM, where A and B makes mergeable changes.\n+ DF: a special case, where A makes a directory and B makes a file.\n+\n+'\n+\n+. ./test-lib.sh\n+\n+# Original tree.\n+mkdir Z\n+for a in N D M\n+do\n+    for b in N D M\n+    do\n+        p=$a$b\n+\techo This is $p from the original tree. >$p\n+\techo This is Z/$p from the original tree. >Z/$p\n+\ttest_expect_success \\\n+\t    \"adding test file $p and Z/$p\" \\\n+\t    'git-update-cache --add $p &&\n+\t    git-update-cache --add Z/$p'\n+    done\n+done\n+echo This is SS from the original tree. >SS\n+test_expect_success \\\n+    'adding test file SS' \\\n+    'git-update-cache --add SS'\n+cat >TT <<\\EOF\n+This is a trivial merge sample text.\n+Branch A is expected to upcase this word, here.\n+There are some filler lines to avoid diff context\n+conflicts here,\n+like this one,\n+and this one,\n+and this one is yet another one of them.\n+At the very end, here comes another line, that is\n+the word, expected to be upcased by Branch B.\n+This concludes the trivial merge sample file.\n+EOF\n+test_expect_success \\\n+    'adding test file TT' \\\n+    'git-update-cache --add TT'\n+test_expect_success \\\n+    'prepare initial tree' \\\n+    'tree_O=$(git-write-tree)'\n+\n+test_expect_success \\\n+    'commit initial tree' \\\n+    'commit_O=$(echo \"Original tree for the merge test.\" |\n+     git-commit-tree $tree_O)'\n+echo $commit_O >.git/HEAD-O\n+\n+################################################################\n+# Branch A and B makes the changes according to the above matrix.\n+\n+################################################################\n+# Branch A\n+\n+to_remove=$(echo D? Z/D?)\n+rm -f $to_remove\n+test_expect_success \\\n+    'change in branch A (removal)' \\\n+    'git-update-cache --remove $to_remove'\n+\n+for p in M? Z/M?\n+do\n+    echo This is modified $p in the branch A. >$p\n+    test_expect_success \\\n+\t'change in branch A (modification)' \\\n+        \"git-update-cache $p\"\n+done\n+\n+for p in AN AA Z/AN Z/AA\n+do\n+    echo This is added $p in the branch A. >$p\n+    test_expect_success \\\n+\t'change in branch A (addition)' \\\n+\t\"git-update-cache --add $p\"\n+done\n+\n+echo This is SS from the modified tree. >SS\n+echo This is LL from the modified tree. >LL\n+test_expect_success \\\n+    'change in branch A (addition)' \\\n+    'git-update-cache --add LL &&\n+     git-update-cache SS'\n+mv TT TT-\n+sed -e '/Branch A/s/word/WORD/g' <TT- >TT\n+rm -f TT-\n+test_expect_success \\\n+    'change in branch A (edit)' \\\n+    'git-update-cache TT'\n+\n+mkdir DF\n+echo Branch A makes a file at DF/DF, creating a directory DF. >DF/DF\n+test_expect_success \\\n+    'change in branch A (change file to directory)' \\\n+    'git-update-cache --add DF/DF'\n+\n+test_expect_success \\\n+    'recording branch A tree' \\\n+    'tree_A=$(git-write-tree)'\n+test_expect_success \\\n+    'committing branch A changes' \\\n+    'commit_A=$(echo \"Branch A for the merge test.\" |\n+           git-commit-tree $tree_A -p $commit_O)'\n+echo $commit_A >.git/HEAD-A\n+\t   \n+################################################################\n+# Branch B\n+# Start from O\n+\n+rm -rf [NDMASLT][NDMASLT] Z DF\n+mkdir Z\n+test_expect_success \\\n+    'reading original tree and checking out' \\\n+    'git-read-tree $tree_O &&\n+     git-checkout-cache -a'\n+\n+to_remove=$(echo ?D Z/?D)\n+rm -f $to_remove\n+test_expect_success \\\n+    'change in branch B (removal)' \\\n+    \"git-update-cache --remove $to_remove\"\n+\n+for p in ?M Z/?M\n+do\n+    echo This is modified $p in the branch B. >$p\n+    test_expect_success \\\n+\t'change in branch B (modification)' \\\n+\t\"git-update-cache $p\"\n+done\n+\n+for p in NA AA Z/NA Z/AA\n+do\n+    echo This is added $p in the branch B. >$p\n+    test_expect_success \\\n+\t'change in branch B (addition)' \\\n+\t\"git-update-cache --add $p\"\n+done\n+echo This is SS from the modified tree. >SS\n+echo This is LL from the modified tree. >LL\n+test_expect_success \\\n+    'change in branch B (addition and modification)' \\\n+    'git-update-cache --add LL &&\n+     git-update-cache SS'\n+mv TT TT-\n+sed -e '/Branch B/s/word/WORD/g' <TT- >TT\n+rm -f TT-\n+test_expect_success \\\n+    'change in branch B (modification)' \\\n+    'git-update-cache TT'\n+\n+echo Branch B makes a file at DF. >DF\n+test_expect_success \\\n+    'change in branch B (addition of a file to conflict with directory)' \\\n+    'git-update-cache --add DF'\n+\n+test_expect_success \\\n+    'recording branch B tree' \\\n+    'tree_B=$(git-write-tree)'\n+test_expect_success \\\n+    'committing branch B changes' \\\n+    'commit_B=$(echo \"Branch B for the merge test.\" |\n+           git-commit-tree $tree_B -p $commit_O)'\n+echo $commit_B >.git/HEAD-B\n+\n+################################################################\n+# Done preparation.\n+\n+test_debug '\n+    for T in O A B\n+    do\n+\techo \"# $T $(eval git-cat-file commit \\$commit_$T | sed -e 1q)\"\n+    done\n+'\n+\n+################################################################\n+# Try merging and showing the various diffs\n+\n+test_expect_success \\\n+    '3-way merge with git-read-tree -m' \\\n+    \"git-read-tree -m $tree_O $tree_A $tree_B\"\n+\n+strip_object_id='s/^\\([0-7]*\\) [0-9a-f]* \\([0-3].*\\)$/\\1 \\2/'\n+\n+test_expect_success \\\n+    'git-ls-files --stage of the merge result' \\\n+    'git-ls-files --stage >current- &&\n+     sed -e \"$strip_object_id\" <current- >current'\n+\n+cat >expected <<\\EOF\n+100644 2 AA\n+100644 3 AA\n+100644 2 AN\n+100644 1 DD\n+100644 3 DF\n+100644 2 DF/DF\n+100644 1 DM\n+100644 3 DM\n+100644 1 DN\n+100644 3 DN\n+100644 2 LL\n+100644 3 LL\n+100644 1 MD\n+100644 2 MD\n+100644 1 MM\n+100644 2 MM\n+100644 3 MM\n+100644 0 MN\n+100644 3 NA\n+100644 1 ND\n+100644 2 ND\n+100644 0 NM\n+100644 0 NN\n+100644 0 SS\n+100644 1 TT\n+100644 2 TT\n+100644 3 TT\n+100644 2 Z/AA\n+100644 3 Z/AA\n+100644 2 Z/AN\n+100644 1 Z/DD\n+100644 1 Z/DM\n+100644 3 Z/DM\n+100644 1 Z/DN\n+100644 3 Z/DN\n+100644 1 Z/MD\n+100644 2 Z/MD\n+100644 1 Z/MM\n+100644 2 Z/MM\n+100644 3 Z/MM\n+100644 0 Z/MN\n+100644 3 Z/NA\n+100644 1 Z/ND\n+100644 2 Z/ND\n+100644 0 Z/NM\n+100644 0 Z/NN\n+EOF\n+\n+test_expect_success \\\n+    'validate merge result' \\\n+    'diff current expected'\n+\n+test_done\n------------------------------------------------\n\n"}]}