{"thread":{"id":"988","subject":"[PATCH] Rollup of git-rev-list Patch Series 1-7 20 June, 2005","startedAt":"2005-06-20T02:45:59Z","lastAt":"2005-06-20T02:45:59Z","messageCount":1,"participants":["Jon Seymour"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"5066","messageId":"20050620024559.779.qmail@blackcubes.dyndns.org","threadId":"988","inReplyTo":null,"subject":"[PATCH] Rollup of git-rev-list Patch Series 1-7 20 June, 2005","fromName":"Jon Seymour","fromEmail":"jon.seymour@gmail.com","sentAt":"2005-06-20T02:45:59Z","receivedAt":"2005-06-20T02:45:59Z","isPatch":true,"sender":{"key":"jon.seymour@gmail.com","avatar":"https://avatars.githubusercontent.com/u/207131?v=4"},"body":"\nThis patch series contains:\n\n[PATCH 1/7] Additional git-rev-list unit tests to demonstrate problems that require fixes\n[PATCH 2/7] Tweaked --merge-order --show-breaks output in case specified head has no parent\n[PATCH 3/7] Fixes problem with --merge-order head ^head\n[PATCH 4/7] Relaxes error checking in epoch.c to allow duplicate parents\n[PATCH 5/7] Prevent git-rev-list --merge-order producing duplicates in the output\n[PATCH 6/7] Prevent git-rev-list without --merge-order producing duplicates in output\n[PATCH 7/7] Fix for --merge-order, --max-age interaction issue\n\nIt is a complete superset of this series:\n\n[PATCH 2/2] Fix for --merge-order, --max-age interaction issue\n[PATCH 1/2] Test case that demonstrates problem with --merge-order, --max-age interaction\n\nSigned-off-by: Jon Seymour <jon.seymour@gmail.com>\n---\nThis rollup provided for ease of application only.\n---\n\n epoch.c                         |   57 +++--\n epoch.h                         |   13 +\n rev-list.c                      |   18 +-\n t/t6001-rev-list-merge-order.sh |  434 ++++++++++++++++++++++++++++++++++-----\n 4 files changed, 427 insertions(+), 95 deletions(-)\n\ndiff --git a/epoch.c b/epoch.c\n--- a/epoch.c\n+++ b/epoch.c\n@@ -224,17 +224,13 @@ static int find_base_for_list(struct com\n \tfor (; list; list = list->next) {\n \t\tstruct commit *item = list->item;\n \n-\t\tif (item->object.util) {\n-\t\t\tdie(\"%s:%d:%s: logic error: this should not have happened - commit %s\",\n-\t\t\t    __FILE__, __LINE__, __FUNCTION__,\n-\t\t\t    sha1_to_hex(item->object.sha1));\n-\t\t}\n-\n-\t\tnew_mass_counter(list->item, get_one());\n-\t\tadd(&injected, &injected, get_one());\n+\t\tif (!item->object.util) {\n+\t\t\tnew_mass_counter(list->item, get_one());\n+\t\t\tadd(&injected, &injected, get_one());\n \n-\t\tcommit_list_insert(list->item, &cleaner);\n-\t\tcommit_list_insert(list->item, &pending);\n+\t\t\tcommit_list_insert(list->item, &cleaner);\n+\t\t\tcommit_list_insert(list->item, &pending);\n+\t\t}\n \t}\n \n \twhile (!*boundary && pending && !ret) {\n@@ -536,6 +532,8 @@ static int sort_in_merge_order(struct co\n \n \tret = parse_commit(head_of_epoch);\n \n+\tnext->object.flags |= BOUNDARY;\n+\n \twhile (next && next->parents && !ret && (action != STOP)) {\n \t\tstruct commit *base = NULL;\n \n@@ -604,7 +602,9 @@ int sort_list_in_merge_order(struct comm\n \t\t}\n \t}\n \n-\tif (!reversed->next) {\n+\tif (!reversed)\n+\t\treturn ret;\n+\telse if (!reversed->next) {\n \t\t/*\n \t\t * If there is only one element in the list, we can sort it\n \t\t * using sort_in_merge_order.\n@@ -621,20 +621,27 @@ int sort_list_in_merge_order(struct comm\n \t\t\tbase->object.flags |= BOUNDARY;\n \n \t\twhile (reversed) {\n-\t\t\tsort_first_epoch(pop_commit(&reversed), &stack);\n-\t\t\tif (reversed) {\n-\t\t\t\t/*\n-\t\t\t\t * If we have more commits to push, then the\n-\t\t\t\t * first push for the next parent may (or may\n-\t\t\t\t * not) represent a discontinuity with respect\n-\t\t\t\t * to the parent currently on the top of\n-\t\t\t\t * the stack.\n-\t\t\t\t *\n-\t\t\t\t * Mark it for checking here, and check it\n-\t\t\t\t * with the next push. See sort_first_epoch()\n-\t\t\t\t * for more details.\n-\t\t\t\t */\n-\t\t\t\tstack->item->object.flags |= DISCONTINUITY;\n+\t\t\tstruct commit * next = pop_commit(&reversed);\n+\n+\t\t\tif (!(next->object.flags & VISITED)) {\n+\t\t\t\tsort_first_epoch(next, &stack);\n+\t\t\t\tif (reversed) {\n+\t\t\t\t\t/*\n+\t\t\t\t\t * If we have more commits \n+\t\t\t\t\t * to push, then the first\n+\t\t\t\t\t * push for the next parent may \n+\t\t\t\t\t * (or may * not) represent a \n+\t\t\t\t\t * discontinuity with respect\n+\t\t\t\t\t * to the parent currently on \n+\t\t\t\t\t * the top of the stack.\n+\t\t\t\t\t *\n+\t\t\t\t\t * Mark it for checking here, \n+\t\t\t\t\t * and check it with the next \n+\t\t\t\t\t * push. See sort_first_epoch()\n+\t\t\t\t\t * for more details.\n+\t\t\t\t\t */\n+\t\t\t\t\tstack->item->object.flags |= DISCONTINUITY;\n+\t\t\t\t}\n \t\t\t}\n \t\t}\n \ndiff --git a/epoch.h b/epoch.h\n--- a/epoch.h\n+++ b/epoch.h\n@@ -10,11 +10,12 @@ typedef int (*emitter_func) (struct comm\n \n int sort_list_in_merge_order(struct commit_list *list, emitter_func emitter);\n \n-#define UNINTERESTING  (1u<<2)\n-#define BOUNDARY       (1u<<3)\n-#define VISITED        (1u<<4)\n-#define DISCONTINUITY  (1u<<5)\n-#define DUPCHECK       (1u<<6)\n+#define UNINTERESTING   (1u<<2)\n+#define BOUNDARY        (1u<<3)\n+#define VISITED         (1u<<4)\n+#define DISCONTINUITY   (1u<<5)\n+#define DUPCHECK        (1u<<6)\n+#define LAST_EPOCH_FLAG (1u<<6)\n \n \n-#endif\t\t\t\t/* EPOCH_H */\n+#endif\t/* EPOCH_H */\ndiff --git a/rev-list.c b/rev-list.c\n--- a/rev-list.c\n+++ b/rev-list.c\n@@ -5,6 +5,7 @@\n #define SEEN\t\t(1u << 0)\n #define INTERESTING\t(1u << 1)\n #define COUNTED\t\t(1u << 2)\n+#define SHOWN\t\t(LAST_EPOCH_FLAG << 2)\n \n static const char rev_list_usage[] =\n \t\"usage: git-rev-list [OPTION] commit-id <commit-id>\\n\"\n@@ -26,9 +27,11 @@ static int max_count = -1;\n static enum cmit_fmt commit_format = CMIT_FMT_RAW;\n static int merge_order = 0;\n static int show_breaks = 0;\n+static int stop_traversal = 0;\n \n static void show_commit(struct commit *commit)\n {\n+\tcommit->object.flags |= SHOWN;\n \tif (show_breaks) {\n \t\tprefix = \"| \";\n \t\tif (commit->object.flags & DISCONTINUITY) {\n@@ -55,15 +58,22 @@ static void show_commit(struct commit *c\n \n static int filter_commit(struct commit * commit)\n {\n-\tif (commit->object.flags & UNINTERESTING)\n+\tif (merge_order && stop_traversal && commit->object.flags & BOUNDARY)\n+\t\treturn STOP;\n+\tif (commit->object.flags & (UNINTERESTING|SHOWN))\n \t\treturn CONTINUE;\n \tif (min_age != -1 && (commit->date > min_age))\n \t\treturn CONTINUE;\n-\tif (max_age != -1 && (commit->date < max_age))\n-\t\treturn STOP;\n+\tif (max_age != -1 && (commit->date < max_age)) {\n+\t\tif (!merge_order)\n+\t\t\treturn STOP;\n+\t\telse {\n+\t\t\tstop_traversal = 1;\n+\t\t\treturn CONTINUE;\n+\t\t}\n+\t}\n \tif (max_count != -1 && !max_count--)\n \t\treturn STOP;\n-\n \treturn DO;\n }\n \ndiff --git a/t/t6001-rev-list-merge-order.sh b/t/t6001-rev-list-merge-order.sh\n--- a/t/t6001-rev-list-merge-order.sh\n+++ b/t/t6001-rev-list-merge-order.sh\n@@ -3,16 +3,124 @@\n # Copyright (c) 2005 Jon Seymour\n #\n \n-test_description='Test rev-list --merge-order\n-'\n+test_description='Tests git-rev-list --merge-order functionality'\n+\n . ./test-lib.sh\n \n-function do_commit\n+#\n+# TODO: move the following block (upto --- end ...) into testlib.sh\n+#\n+[ -d .git/refs/tags ] || mkdir -p .git/refs/tags\n+\n+sed_script=\"\";\n+\n+# Answer the sha1 has associated with the tag. The tag must exist in .git or .git/refs/tags\n+tag()\n+{\n+\t_tag=$1\n+\t[ -f .git/refs/tags/$_tag ] || error \"tag: \\\"$_tag\\\" does not exist\"\n+\tcat .git/refs/tags/$_tag\n+}\n+\n+# Generate a commit using the text specified to make it unique and the tree\n+# named by the tag specified.\n+unique_commit()\n+{\n+\t_text=$1\n+        _tree=$2\n+\tshift 2\n+    \techo $_text | git-commit-tree $(tag $_tree) \"$@\"\n+}\n+\n+# Save the output of a command into the tag specified. Prepend\n+# a substitution script for the tag onto the front of $sed_script\n+save_tag()\n+{\n+\t_tag=$1\t\n+\t[ -n \"$_tag\" ] || error \"usage: save_tag tag commit-args ...\"\n+\tshift 1\n+    \t\"$@\" >.git/refs/tags/$_tag\n+    \tsed_script=\"s/$(tag $_tag)/$_tag/g${sed_script+;}$sed_script\"\n+}\n+\n+# Replace unhelpful sha1 hashses with their symbolic equivalents \n+entag()\n+{\n+\tsed \"$sed_script\"\n+}\n+\n+# Execute a command after first saving, then setting the GIT_AUTHOR_EMAIL\n+# tag to a specified value. Restore the original value on return.\n+as_author()\n+{\n+\t_author=$1\n+\tshift 1\n+        _save=$GIT_AUTHOR_EMAIL\n+\n+\texport GIT_AUTHOR_EMAIL=\"$_author\"\n+\t\"$@\"\n+        export GIT_AUTHOR_EMAIL=\"$_save\"\n+}\n+\n+commit_date()\n+{\n+        _commit=$1\n+\tgit-cat-file commit $_commit | sed -n \"s/^committer .*> \\([0-9]*\\) .*/\\1/p\" \n+}\n+\n+on_committer_date()\n+{\n+    _date=$1\n+    shift 1\n+    GIT_COMMITTER_DATE=$_date \"$@\"\n+}\n+\n+# Execute a command and suppress any error output.\n+hide_error()\n {\n-    git-commit-tree \"$@\" </dev/null\n+\t\"$@\" 2>/dev/null\n+}\n+\n+check_output()\n+{\n+\t_name=$1\n+\tshift 1\n+\tif \"$@\" | entag > $_name.actual\n+\tthen\n+\t\tdiff $_name.expected $_name.actual\n+\telse\n+\t\treturn 1;\n+\tfi\n+\t\n+}\n+\n+# Turn a reasonable test description into a reasonable test name.\n+# All alphanums translated into -'s which are then compressed and stripped\n+# from front and back.\n+name_from_description()\n+{\n+        tr \"'\" '-' | tr '~`!@#$%^&*()_+={}[]|\\;:\"<>,/? ' '-' | tr -s '-' | tr '[A-Z]' '[a-z]' | sed \"s/^-*//;s/-*\\$//\"\n+}\n+\n+\n+# Execute the test described by the first argument, by eval'ing\n+# command line specified in the 2nd argument. Check the status code\n+# is zero and that the output matches the stream read from \n+# stdin.\n+test_output_expect_success()\n+{\t\n+\t_description=$1\n+        _test=$2\n+        [ $# -eq 2 ] || error \"usage: test_output_expect_success description test <<EOF ... EOF\"\n+        _name=$(echo $_description | name_from_description)\n+\tcat > $_name.expected\n+\ttest_expect_success \"$_description\" \"check_output $_name $_test\" \n }\n \n-function check_adjacency\n+# --- end of stuff to move ---\n+\n+# test-case specific test function\n+check_adjacency()\n {\n     read previous\n     echo \"= $previous\"\n@@ -28,43 +136,94 @@ function check_adjacency\n     done\n }\n \n-function sed_script\n+list_duplicates()\n+{\n+    \"$@\" | sort | uniq -d\n+}\n+\n+grep_stderr()\n {\n-   for c in root a0 a1 a2 a3 a4 b1 b2 b3 b4 c1 c2 c3 l0 l1 l2 l3 l4 l5\n-   do\n-       echo -n \"s/${!c}/$c/;\"\n-   done\n+    args=$1\n+    shift 1\n+    \"$@\" 2>&1 | grep \"$args\"\n }\n \n date >path0\n git-update-cache --add path0\n-tree=$(git-write-tree)\n-root=$(do_commit $tree 2>/dev/null)\n-export GIT_COMMITTER_NAME=foobar  # to guarantee that the commit is different\n-l0=$(do_commit $tree -p $root)\n-l1=$(do_commit $tree -p $l0)\n-l2=$(do_commit $tree -p $l1)\n-a0=$(do_commit $tree -p $l2)\n-a1=$(do_commit $tree -p $a0)\n-export GIT_COMMITTER_NAME=foobar2 # to guarantee that the commit is different\n-b1=$(do_commit $tree -p $a0)\n-c1=$(do_commit $tree -p $b1)\n-export GIT_COMMITTER_NAME=foobar3 # to guarantee that the commit is different\n-b2=$(do_commit $tree -p $b1)\n-b3=$(do_commit $tree -p $b2)\n-c2=$(do_commit $tree -p $c1 -p $b2)\n-c3=$(do_commit $tree -p $c2)\n-a2=$(do_commit $tree -p $a1)\n-a3=$(do_commit $tree -p $a2)\n-b4=$(do_commit $tree -p $b3 -p $a3)\n-a4=$(do_commit $tree -p $a3 -p $b4 -p $c3)\n-l3=$(do_commit $tree -p $a4)\n-l4=$(do_commit $tree -p $l3)\n-l5=$(do_commit $tree -p $l4)\n-echo $l5 > .git/HEAD\n+save_tag tree git-write-tree\n+on_committer_date \"1971-08-16 00:00:00\" hide_error save_tag root unique_commit root tree\n+on_committer_date \"1971-08-16 00:00:01\" save_tag l0 unique_commit l0 tree -p root\n+on_committer_date \"1971-08-16 00:00:02\" save_tag l1 unique_commit l1 tree -p l0\n+on_committer_date \"1971-08-16 00:00:03\" save_tag l2 unique_commit l2 tree -p l1\n+on_committer_date \"1971-08-16 00:00:04\" save_tag a0 unique_commit a0 tree -p l2\n+on_committer_date \"1971-08-16 00:00:05\" save_tag a1 unique_commit a1 tree -p a0\n+on_committer_date \"1971-08-16 00:00:06\" save_tag b1 unique_commit b1 tree -p a0\n+on_committer_date \"1971-08-16 00:00:07\" save_tag c1 unique_commit c1 tree -p b1\n+on_committer_date \"1971-08-16 00:00:08\" as_author foobar@example.com save_tag b2 unique_commit b2 tree -p b1\n+on_committer_date \"1971-08-16 00:00:09\" save_tag b3 unique_commit b2 tree -p b2\n+on_committer_date \"1971-08-16 00:00:10\" save_tag c2 unique_commit c2 tree -p c1 -p b2\n+on_committer_date \"1971-08-16 00:00:11\" save_tag c3 unique_commit c3 tree -p c2\n+on_committer_date \"1971-08-16 00:00:12\" save_tag a2 unique_commit a2 tree -p a1\n+on_committer_date \"1971-08-16 00:00:13\" save_tag a3 unique_commit a3 tree -p a2\n+on_committer_date \"1971-08-16 00:00:14\" save_tag b4 unique_commit b4 tree -p b3 -p a3\n+on_committer_date \"1971-08-16 00:00:15\" save_tag a4 unique_commit a4 tree -p a3 -p b4 -p c3\n+on_committer_date \"1971-08-16 00:00:16\" save_tag l3 unique_commit l3 tree -p a4\n+on_committer_date \"1971-08-16 00:00:17\" save_tag l4 unique_commit l4 tree -p l3\n+on_committer_date \"1971-08-16 00:00:18\" save_tag l5 unique_commit l5 tree -p l4\n+on_committer_date \"1971-08-16 00:00:19\" save_tag m1 unique_commit m1 tree -p a4 -p c3\n+on_committer_date \"1971-08-16 00:00:20\" save_tag m2 unique_commit m2 tree -p c3 -p a4\n+#\n+# note: as of 20/6, it isn't possible to create duplicate parents, so this\n+# can't be tested.\n+#\n+#on_committer_date \"1971-08-16 00:00:20\" save_tag m3 unique_commit m3 tree -p c3 -p a4 -p c3\n+hide_error save_tag e1 as_author e@example.com unique_commit e1 tree\n+save_tag e2 as_author e@example.com unique_commit e2 tree -p e1\n+save_tag f1 as_author f@example.com unique_commit f1 tree -p e1\n+save_tag e3 as_author e@example.com unique_commit e3 tree -p e2\n+save_tag f2 as_author f@example.com unique_commit f2 tree -p f1\n+save_tag e4 as_author e@example.com unique_commit e4 tree -p e3 -p f2\n+save_tag e5 as_author e@example.com unique_commit e5 tree -p e4\n+save_tag f3 as_author f@example.com unique_commit f3 tree -p f2\n+save_tag f4 as_author f@example.com unique_commit f4 tree -p f3\n+save_tag e6 as_author e@example.com unique_commit e6 tree -p e5 -p f4\n+save_tag f5 as_author f@example.com unique_commit f5 tree -p f4\n+save_tag f6 as_author f@example.com unique_commit f6 tree -p f5 -p e6\n+save_tag e7 as_author e@example.com unique_commit e7 tree -p e6\n+save_tag e8 as_author e@example.com unique_commit e8 tree -p e7\n+save_tag e9 as_author e@example.com unique_commit e9 tree -p e8\n+save_tag f7 as_author f@example.com unique_commit f7 tree -p f6\n+save_tag f8 as_author f@example.com unique_commit f8 tree -p f7\n+save_tag f9 as_author f@example.com unique_commit f9 tree -p f8\n+save_tag e10 as_author e@example.com unique_commit e1 tree -p e9 -p f8\n+\n+hide_error save_tag g0 unique_commit g0 tree\n+save_tag g1 unique_commit g1 tree -p g0\n+save_tag h1 unique_commit g2 tree -p g0\n+save_tag g2 unique_commit g3 tree -p g1 -p h1\n+save_tag h2 unique_commit g4 tree -p g2\n+save_tag g3 unique_commit g5 tree -p g2\n+save_tag g4 unique_commit g6 tree -p g3 -p h2\n+\n+tag l5 > .git/HEAD\n+\n+#\n+# cd to t/trash and use \n+#\n+#    git-rev-list ... 2>&1 | sed \"$(cat sed.script)\" \n+#\n+# if you ever want to manually debug the operation of git-rev-list\n+#\n+echo $sed_script > sed.script\n \n-git-rev-list --merge-order --show-breaks HEAD | sed \"$(sed_script)\" > actual-merge-order\n-cat > expected-merge-order <<EOF\n+test_expect_success 'rev-list has correct number of entries' 'git-rev-list HEAD | wc -l | tr -s \" \"' <<EOF\n+19\n+EOF\n+\n+normal_adjacency_count=$(git-rev-list HEAD | check_adjacency | grep -c \"\\^\" | tr -d ' ')\n+merge_order_adjacency_count=$(git-rev-list --merge-order HEAD | check_adjacency | grep -c \"\\^\" | tr -d ' ')\n+test_expect_success '--merge-order produces as many or fewer discontinuities' '[ $merge_order_adjacency_count -le $normal_adjacency_count ]'\n+test_output_expect_success 'simple merge order' 'git-rev-list --merge-order --show-breaks HEAD' <<EOF\n = l5\n | l4\n | l3\n@@ -86,15 +245,17 @@ cat > expected-merge-order <<EOF\n = root\n EOF\n \n-git-rev-list HEAD | check_adjacency | sed \"$(sed_script)\" > actual-default-order\n-normal_adjacency_count=$(git-rev-list HEAD | check_adjacency | grep -c \"\\^\" | tr -d ' ')\n-merge_order_adjacency_count=$(git-rev-list --merge-order HEAD | check_adjacency | grep -c \"\\^\" | tr -d ' ')\n-\n-test_expect_success 'Testing that the rev-list has correct number of entries' '[ $(git-rev-list HEAD | wc -l) -eq 19 ]'\n-test_expect_success 'Testing that --merge-order produces the correct result' 'diff expected-merge-order actual-merge-order'\n-test_expect_success 'Testing that --merge-order produces as many or fewer discontinuities' '[ $merge_order_adjacency_count -le $normal_adjacency_count ]'\n+test_output_expect_success 'two diamonds merge order (g6)' 'git-rev-list --merge-order --show-breaks g4' <<EOF\n+= g4\n+| h2\n+^ g3\n+= g2\n+| h1\n+^ g1\n+= g0\n+EOF\n \n-cat > expected-merge-order-1 <<EOF\n+test_output_expect_success 'multiple heads' 'git-rev-list --merge-order a3 b3 c3' <<EOF\n c3\n c2\n c1\n@@ -111,10 +272,7 @@ l0\n root\n EOF\n \n-git-rev-list --merge-order $a3 $b3 $c3 | sed \"$(sed_script)\" > actual-merge-order-1\n-test_expect_success 'Testing multiple heads' 'diff expected-merge-order-1 actual-merge-order-1'\n-\n-cat > expected-merge-order-2 <<EOF\n+test_output_expect_success 'multiple heads, prune at a1' 'git-rev-list --merge-order a3 b3 c3 ^a1' <<EOF\n c3\n c2\n c1\n@@ -125,10 +283,7 @@ a3\n a2\n EOF\n \n-git-rev-list --merge-order $a3 $b3 $c3 ^$a1 | sed \"$(sed_script)\" > actual-merge-order-2\n-test_expect_success 'Testing stop' 'diff expected-merge-order-2 actual-merge-order-2'\n-\n-cat > expected-merge-order-3 <<EOF\n+test_output_expect_success 'multiple heads, prune at l1' 'git-rev-list --merge-order a3 b3 c3 ^l1' <<EOF\n c3\n c2\n c1\n@@ -142,10 +297,26 @@ a0\n l2\n EOF\n \n-git-rev-list --merge-order $a3 $b3 $c3 ^$l1 | sed \"$(sed_script)\" > actual-merge-order-3\n-test_expect_success 'Testing stop in linear epoch' 'diff expected-merge-order-3 actual-merge-order-3'\n+test_output_expect_success 'cross-epoch, head at l5, prune at l1' 'git-rev-list --merge-order l5 ^l1' <<EOF\n+l5\n+l4\n+l3\n+a4\n+c3\n+c2\n+c1\n+b4\n+b3\n+b2\n+b1\n+a3\n+a2\n+a1\n+a0\n+l2\n+EOF\n \n-cat > expected-merge-order-4 <<EOF\n+test_output_expect_success 'duplicated head arguments' 'git-rev-list --merge-order l5 l5 ^l1' <<EOF\n l5\n l4\n l3\n@@ -164,12 +335,155 @@ a0\n l2\n EOF\n \n-git-rev-list --merge-order $l5 ^$l1 | sed \"$(sed_script)\" > actual-merge-order-4\n-test_expect_success 'Testing start in linear epoch, stop after non-linear epoch' 'diff expected-merge-order-4 actual-merge-order-4'\n+test_output_expect_success 'prune near merge' 'git-rev-list --merge-order a4 ^c3' <<EOF\n+a4\n+b4\n+b3\n+a3\n+a2\n+a1\n+EOF\n+\n+test_output_expect_success \"head has no parent\" 'git-rev-list --merge-order --show-breaks root' <<EOF\n+= root\n+EOF\n \n-git-rev-list --merge-order $l5 $l5 ^$l1 2>/dev/null | sed \"$(sed_script)\" > actual-merge-order-5\n-test_expect_success 'Testing duplicated start arguments' 'diff expected-merge-order-4 actual-merge-order-5'\n+test_output_expect_success \"two nodes - one head, one base\" 'git-rev-list --merge-order --show-breaks l0' <<EOF\n+= l0\n+= root\n+EOF\n \n-test_expect_success 'Testing exclusion near merge' 'git-rev-list --merge-order $a4 ^$c3 2>/dev/null'\n+test_output_expect_success \"three nodes one head, one internal, one base\" 'git-rev-list --merge-order --show-breaks l1' <<EOF\n+= l1\n+| l0\n+= root\n+EOF\n+\n+test_output_expect_success \"linear prune l2 ^root\" 'git-rev-list --merge-order --show-breaks l2 ^root' <<EOF\n+= l2\n+| l1\n+| l0\n+EOF\n+\n+test_output_expect_success \"linear prune l2 ^l0\" 'git-rev-list --merge-order --show-breaks l2 ^l0' <<EOF\n+= l2\n+| l1\n+EOF\n+\n+test_output_expect_success \"linear prune l2 ^l1\" 'git-rev-list --merge-order --show-breaks l2 ^l1' <<EOF\n+= l2\n+EOF\n+\n+test_output_expect_success \"linear prune l5 ^a4\" 'git-rev-list --merge-order --show-breaks l5 ^a4' <<EOF\n+= l5\n+| l4\n+| l3\n+EOF\n+\n+test_output_expect_success \"linear prune l5 ^l3\" 'git-rev-list --merge-order --show-breaks l5 ^l3' <<EOF\n+= l5\n+| l4\n+EOF\n+\n+test_output_expect_success \"linear prune l5 ^l4\" 'git-rev-list --merge-order --show-breaks l5 ^l4' <<EOF\n+= l5\n+EOF\n+\n+test_output_expect_success \"max-count 10 - merge order\" 'git-rev-list --merge-order --show-breaks --max-count=10 l5' <<EOF\n+= l5\n+| l4\n+| l3\n+= a4\n+| c3\n+| c2\n+| c1\n+^ b4\n+| b3\n+| b2\n+EOF\n+\n+test_output_expect_success \"max-count 10 - non merge order\" 'git-rev-list --max-count=10 l5 | sort' <<EOF\n+a4\n+b2\n+b3\n+b4\n+c1\n+c2\n+c3\n+l3\n+l4\n+l5\n+EOF\n+\n+test_output_expect_success '--max-age=c3, no --merge-order' \"git-rev-list --max-age=$(commit_date c3) l5\" <<EOF\n+l5\n+l4\n+l3\n+a4\n+b4\n+a3\n+a2\n+c3\n+EOF\n+\n+test_output_expect_success '--max-age=c3, --merge-order' \"git-rev-list --merge-order --max-age=$(commit_date c3) l5\" <<EOF\n+l5\n+l4\n+l3\n+a4\n+c3\n+b4\n+a3\n+a2\n+EOF\n+\n+test_output_expect_success 'one specified head reachable from another a4, c3, --merge-order' \"list_duplicates git-rev-list --merge-order a4 c3\" <<EOF\n+EOF\n+\n+test_output_expect_success 'one specified head reachable from another c3, a4, --merge-order' \"list_duplicates git-rev-list --merge-order c3 a4\" <<EOF\n+EOF\n+\n+test_output_expect_success 'one specified head reachable from another a4, c3, no --merge-order' \"list_duplicates git-rev-list a4 c3\" <<EOF\n+EOF\n+\n+test_output_expect_success 'one specified head reachable from another c3, a4, no --merge-order' \"list_duplicates git-rev-list c3 a4\" <<EOF\n+EOF\n+\n+test_output_expect_success 'graph with c3 and a4 parents of head' \"list_duplicates git-rev-list m1\" <<EOF\n+EOF\n+\n+test_output_expect_success 'graph with a4 and c3 parents of head' \"list_duplicates git-rev-list m2\" <<EOF\n+EOF\n+\n+test_expect_success \"head ^head --merge-order\" 'git-rev-list --merge-order --show-breaks a3 ^a3' <<EOF\n+EOF\n+\n+#\n+# can't test this now - duplicate parents can't be created\n+#\n+#test_output_expect_success 'duplicate parents' 'git-rev-list --parents --merge-order --show-breaks m3' <<EOF\n+#= m3 c3 a4 c3\n+#| a4 c3 b4 a3\n+#| b4 a3 b3\n+#| b3 b2\n+#^ a3 a2\n+#| a2 a1\n+#| a1 a0\n+#^ c3 c2\n+#| c2 b2 c1\n+#| b2 b1\n+#^ c1 b1\n+#| b1 a0\n+#= a0 l2\n+#| l2 l1\n+#| l1 l0\n+#| l0 root\n+#= root\n+#EOF\n+\n+test_expect_success \"head ^head no --merge-order\" 'git-rev-list a3 ^a3' <<EOF\n+EOF\n+#\n+#\n \n test_done\n------------\n"}]}