{"thread":{"id":"24765","subject":"[PATCH/RFC] updating examples/git-merge (plus a builtin/merge fix)","startedAt":"2010-08-17T06:51:47Z","lastAt":"2010-08-18T10:44:32Z","messageCount":36,"participants":["Jonathan Nieder","Ævar Arnfjörð Bjarmason","Tay Ray Chuan","Sverre Rabbelier"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"148231","messageId":"20100817065147.GA18293@burratino","threadId":"24765","inReplyTo":null,"subject":"[PATCH/RFC] updating examples/git-merge (plus a builtin/merge fix)","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T06:51:47Z","receivedAt":"2010-08-17T06:51:47Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"While preparing to make some minor \"git merge\" changes, I noticed that\nthe old merge script does not pass all tests any more.  Since it can\nbe easier to prototype in shell and then port to C, I think that is\nworth fixing.\n\nOf course this is not urgent at all.\n\nPatch 1 fixes a minor bug that the scripted implementation does not\nsuffer from, illustrated by the test \"merge early part of c2\" from\nt7600-merge.sh.\n\nThe underlying problem is a subtlety in the resolve_ref() API (from\nv0.99.8~13, Use resolve_ref() to implement read_ref(), 2005-09-30):\nthe \"reading\" argument to resolve_ref() should usually be true, but\nthat is not obvious to newcomers.\n\nPatches 2-7 are minor test changes.  They are early in the series\nto give flexibility about when to merge them.\n\nPatches 8-10 expose functionality used by merge when handling octopus\nmerges.  merge-base --octopus is get_octopus_merge_bases(), used to\nprovide basis arguments when running the \"git merge-octopus\" command.\nOf course the latter does not care about its basis arguments, but\nthat is a topic for another series.  merge-base --independent is\nreduce_refs(), used to reduce the parent list when --no-ff is not\nin use.\n\nThese are analagous to show-branch --merge-base and\nshow-branch --independent but are slower and can be used with more\nthan 25 refs.\n\nPatch 11 exposes the functionality from fmt-merge-msg needed to\nimplement merge --log -m.\n\nPatches 12 and later are ports of various patches to builtin/merge.c.\nI did the bare minimum to make tests pass. :)\n\nPatches are against jn/merge-renormalize~2 (rerere: migrate to\nparse-options API) from pu, because without that,\n\"rerere --rerere-autoupdate\" does not work.\n\nThoughts?\n\nJonathan Nieder (24):\n  merge: do not mistake (ancestor of) tag for branch\n  t7600 (merge): modernize style\n  t7600 (merge): do not launch gitk for --debug\n  t7600 (merge): check reflog entry\n  t7600 (merge): test merge from branch yet to be born\n  t6010 (merge-base): modernize style\n  t6200 (fmt-merge-msg): style nitpicks\n  Documentation: add a SEE ALSO section for merge-base\n  merge-base --octopus to mimic show-branch --merge-base\n  merge-base --independent to print reduced parent list in a merge\n  fmt-merge-msg -m to replace subject line\n  merge script: --squash, --ff from unborn branch are errors\n  merge script: tweak unmerged files message to match builtin\n  merge script: refuse to merge during merge\n  merge script: improve log message subject\n  merge script: merge -X<option>\n  merge script: allow custom strategies\n  merge script: forbid merge -s index\n  merge script: handle -m --log correctly\n  merge script: handle many-way octopus\n  merge script: --ff-only to disallow true merge\n  merge script: handle --no-ff --no-commit correctly\n  merge script: notice @{-1} shorthand\n  merge script: learn --[no-]rerere-autoupdate\n\n Documentation/git-fmt-merge-msg.txt |    9 +-\n Documentation/git-merge-base.txt    |   34 +++-\n builtin/fmt-merge-msg.c             |   18 ++-\n builtin/merge-base.c                |   44 ++++-\n builtin/merge.c                     |    2 +-\n contrib/examples/git-merge.sh       |  115 ++++++++---\n t/t6010-merge-base.sh               |  358 +++++++++++++++++++--------------\n t/t6200-fmt-merge-msg.sh            |  306 ++++++++++++++--------------\n t/t7600-merge.sh                    |  385 +++++++++++++++--------------------\n 9 files changed, 705 insertions(+), 566 deletions(-)\n"},{"id":"148232","messageId":"20100817065248.GA22057@burratino","threadId":"24765","inReplyTo":"20100817065147.GA18293@burratino","subject":"[PATCH 01/24] merge: do not mistake (ancestor of) tag for branch","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T06:52:48Z","receivedAt":"2010-08-17T06:52:48Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"If no branch 'foo' exists but a tag 'foo' does, then\ngit merge foo^ results in\n\n\tMerge branch 'foo' (early part)\n\nas a commit message, because the relevant code path checks that\nrefs/heads/foo is a valid refname for writing rather than for\nreading.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n builtin/merge.c  |    2 +-\n t/t7600-merge.sh |   16 ++++++++++++----\n 2 files changed, 13 insertions(+), 5 deletions(-)\n\ndiff --git a/builtin/merge.c b/builtin/merge.c\nindex b836e9c..f285b7e 100644\n--- a/builtin/merge.c\n+++ b/builtin/merge.c\n@@ -437,7 +437,7 @@ static void merge_name(const char *remote, struct strbuf *msg)\n \t\tstrbuf_addstr(&truname, \"refs/heads/\");\n \t\tstrbuf_addstr(&truname, remote);\n \t\tstrbuf_setlen(&truname, truname.len - len);\n-\t\tif (resolve_ref(truname.buf, buf_sha, 0, NULL)) {\n+\t\tif (resolve_ref(truname.buf, buf_sha, 1, NULL)) {\n \t\t\tstrbuf_addf(msg,\n \t\t\t\t    \"%s\\t\\tbranch '%s'%s of .\\n\",\n \t\t\t\t    sha1_to_hex(remote_head->sha1),\ndiff --git a/t/t7600-merge.sh b/t/t7600-merge.sh\nindex cde8390..16e5ba1 100755\n--- a/t/t7600-merge.sh\n+++ b/t/t7600-merge.sh\n@@ -558,8 +558,11 @@ test_expect_success 'refresh the index before merging' '\n \tgit merge c3\n '\n \n-cat >expected <<EOF\n-Merge branch 'c5' (early part)\n+cat >expected.branch <<\\EOF\n+Merge branch 'c5-branch' (early part)\n+EOF\n+cat >expected.tag <<\\EOF\n+Merge commit 'c5~1'\n EOF\n \n test_expect_success 'merge early part of c2' '\n@@ -577,9 +580,14 @@ test_expect_success 'merge early part of c2' '\n \tgit add c6.c &&\n \tgit commit -m c6 &&\n \tgit tag c6 &&\n+\tgit branch -f c5-branch c5 &&\n+\tgit merge c5-branch~1 &&\n+\tgit show -s --pretty=format:%s HEAD >actual.branch &&\n+\tgit reset --keep HEAD^ &&\n \tgit merge c5~1 &&\n-\tgit show -s --pretty=format:%s HEAD > actual &&\n-\ttest_cmp actual expected\n+\tgit show -s --pretty=format:%s HEAD >actual.tag &&\n+\ttest_cmp expected.branch actual.branch &&\n+\ttest_cmp expected.tag actual.tag\n '\n \n test_debug 'gitk --all'\n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"148233","messageId":"20100817065356.GB22057@burratino","threadId":"24765","inReplyTo":"20100817065147.GA18293@burratino","subject":"[PATCH 02/24] t7600 (merge): modernize style","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T06:53:56Z","receivedAt":"2010-08-17T06:53:56Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Guard setup commands with test_expect_success, so they are easier\nto visually skip over and get to the good part.  While at it:\n\n - use \"printf '%s\\n' a b ...\" instead of \"cat <<EOF\" for test\n   vectors with short lines;\n\n - use test_cmp instead of test foo = bar where possible, for\n   better output with -v on failure;\n\n - do not go to extraordinary lengths to print a relevant message\n   when test commands fail.  There is a patch in flight that could be\n   used to restore the nice error messages in a cleaner way.\n\nCc: Lars Hjemli <hjemli@gmail.com>\nCc: Matthieu Moy <Matthieu.Moy@imag.fr>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n t/t7600-merge.sh |  282 +++++++++++++++++++-----------------------------------\n 1 files changed, 98 insertions(+), 184 deletions(-)\n\ndiff --git a/t/t7600-merge.sh b/t/t7600-merge.sh\nindex 16e5ba1..48a91ba 100755\n--- a/t/t7600-merge.sh\n+++ b/t/t7600-merge.sh\n@@ -5,189 +5,103 @@\n \n test_description='git merge\n \n-Testing basic merge operations/option parsing.'\n+Testing basic merge operations/option parsing.\n+\n+! [c0] commit 0\n+ ! [c1] commit 1\n+  ! [c2] commit 2\n+   ! [c3] commit 3\n+    ! [c4] c4\n+     ! [c5] c5\n+      ! [c6] c6\n+       * [master] Merge commit 'c1'\n+--------\n+       - [master] Merge commit 'c1'\n+ +     * [c1] commit 1\n+      +  [c6] c6\n+     +   [c5] c5\n+    ++   [c4] c4\n+   ++++  [c3] commit 3\n+  +      [c2] commit 2\n++++++++* [c0] commit 0\n+'\n \n . ./test-lib.sh\n \n-cat >file <<EOF\n-1\n-2\n-3\n-4\n-5\n-6\n-7\n-8\n-9\n-EOF\n+test_expect_success 'set up test data and helpers' '\n+\tprintf \"%s\\n\" 1 2 3 4 5 6 7 8 9 >file &&\n+\tprintf \"%s\\n\" \"1 X\" 2 3 4 5 6 7 8 9 >file.1 &&\n+\tprintf \"%s\\n\" 1 2 3 4 \"5 X\" 6 7 8 9 >file.5 &&\n+\tprintf \"%s\\n\" 1 2 3 4 5 6 7 8 \"9 X\" >file.9 &&\n+\tprintf \"%s\\n\" \"1 X\" 2 3 4 5 6 7 8 9 >result.1 &&\n+\tprintf \"%s\\n\" \"1 X\" 2 3 4 \"5 X\" 6 7 8 9 >result.1-5 &&\n+\tprintf \"%s\\n\" \"1 X\" 2 3 4 \"5 X\" 6 7 8 \"9 X\" >result.1-5-9 &&\n \n-cat >file.1 <<EOF\n-1 X\n-2\n-3\n-4\n-5\n-6\n-7\n-8\n-9\n-EOF\n+\tcreate_merge_msgs() {\n+\t\techo \"Merge commit '\\''c2'\\''\" >msg.1-5 &&\n+\t\techo \"Merge commit '\\''c2'\\''; commit '\\''c3'\\''\" >msg.1-5-9 &&\n+\t\t{\n+\t\t\techo \"Squashed commit of the following:\" &&\n+\t\t\techo &&\n+\t\t\tgit log --no-merges ^HEAD c1\n+\t\t} >squash.1 &&\n+\t\t{\n+\t\t\techo \"Squashed commit of the following:\" &&\n+\t\t\techo &&\n+\t\t\tgit log --no-merges ^HEAD c2\n+\t\t} >squash.1-5 &&\n+\t\t{\n+\t\t\techo \"Squashed commit of the following:\" &&\n+\t\t\techo &&\n+\t\t\tgit log --no-merges ^HEAD c2 c3\n+\t\t} >squash.1-5-9 &&\n+\t\techo >msg.nolog &&\n+\t\t{\n+\t\t\techo \"* commit '\\''c3'\\'':\" &&\n+\t\t\techo \"  commit 3\" &&\n+\t\t\techo\n+\t\t} >msg.log\n+\t} &&\n \n-cat >file.5 <<EOF\n-1\n-2\n-3\n-4\n-5 X\n-6\n-7\n-8\n-9\n-EOF\n-\n-cat >file.9 <<EOF\n-1\n-2\n-3\n-4\n-5\n-6\n-7\n-8\n-9 X\n-EOF\n-\n-cat  >result.1 <<EOF\n-1 X\n-2\n-3\n-4\n-5\n-6\n-7\n-8\n-9\n-EOF\n-\n-cat >result.1-5 <<EOF\n-1 X\n-2\n-3\n-4\n-5 X\n-6\n-7\n-8\n-9\n-EOF\n-\n-cat >result.1-5-9 <<EOF\n-1 X\n-2\n-3\n-4\n-5 X\n-6\n-7\n-8\n-9 X\n-EOF\n-\n-create_merge_msgs() {\n-\techo \"Merge commit 'c2'\" >msg.1-5 &&\n-\techo \"Merge commit 'c2'; commit 'c3'\" >msg.1-5-9 &&\n-\techo \"Squashed commit of the following:\" >squash.1 &&\n-\techo >>squash.1 &&\n-\tgit log --no-merges ^HEAD c1 >>squash.1 &&\n-\techo \"Squashed commit of the following:\" >squash.1-5 &&\n-\techo >>squash.1-5 &&\n-\tgit log --no-merges ^HEAD c2 >>squash.1-5 &&\n-\techo \"Squashed commit of the following:\" >squash.1-5-9 &&\n-\techo >>squash.1-5-9 &&\n-\tgit log --no-merges ^HEAD c2 c3 >>squash.1-5-9 &&\n-\techo > msg.nolog &&\n-\techo \"* commit 'c3':\" >msg.log &&\n-\techo \"  commit 3\" >>msg.log &&\n-\techo >>msg.log\n-}\n-\n-verify_diff() {\n-\tif ! test_cmp \"$1\" \"$2\"\n-\tthen\n-\t\techo \"$3\"\n-\t\tfalse\n-\tfi\n-}\n-\n-verify_merge() {\n-\tverify_diff \"$2\" \"$1\" \"[OOPS] bad merge result\" &&\n-\tif test $(git ls-files -u | wc -l) -gt 0\n-\tthen\n-\t\techo \"[OOPS] unmerged files\"\n-\t\tfalse\n-\tfi &&\n-\tif test_must_fail git diff --exit-code\n-\tthen\n-\t\techo \"[OOPS] working tree != index\"\n-\t\tfalse\n-\tfi &&\n-\tif test -n \"$3\"\n-\tthen\n-\t\tgit show -s --pretty=format:%s HEAD >msg.act &&\n-\t\tverify_diff \"$3\" msg.act \"[OOPS] bad merge message\"\n-\tfi\n-}\n-\n-verify_head() {\n-\tif test \"$1\" != \"$(git rev-parse HEAD)\"\n-\tthen\n-\t\techo \"[OOPS] HEAD != $1\"\n-\t\tfalse\n-\tfi\n-}\n-\n-verify_parents() {\n-\ti=1\n-\twhile test $# -gt 0\n-\tdo\n-\t\tif test \"$1\" != \"$(git rev-parse HEAD^$i)\"\n+\tverify_merge() {\n+\t\ttest_cmp \"$2\" \"$1\" &&\n+\t\tgit update-index --refresh &&\n+\t\tgit diff --exit-code &&\n+\t\tif test -n \"$3\"\n \t\tthen\n-\t\t\techo \"[OOPS] HEAD^$i != $1\"\n-\t\t\treturn 1\n+\t\t\tgit show -s --pretty=format:%s HEAD >msg.act &&\n+\t\t\ttest_cmp \"$3\" msg.act\n \t\tfi\n-\t\ti=$(expr $i + 1)\n-\t\tshift\n-\tdone\n-}\n+\t} &&\n \n-verify_mergeheads() {\n-\ti=1\n-\tif ! test -f .git/MERGE_HEAD\n-\tthen\n-\t\techo \"[OOPS] MERGE_HEAD is missing\"\n-\t\tfalse\n-\tfi &&\n-\twhile test $# -gt 0\n-\tdo\n-\t\thead=$(head -n $i .git/MERGE_HEAD | sed -ne \\$p)\n-\t\tif test \"$1\" != \"$head\"\n-\t\tthen\n-\t\t\techo \"[OOPS] MERGE_HEAD $i != $1\"\n+\tverify_head() {\n+\t\techo \"$1\" >head.expected &&\n+\t\tgit rev-parse HEAD >head.actual &&\n+\t\ttest_cmp head.expected head.actual\n+\t} &&\n+\n+\tverify_parents() {\n+\t\tprintf \"%s\\n\" \"$@\" >parents.expected &&\n+\t\t>parents.actual &&\n+\t\ti=1 &&\n+\t\twhile test $i -le $#\n+\t\tdo\n+\t\t\tgit rev-parse HEAD^$i >>parents.actual &&\n+\t\t\ti=$(expr $i + 1) ||\n \t\t\treturn 1\n-\t\tfi\n-\t\ti=$(expr $i + 1)\n-\t\tshift\n-\tdone\n-}\n+\t\tdone &&\n+\t\ttest_cmp parents.expected parents.actual\n+\t} &&\n \n-verify_no_mergehead() {\n-\tif test -f .git/MERGE_HEAD\n-\tthen\n-\t\techo \"[OOPS] MERGE_HEAD exists\"\n-\t\tfalse\n-\tfi\n-}\n+\tverify_mergeheads() {\n+\t\tprintf \"%s\\n\" \"$@\" >mergehead.expected &&\n+\t\ttest_cmp mergehead.expected .git/MERGE_HEAD\n+\t} &&\n \n+\tverify_no_mergehead() {\n+\t\t! test -e .git/MERGE_HEAD\n+\t}\n+'\n \n test_expect_success 'setup' '\n \tgit add file &&\n@@ -316,7 +230,7 @@ test_expect_success 'merge c0 with c1 (squash)' '\n \tverify_merge file result.1 &&\n \tverify_head $c0 &&\n \tverify_no_mergehead &&\n-\tverify_diff squash.1 .git/SQUASH_MSG \"[OOPS] bad squash message\"\n+\ttest_cmp squash.1 .git/SQUASH_MSG\n '\n \n test_debug 'gitk --all'\n@@ -327,7 +241,7 @@ test_expect_success 'merge c0 with c1 (squash, ff-only)' '\n \tverify_merge file result.1 &&\n \tverify_head $c0 &&\n \tverify_no_mergehead &&\n-\tverify_diff squash.1 .git/SQUASH_MSG \"[OOPS] bad squash message\"\n+\ttest_cmp squash.1 .git/SQUASH_MSG\n '\n \n test_debug 'gitk --all'\n@@ -338,7 +252,7 @@ test_expect_success 'merge c1 with c2 (squash)' '\n \tverify_merge file result.1-5 &&\n \tverify_head $c1 &&\n \tverify_no_mergehead &&\n-\tverify_diff squash.1-5 .git/SQUASH_MSG \"[OOPS] bad squash message\"\n+\ttest_cmp squash.1-5 .git/SQUASH_MSG\n '\n \n test_debug 'gitk --all'\n@@ -356,7 +270,7 @@ test_expect_success 'merge c1 with c2 and c3 (squash)' '\n \tverify_merge file result.1-5-9 &&\n \tverify_head $c1 &&\n \tverify_no_mergehead &&\n-\tverify_diff squash.1-5-9 .git/SQUASH_MSG \"[OOPS] bad squash message\"\n+\ttest_cmp squash.1-5-9 .git/SQUASH_MSG\n '\n \n test_debug 'gitk --all'\n@@ -379,7 +293,7 @@ test_expect_success 'merge c1 with c2 (squash in config)' '\n \tverify_merge file result.1-5 &&\n \tverify_head $c1 &&\n \tverify_no_mergehead &&\n-\tverify_diff squash.1-5 .git/SQUASH_MSG \"[OOPS] bad squash message\"\n+\ttest_cmp squash.1-5 .git/SQUASH_MSG\n '\n \n test_debug 'gitk --all'\n@@ -485,17 +399,17 @@ test_expect_success 'merge log message' '\n \tgit reset --hard c0 &&\n \tgit merge --no-log c2 &&\n \tgit show -s --pretty=format:%b HEAD >msg.act &&\n-\tverify_diff msg.nolog msg.act \"[OOPS] bad merge log message\" &&\n+\ttest_cmp msg.nolog msg.act &&\n \n \tgit merge --log c3 &&\n \tgit show -s --pretty=format:%b HEAD >msg.act &&\n-\tverify_diff msg.log msg.act \"[OOPS] bad merge log message\" &&\n+\ttest_cmp msg.log msg.act &&\n \n \tgit reset --hard HEAD^ &&\n \tgit config merge.log yes &&\n \tgit merge c3 &&\n \tgit show -s --pretty=format:%b HEAD >msg.act &&\n-\tverify_diff msg.log msg.act \"[OOPS] bad merge log message\"\n+\ttest_cmp msg.log msg.act\n '\n \n test_debug 'gitk --all'\n@@ -545,7 +459,7 @@ test_debug 'gitk --all'\n \n test_expect_success 'in-index merge' '\n \tgit reset --hard c0 &&\n-\tgit merge --no-ff -s resolve c1 > out &&\n+\tgit merge --no-ff -s resolve c1 >out &&\n \tgrep \"Wonderful.\" out &&\n \tverify_parents $c0 $c1\n '\n@@ -567,16 +481,16 @@ EOF\n \n test_expect_success 'merge early part of c2' '\n \tgit reset --hard c3 &&\n-\techo c4 > c4.c &&\n+\techo c4 >c4.c &&\n \tgit add c4.c &&\n \tgit commit -m c4 &&\n \tgit tag c4 &&\n-\techo c5 > c5.c &&\n+\techo c5 >c5.c &&\n \tgit add c5.c &&\n \tgit commit -m c5 &&\n \tgit tag c5 &&\n \tgit reset --hard c3 &&\n-\techo c6 > c6.c &&\n+\techo c6 >c6.c &&\n \tgit add c6.c &&\n \tgit commit -m c6 &&\n \tgit tag c6 &&\n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"148234","messageId":"20100817065459.GC22057@burratino","threadId":"24765","inReplyTo":"20100817065147.GA18293@burratino","subject":"[PATCH 03/24] t7600 (merge): do not launch gitk for --debug","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T06:54:59Z","receivedAt":"2010-08-17T06:54:59Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Probably as a development aid, this test script runs gitk --all\nto allow the driver to inspect history between tests when run\nwith --debug.  As a result, running all tests with --debug\nrequires closing a long series of gitk displays, one at a time.\n\nUse git log --graph --oneline instead.  This way, the history is\navailable for viewing with \"git show\" but the test script finishes\nwithout interaction.\n\nLonger term, it would be nice to have an option to run a\nuser-specified command between tests.  This patch does not do\nthat.\n\nCc: Lars Hjemli <hjemli@gmail.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n t/t7600-merge.sh |   58 +++++++++++++++++++++++++++---------------------------\n 1 files changed, 29 insertions(+), 29 deletions(-)\n\ndiff --git a/t/t7600-merge.sh b/t/t7600-merge.sh\nindex 48a91ba..64a4265 100755\n--- a/t/t7600-merge.sh\n+++ b/t/t7600-merge.sh\n@@ -133,7 +133,7 @@ test_expect_success 'setup' '\n \tcreate_merge_msgs\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'test option parsing' '\n \ttest_must_fail git merge -$ c1 &&\n@@ -155,7 +155,7 @@ test_expect_success 'merge c0 with c1' '\n \tverify_head \"$c1\"\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'merge c0 with c1 with --ff-only' '\n \tgit reset --hard c0 &&\n@@ -165,7 +165,7 @@ test_expect_success 'merge c0 with c1 with --ff-only' '\n \tverify_head \"$c1\"\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'merge c1 with c2' '\n \tgit reset --hard c1 &&\n@@ -175,7 +175,7 @@ test_expect_success 'merge c1 with c2' '\n \tverify_parents $c1 $c2\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'merge c1 with c2 and c3' '\n \tgit reset --hard c1 &&\n@@ -185,7 +185,7 @@ test_expect_success 'merge c1 with c2 and c3' '\n \tverify_parents $c1 $c2 $c3\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'failing merges with --ff-only' '\n \tgit reset --hard c1 &&\n@@ -202,7 +202,7 @@ test_expect_success 'merge c0 with c1 (no-commit)' '\n \tverify_head $c1\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'merge c1 with c2 (no-commit)' '\n \tgit reset --hard c1 &&\n@@ -212,7 +212,7 @@ test_expect_success 'merge c1 with c2 (no-commit)' '\n \tverify_mergeheads $c2\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'merge c1 with c2 and c3 (no-commit)' '\n \tgit reset --hard c1 &&\n@@ -222,7 +222,7 @@ test_expect_success 'merge c1 with c2 and c3 (no-commit)' '\n \tverify_mergeheads $c2 $c3\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'merge c0 with c1 (squash)' '\n \tgit reset --hard c0 &&\n@@ -233,7 +233,7 @@ test_expect_success 'merge c0 with c1 (squash)' '\n \ttest_cmp squash.1 .git/SQUASH_MSG\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'merge c0 with c1 (squash, ff-only)' '\n \tgit reset --hard c0 &&\n@@ -244,7 +244,7 @@ test_expect_success 'merge c0 with c1 (squash, ff-only)' '\n \ttest_cmp squash.1 .git/SQUASH_MSG\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'merge c1 with c2 (squash)' '\n \tgit reset --hard c1 &&\n@@ -255,14 +255,14 @@ test_expect_success 'merge c1 with c2 (squash)' '\n \ttest_cmp squash.1-5 .git/SQUASH_MSG\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'unsuccesful merge of c1 with c2 (squash, ff-only)' '\n \tgit reset --hard c1 &&\n \ttest_must_fail git merge --squash --ff-only c2\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'merge c1 with c2 and c3 (squash)' '\n \tgit reset --hard c1 &&\n@@ -273,7 +273,7 @@ test_expect_success 'merge c1 with c2 and c3 (squash)' '\n \ttest_cmp squash.1-5-9 .git/SQUASH_MSG\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'merge c1 with c2 (no-commit in config)' '\n \tgit reset --hard c1 &&\n@@ -284,7 +284,7 @@ test_expect_success 'merge c1 with c2 (no-commit in config)' '\n \tverify_mergeheads $c2\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'merge c1 with c2 (squash in config)' '\n \tgit reset --hard c1 &&\n@@ -296,7 +296,7 @@ test_expect_success 'merge c1 with c2 (squash in config)' '\n \ttest_cmp squash.1-5 .git/SQUASH_MSG\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'override config option -n with --summary' '\n \tgit reset --hard c1 &&\n@@ -326,7 +326,7 @@ test_expect_success 'override config option -n with --stat' '\n \tfi\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'override config option --stat' '\n \tgit reset --hard c1 &&\n@@ -342,7 +342,7 @@ test_expect_success 'override config option --stat' '\n \tfi\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'merge c1 with c2 (override --no-commit)' '\n \tgit reset --hard c1 &&\n@@ -353,7 +353,7 @@ test_expect_success 'merge c1 with c2 (override --no-commit)' '\n \tverify_parents $c1 $c2\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'merge c1 with c2 (override --squash)' '\n \tgit reset --hard c1 &&\n@@ -364,7 +364,7 @@ test_expect_success 'merge c1 with c2 (override --squash)' '\n \tverify_parents $c1 $c2\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'merge c0 with c1 (no-ff)' '\n \tgit reset --hard c0 &&\n@@ -375,7 +375,7 @@ test_expect_success 'merge c0 with c1 (no-ff)' '\n \tverify_parents $c0 $c1\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'combining --squash and --no-ff is refused' '\n \ttest_must_fail git merge --squash --no-ff c1 &&\n@@ -412,7 +412,7 @@ test_expect_success 'merge log message' '\n \ttest_cmp msg.log msg.act\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'merge c1 with c0, c2, c0, and c1' '\n        git reset --hard c1 &&\n@@ -423,7 +423,7 @@ test_expect_success 'merge c1 with c0, c2, c0, and c1' '\n        verify_parents $c1 $c2\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'merge c1 with c0, c2, c0, and c1' '\n        git reset --hard c1 &&\n@@ -434,7 +434,7 @@ test_expect_success 'merge c1 with c0, c2, c0, and c1' '\n        verify_parents $c1 $c2\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'merge c1 with c1 and c2' '\n        git reset --hard c1 &&\n@@ -445,7 +445,7 @@ test_expect_success 'merge c1 with c1 and c2' '\n        verify_parents $c1 $c2\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'merge fast-forward in a dirty tree' '\n        git reset --hard c0 &&\n@@ -455,7 +455,7 @@ test_expect_success 'merge fast-forward in a dirty tree' '\n        git merge c2\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'in-index merge' '\n \tgit reset --hard c0 &&\n@@ -464,7 +464,7 @@ test_expect_success 'in-index merge' '\n \tverify_parents $c0 $c1\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'refresh the index before merging' '\n \tgit reset --hard c1 &&\n@@ -504,7 +504,7 @@ test_expect_success 'merge early part of c2' '\n \ttest_cmp expected.tag actual.tag\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'merge --no-ff --no-commit && commit' '\n \tgit reset --hard c0 &&\n@@ -513,13 +513,13 @@ test_expect_success 'merge --no-ff --no-commit && commit' '\n \tverify_parents $c0 $c1\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_expect_success 'amending no-ff merge commit' '\n \tEDITOR=: git commit --amend &&\n \tverify_parents $c0 $c1\n '\n \n-test_debug 'gitk --all'\n+test_debug 'git log --graph --decorate --oneline --all'\n \n test_done\n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"148235","messageId":"20100817065613.GD22057@burratino","threadId":"24765","inReplyTo":"20100817065147.GA18293@burratino","subject":"[PATCH 04/24] t7600 (merge): check reflog entry","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T06:56:13Z","receivedAt":"2010-08-17T06:56:13Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"The details of the reflog message are not important, but\nincluding something sane in the reflog is.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n t/t7600-merge.sh |    8 +++++++-\n 1 files changed, 7 insertions(+), 1 deletions(-)\n\ndiff --git a/t/t7600-merge.sh b/t/t7600-merge.sh\nindex 64a4265..6e839a6 100755\n--- a/t/t7600-merge.sh\n+++ b/t/t7600-merge.sh\n@@ -149,10 +149,16 @@ test_expect_success 'reject non-strategy with a git-merge-foo name' '\n '\n \n test_expect_success 'merge c0 with c1' '\n+\techo \"OBJID HEAD@{0}: merge c1: Fast-forward\" >reflog.expected &&\n+\n \tgit reset --hard c0 &&\n \tgit merge c1 &&\n \tverify_merge file result.1 &&\n-\tverify_head \"$c1\"\n+\tverify_head \"$c1\" &&\n+\n+\tgit reflog -1 >reflog.actual &&\n+\tsed \"s/$_x05[0-9a-f]*/OBJID/g\" reflog.actual >reflog.fuzzy &&\n+\ttest_cmp reflog.expected reflog.fuzzy\n '\n \n test_debug 'git log --graph --decorate --oneline --all'\n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"148236","messageId":"20100817065646.GE22057@burratino","threadId":"24765","inReplyTo":"20100817065147.GA18293@burratino","subject":"[PATCH 05/24] t7600 (merge): test merge from branch yet to be born","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T06:56:46Z","receivedAt":"2010-08-17T06:56:46Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Some people like to \"git fetch origin && merge origin/master\" from\nthe unborn branch provided when first initializing a repository.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n t/t7600-merge.sh |   21 +++++++++++++++++++++\n 1 files changed, 21 insertions(+), 0 deletions(-)\n\ndiff --git a/t/t7600-merge.sh b/t/t7600-merge.sh\nindex 6e839a6..b4f40e4 100755\n--- a/t/t7600-merge.sh\n+++ b/t/t7600-merge.sh\n@@ -173,6 +173,27 @@ test_expect_success 'merge c0 with c1 with --ff-only' '\n \n test_debug 'git log --graph --decorate --oneline --all'\n \n+test_expect_success 'merge from unborn branch' '\n+\tgit checkout -f master &&\n+\ttest_might_fail git branch -D kid &&\n+\n+\techo \"OBJID HEAD@{0}: initial pull\" >reflog.expected &&\n+\n+\tgit checkout --orphan kid &&\n+\ttest_when_finished \"git checkout -f master\" &&\n+\tgit rm -fr . &&\n+\ttest_tick &&\n+\tgit merge --ff-only c1 &&\n+\tverify_merge file result.1 &&\n+\tverify_head \"$c1\" &&\n+\n+\tgit reflog -1 >reflog.actual &&\n+\tsed \"s/$_x05[0-9a-f][0-9a-f]/OBJID/g\" reflog.actual >reflog.fuzzy &&\n+\ttest_cmp reflog.expected reflog.fuzzy\n+'\n+\n+test_debug 'git log --graph --decorate --oneline --all'\n+\n test_expect_success 'merge c1 with c2' '\n \tgit reset --hard c1 &&\n \ttest_tick &&\n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"148237","messageId":"20100817065712.GF22057@burratino","threadId":"24765","inReplyTo":"20100817065147.GA18293@burratino","subject":"[PATCH 06/24] t6010 (merge-base): modernize style","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T06:57:12Z","receivedAt":"2010-08-17T06:57:12Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Guard setup with test_expect_success, put the opening quote\nstarting each test on the same line as the test_expect_* invocation,\nand combine related actions into single tests.\n\nWhile at it:\n\n - use test_cmp instead of expr or test $foo = $bar, for more helpful\n   output with -v when tests fail;\n\n - use test_commit for brevity.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n t/t6010-merge-base.sh |  317 ++++++++++++++++++++++++++-----------------------\n 1 files changed, 167 insertions(+), 150 deletions(-)\n\ndiff --git a/t/t6010-merge-base.sh b/t/t6010-merge-base.sh\nindex 0144d9e..4466e45 100755\n--- a/t/t6010-merge-base.sh\n+++ b/t/t6010-merge-base.sh\n@@ -8,170 +8,187 @@ test_description='Merge base computation.\n \n . ./test-lib.sh\n \n-T=$(git write-tree)\n-\n-M=1130000000\n-Z=+0000\n-\n-GIT_COMMITTER_EMAIL=git@comm.iter.xz\n-GIT_COMMITTER_NAME='C O Mmiter'\n-GIT_AUTHOR_NAME='A U Thor'\n-GIT_AUTHOR_EMAIL=git@au.thor.xz\n-export GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL\n-\n-doit() {\n-\tOFFSET=$1; shift\n-\tNAME=$1; shift\n-\tPARENTS=\n-\tfor P\n-\tdo\n-\t\tPARENTS=\"${PARENTS}-p $P \"\n-\tdone\n-\tGIT_COMMITTER_DATE=\"$(($M + $OFFSET)) $Z\"\n-\tGIT_AUTHOR_DATE=$GIT_COMMITTER_DATE\n-\texport GIT_COMMITTER_DATE GIT_AUTHOR_DATE\n-\tcommit=$(echo $NAME | git commit-tree $T $PARENTS)\n-\techo $commit >.git/refs/tags/$NAME\n-\techo $commit\n-}\n-\n-#  E---D---C---B---A\n-#  \\'-_         \\   \\\n-#   \\  `---------G   \\\n-#    \\                \\\n-#     F----------------H\n-\n-# Setup...\n-E=$(doit 5 E)\n-D=$(doit 4 D $E)\n-F=$(doit 6 F $E)\n-C=$(doit 3 C $D)\n-B=$(doit 2 B $C)\n-A=$(doit 1 A $B)\n-G=$(doit 7 G $B $E)\n-H=$(doit 8 H $A $F)\n-\n-test_expect_success 'compute merge-base (single)' \\\n-    'MB=$(git merge-base G H) &&\n-     expr \"$(git name-rev \"$MB\")\" : \"[0-9a-f]* tags/B\"'\n-\n-test_expect_success 'compute merge-base (all)' \\\n-    'MB=$(git merge-base --all G H) &&\n-     expr \"$(git name-rev \"$MB\")\" : \"[0-9a-f]* tags/B\"'\n-\n-test_expect_success 'compute merge-base with show-branch' \\\n-    'MB=$(git show-branch --merge-base G H) &&\n-     expr \"$(git name-rev \"$MB\")\" : \"[0-9a-f]* tags/B\"'\n-\n-# Setup for second test to demonstrate that relying on timestamps in a\n-# distributed SCM to provide a _consistent_ partial ordering of commits\n-# leads to insanity.\n-#\n-#               Relative\n-# Structure     timestamps\n-#\n-#   PL  PR        +4  +4\n-#  /  \\/  \\      /  \\/  \\\n-# L2  C2  R2    +3  -1  +3\n-# |   |   |     |   |   |\n-# L1  C1  R1    +2  -2  +2\n-# |   |   |     |   |   |\n-# L0  C0  R0    +1  -3  +1\n-#   \\ |  /        \\ |  /\n-#     S             0\n-#\n-# The left and right chains of commits can be of any length and complexity as\n-# long as all of the timestamps are greater than that of S.\n-\n-S=$(doit  0 S)\n-\n-C0=$(doit -3 C0 $S)\n-C1=$(doit -2 C1 $C0)\n-C2=$(doit -1 C2 $C1)\n-\n-L0=$(doit  1 L0 $S)\n-L1=$(doit  2 L1 $L0)\n-L2=$(doit  3 L2 $L1)\n-\n-R0=$(doit  1 R0 $S)\n-R1=$(doit  2 R1 $R0)\n-R2=$(doit  3 R2 $R1)\n-\n-PL=$(doit  4 PL $L2 $C2)\n-PR=$(doit  4 PR $C2 $R2)\n-\n-test_expect_success 'compute merge-base (single)' \\\n-    'MB=$(git merge-base PL PR) &&\n-     expr \"$(git name-rev \"$MB\")\" : \"[0-9a-f]* tags/C2\"'\n-\n-test_expect_success 'compute merge-base (all)' \\\n-    'MB=$(git merge-base --all PL PR) &&\n-     expr \"$(git name-rev \"$MB\")\" : \"[0-9a-f]* tags/C2\"'\n-\n-# Another set to demonstrate base between one commit and a merge\n-# in the documentation.\n-#\n-# * C (MMC) * B (MMB) * A  (MMA)\n-# * o       * o       * o\n-# * o       * o       * o\n-# * o       * o       * o\n-# * o       | _______/\n-# |         |/\n-# |         * 1 (MM1)\n-# | _______/\n-# |/\n-# * root (MMR)\n-\n+test_expect_success 'setup' '\n+\tT=$(git write-tree) &&\n+\n+\tM=1130000000 &&\n+\tZ=+0000 &&\n+\n+\tGIT_COMMITTER_EMAIL=git@comm.iter.xz &&\n+\tGIT_COMMITTER_NAME=\"C O Mmiter\" &&\n+\tGIT_AUTHOR_NAME=\"A U Thor\" &&\n+\tGIT_AUTHOR_EMAIL=git@au.thor.xz &&\n+\texport GIT_COMMITTER_EMAIL GIT_COMMITTER_NAME GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL &&\n+\n+\tdoit() {\n+\t\tOFFSET=$1 &&\n+\t\tNAME=$2 &&\n+\t\tshift 2 &&\n+\n+\t\tPARENTS= &&\n+\t\tfor P\n+\t\tdo\n+\t\t\tPARENTS=\"${PARENTS}-p $P \"\n+\t\tdone &&\n+\n+\t\tGIT_COMMITTER_DATE=\"$(($M + $OFFSET)) $Z\" &&\n+\t\tGIT_AUTHOR_DATE=$GIT_COMMITTER_DATE &&\n+\t\texport GIT_COMMITTER_DATE GIT_AUTHOR_DATE &&\n+\n+\t\tcommit=$(echo $NAME | git commit-tree $T $PARENTS) &&\n+\n+\t\techo $commit >.git/refs/tags/$NAME &&\n+\t\techo $commit\n+\t}\n+'\n+\n+test_expect_success 'set up G and H' '\n+\t# E---D---C---B---A\n+\t# \\\"-_         \\   \\\n+\t#  \\  `---------G   \\\n+\t#   \\                \\\n+\t#    F----------------H\n+\tE=$(doit 5 E) &&\n+\tD=$(doit 4 D $E) &&\n+\tF=$(doit 6 F $E) &&\n+\tC=$(doit 3 C $D) &&\n+\tB=$(doit 2 B $C) &&\n+\tA=$(doit 1 A $B) &&\n+\tG=$(doit 7 G $B $E) &&\n+\tH=$(doit 8 H $A $F)\n+'\n+\n+test_expect_success 'merge-base G H' '\n+\tgit name-rev $B >expected &&\n+\n+\tMB=$(git merge-base G H) &&\n+\tgit name-rev \"$MB\" >actual.single &&\n+\n+\tMB=$(git merge-base --all G H) &&\n+\tgit name-rev \"$MB\" >actual.all &&\n+\n+\tMB=$(git show-branch --merge-base G H) &&\n+\tgit name-rev \"$MB\" >actual.sb &&\n+\n+\ttest_cmp expected actual.single &&\n+\ttest_cmp expected actual.all &&\n+\ttest_cmp expected actual.sb\n+'\n+\n+test_expect_success 'unsynchronized clocks' '\n+\t# This test is to demonstrate that relying on timestamps in a distributed\n+\t# SCM to provide a _consistent_ partial ordering of commits leads to\n+\t# insanity.\n+\t#\n+\t#               Relative\n+\t# Structure     timestamps\n+\t#\n+\t#   PL  PR        +4  +4\n+\t#  /  \\/  \\      /  \\/  \\\n+\t# L2  C2  R2    +3  -1  +3\n+\t# |   |   |     |   |   |\n+\t# L1  C1  R1    +2  -2  +2\n+\t# |   |   |     |   |   |\n+\t# L0  C0  R0    +1  -3  +1\n+\t#   \\ |  /        \\ |  /\n+\t#     S             0\n+\t#\n+\t# The left and right chains of commits can be of any length and complexity as\n+\t# long as all of the timestamps are greater than that of S.\n+\n+\tS=$(doit  0 S) &&\n+\n+\tC0=$(doit -3 C0 $S) &&\n+\tC1=$(doit -2 C1 $C0) &&\n+\tC2=$(doit -1 C2 $C1) &&\n+\n+\tL0=$(doit  1 L0 $S) &&\n+\tL1=$(doit  2 L1 $L0) &&\n+\tL2=$(doit  3 L2 $L1) &&\n+\n+\tR0=$(doit  1 R0 $S) &&\n+\tR1=$(doit  2 R1 $R0) &&\n+\tR2=$(doit  3 R2 $R1) &&\n+\n+\tPL=$(doit  4 PL $L2 $C2) &&\n+\tPR=$(doit  4 PR $C2 $R2)\n+\n+\tgit name-rev $C2 >expected &&\n+\n+\tMB=$(git merge-base PL PR) &&\n+\tgit name-rev \"$MB\" >actual.single &&\n+\n+\tMB=$(git merge-base --all PL PR) &&\n+\tgit name-rev \"$MB\" >actual.all &&\n+\n+\ttest_cmp expected actual.single &&\n+\ttest_cmp expected actual.all\n+'\n \n test_expect_success 'merge-base for octopus-step (setup)' '\n-\ttest_tick && git commit --allow-empty -m root && git tag MMR &&\n-\ttest_tick && git commit --allow-empty -m 1 && git tag MM1 &&\n-\ttest_tick && git commit --allow-empty -m o &&\n-\ttest_tick && git commit --allow-empty -m o &&\n-\ttest_tick && git commit --allow-empty -m o &&\n-\ttest_tick && git commit --allow-empty -m A && git tag MMA &&\n+\t# Another set to demonstrate base between one commit and a merge\n+\t# in the documentation.\n+\t#\n+\t# * C (MMC) * B (MMB) * A  (MMA)\n+\t# * o       * o       * o\n+\t# * o       * o       * o\n+\t# * o       * o       * o\n+\t# * o       | _______/\n+\t# |         |/\n+\t# |         * 1 (MM1)\n+\t# | _______/\n+\t# |/\n+\t# * root (MMR)\n+\n+\ttest_commit MMR &&\n+\ttest_commit MM1 &&\n+\ttest_commit MM-o &&\n+\ttest_commit MM-p &&\n+\ttest_commit MM-q &&\n+\ttest_commit MMA &&\n \tgit checkout MM1 &&\n-\ttest_tick && git commit --allow-empty -m o &&\n-\ttest_tick && git commit --allow-empty -m o &&\n-\ttest_tick && git commit --allow-empty -m o &&\n-\ttest_tick && git commit --allow-empty -m B && git tag MMB &&\n+\ttest_commit MM-r &&\n+\ttest_commit MM-s &&\n+\ttest_commit MM-t &&\n+\ttest_commit MMB &&\n \tgit checkout MMR &&\n-\ttest_tick && git commit --allow-empty -m o &&\n-\ttest_tick && git commit --allow-empty -m o &&\n-\ttest_tick && git commit --allow-empty -m o &&\n-\ttest_tick && git commit --allow-empty -m o &&\n-\ttest_tick && git commit --allow-empty -m C && git tag MMC\n+\ttest_commit MM-u &&\n+\ttest_commit MM-v &&\n+\ttest_commit MM-w &&\n+\ttest_commit MM-x &&\n+\ttest_commit MMC\n '\n \n test_expect_success 'merge-base A B C' '\n-\tMB=$(git merge-base --all MMA MMB MMC) &&\n-\tMM1=$(git rev-parse --verify MM1) &&\n-\ttest \"$MM1\" = \"$MB\"\n-'\n+\tgit rev-parse --verify MM1 >expected &&\n+\tgit rev-parse --verify MMR >expected.sb &&\n+\n+\tgit merge-base --all MMA MMB MMC >actual &&\n+\tgit show-branch --merge-base MMA MMB MMC >actual.sb &&\n \n-test_expect_success 'merge-base A B C using show-branch' '\n-\tMB=$(git show-branch --merge-base MMA MMB MMC) &&\n-\tMMR=$(git rev-parse --verify MMR) &&\n-\ttest \"$MMR\" = \"$MB\"\n+\ttest_cmp expected actual &&\n+\ttest_cmp expected.sb actual.sb\n '\n \n-test_expect_success 'criss-cross merge-base for octopus-step (setup)' '\n+test_expect_success 'criss-cross merge-base for octopus-step' '\n \tgit reset --hard MMR &&\n-\ttest_tick && git commit --allow-empty -m 1 && git tag CC1 &&\n+\ttest_commit CC1 &&\n \tgit reset --hard E &&\n-\ttest_tick && git commit --allow-empty -m 2 && git tag CC2 &&\n-\ttest_tick && git merge -s ours CC1 &&\n-\ttest_tick && git commit --allow-empty -m o &&\n-\ttest_tick && git commit --allow-empty -m B && git tag CCB &&\n+\ttest_commit CC2 &&\n+\ttest_tick &&\n+\tgit merge -s ours CC1 &&\n+\ttest_commit CC-o &&\n+\ttest_commit CCB &&\n \tgit reset --hard CC1 &&\n-\ttest_tick && git merge -s ours CC2 &&\n-\ttest_tick && git commit --allow-empty -m A && git tag CCA\n-'\n+\tgit merge -s ours CC2 &&\n+\ttest_commit CCA &&\n \n-test_expect_success 'merge-base B A^^ A^^2' '\n-\tMB0=$(git merge-base --all CCB CCA^^ CCA^^2 | sort) &&\n-\tMB1=$(git rev-parse CC1 CC2 | sort) &&\n-\ttest \"$MB0\" = \"$MB1\"\n+\tgit rev-parse CC1 CC2 >expected &&\n+\tgit merge-base --all CCB CCA^^ CCA^^2 >actual &&\n+\n+\tsort expected >expected.sorted &&\n+\tsort actual >actual.sorted &&\n+\ttest_cmp expected.sorted actual.sorted\n '\n \n test_done\n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"148238","messageId":"20100817065740.GG22057@burratino","threadId":"24765","inReplyTo":"20100817065147.GA18293@burratino","subject":"[PATCH 07/24] t6200 (fmt-merge-msg): style nitpicks","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T06:57:40Z","receivedAt":"2010-08-17T06:57:40Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Guard setup with test_expect_success.  Use test_might_fail\ninstead of ignoring the exit code from git config --unset.\nPoint out setup commands that are shared by multiple tests,\nto make it easy to write GIT_SKIP_TESTS specifications that\nwork.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n t/t6200-fmt-merge-msg.sh |  278 ++++++++++++++++++++--------------------------\n 1 files changed, 119 insertions(+), 159 deletions(-)\n\ndiff --git a/t/t6200-fmt-merge-msg.sh b/t/t6200-fmt-merge-msg.sh\nindex 42f8ece..5553dff 100755\n--- a/t/t6200-fmt-merge-msg.sh\n+++ b/t/t6200-fmt-merge-msg.sh\n@@ -70,14 +70,13 @@ test_expect_success setup '\n \t\ti=$(($i+1))\n \tdone &&\n \n-\tgit show-branch\n+\tgit show-branch &&\n+\n+\tapos=\"'\\''\"\n '\n \n-cat >expected <<\\EOF\n-Merge branch 'left'\n-EOF\n-\n-test_expect_success 'merge-msg test #1' '\n+test_expect_success 'message for merging local branch' '\n+\techo \"Merge branch ${apos}left${apos}\" >expected &&\n \n \tgit checkout master &&\n \tgit fetch . left &&\n@@ -86,11 +85,8 @@ test_expect_success 'merge-msg test #1' '\n \ttest_cmp expected actual\n '\n \n-cat >expected <<EOF\n-Merge branch 'left' of $(pwd)\n-EOF\n-\n-test_expect_success 'merge-msg test #2' '\n+test_expect_success 'message for merging external branch' '\n+\techo \"Merge branch ${apos}left${apos} of $(pwd)\" >expected &&\n \n \tgit checkout master &&\n \tgit fetch \"$(pwd)\" left &&\n@@ -99,139 +95,108 @@ test_expect_success 'merge-msg test #2' '\n \ttest_cmp expected actual\n '\n \n-cat >expected <<\\EOF\n-Merge branch 'left'\n+test_expect_success '[merge] summary/log configuration' '\n+\tcat >expected <<-EOF &&\n+\tMerge branch ${apos}left${apos}\n+\n+\t* left:\n+\t  Left #5\n+\t  Left #4\n+\t  Left #3\n+\t  Common #2\n+\t  Common #1\n+\tEOF\n \n-* left:\n-  Left #5\n-  Left #4\n-  Left #3\n-  Common #2\n-  Common #1\n-EOF\n-\n-test_expect_success 'merge-msg test #3-1' '\n-\n-\tgit config --unset-all merge.log\n-\tgit config --unset-all merge.summary\n \tgit config merge.log true &&\n+\ttest_might_fail git config --unset-all merge.summary &&\n \n \tgit checkout master &&\n \ttest_tick &&\n \tgit fetch . left &&\n \n-\tgit fmt-merge-msg <.git/FETCH_HEAD >actual &&\n-\ttest_cmp expected actual\n-'\n+\tgit fmt-merge-msg <.git/FETCH_HEAD >actual1 &&\n \n-test_expect_success 'merge-msg test #3-2' '\n-\n-\tgit config --unset-all merge.log\n-\tgit config --unset-all merge.summary\n+\ttest_might_fail git config --unset-all merge.log &&\n \tgit config merge.summary true &&\n \n \tgit checkout master &&\n \ttest_tick &&\n \tgit fetch . left &&\n \n-\tgit fmt-merge-msg <.git/FETCH_HEAD >actual &&\n-\ttest_cmp expected actual\n-'\n+\tgit fmt-merge-msg <.git/FETCH_HEAD >actual2 &&\n \n-cat >expected <<\\EOF\n-Merge branches 'left' and 'right'\n-\n-* left:\n-  Left #5\n-  Left #4\n-  Left #3\n-  Common #2\n-  Common #1\n-\n-* right:\n-  Right #5\n-  Right #4\n-  Right #3\n-  Common #2\n-  Common #1\n-EOF\n+\ttest_cmp expected actual1 &&\n+\ttest_cmp expected actual2\n+'\n \n-test_expect_success 'merge-msg test #4-1' '\n+test_expect_success 'setup: expected shortlog for two branches' '\n+\tcat >expected <<-EOF\n+\tMerge branches ${apos}left${apos} and ${apos}right${apos}\n+\n+\t* left:\n+\t  Left #5\n+\t  Left #4\n+\t  Left #3\n+\t  Common #2\n+\t  Common #1\n+\n+\t* right:\n+\t  Right #5\n+\t  Right #4\n+\t  Right #3\n+\t  Common #2\n+\t  Common #1\n+\tEOF\n+'\n \n-\tgit config --unset-all merge.log\n-\tgit config --unset-all merge.summary\n+test_expect_success 'shortlog for two branches' '\n \tgit config merge.log true &&\n-\n+\ttest_might_fail git config --unset-all merge.summary &&\n \tgit checkout master &&\n \ttest_tick &&\n \tgit fetch . left right &&\n+\tgit fmt-merge-msg <.git/FETCH_HEAD >actual1 &&\n \n-\tgit fmt-merge-msg <.git/FETCH_HEAD >actual &&\n-\ttest_cmp expected actual\n-'\n-\n-test_expect_success 'merge-msg test #4-2' '\n-\n-\tgit config --unset-all merge.log\n-\tgit config --unset-all merge.summary\n+\ttest_might_fail git config --unset-all merge.log &&\n \tgit config merge.summary true &&\n-\n \tgit checkout master &&\n \ttest_tick &&\n \tgit fetch . left right &&\n+\tgit fmt-merge-msg <.git/FETCH_HEAD >actual2 &&\n \n-\tgit fmt-merge-msg <.git/FETCH_HEAD >actual &&\n-\ttest_cmp expected actual\n-'\n-\n-test_expect_success 'merge-msg test #5-1' '\n-\n-\tgit config --unset-all merge.log\n-\tgit config --unset-all merge.summary\n \tgit config merge.log yes &&\n-\n+\ttest_might_fail git config --unset-all merge.summary &&\n \tgit checkout master &&\n \ttest_tick &&\n \tgit fetch . left right &&\n+\tgit fmt-merge-msg <.git/FETCH_HEAD >actual3 &&\n \n-\tgit fmt-merge-msg <.git/FETCH_HEAD >actual &&\n-\ttest_cmp expected actual\n-'\n-\n-test_expect_success 'merge-msg test #5-2' '\n-\n-\tgit config --unset-all merge.log\n-\tgit config --unset-all merge.summary\n+\ttest_might_fail git config --unset-all merge.log &&\n \tgit config merge.summary yes &&\n-\n \tgit checkout master &&\n \ttest_tick &&\n \tgit fetch . left right &&\n+\tgit fmt-merge-msg <.git/FETCH_HEAD >actual4 &&\n \n-\tgit fmt-merge-msg <.git/FETCH_HEAD >actual &&\n-\ttest_cmp expected actual\n+\ttest_cmp expected actual1 &&\n+\ttest_cmp expected actual2 &&\n+\ttest_cmp expected actual3 &&\n+\ttest_cmp expected actual4\n '\n \n test_expect_success 'merge-msg -F' '\n-\n-\tgit config --unset-all merge.log\n-\tgit config --unset-all merge.summary\n+\ttest_might_fail git config --unset-all merge.log &&\n \tgit config merge.summary yes &&\n-\n \tgit checkout master &&\n \ttest_tick &&\n \tgit fetch . left right &&\n-\n \tgit fmt-merge-msg -F .git/FETCH_HEAD >actual &&\n \ttest_cmp expected actual\n '\n \n test_expect_success 'merge-msg -F in subdirectory' '\n-\n-\tgit config --unset-all merge.log\n-\tgit config --unset-all merge.summary\n+\ttest_might_fail git config --unset-all merge.log &&\n \tgit config merge.summary yes &&\n-\n \tgit checkout master &&\n \ttest_tick &&\n \tgit fetch . left right &&\n@@ -245,11 +210,11 @@ test_expect_success 'merge-msg -F in subdirectory' '\n '\n \n test_expect_success 'merge-msg with nothing to merge' '\n-\n-\tgit config --unset-all merge.log\n-\tgit config --unset-all merge.summary\n+\ttest_might_fail git config --unset-all merge.log &&\n \tgit config merge.summary yes &&\n \n+\t>empty &&\n+\n \t(\n \t\tcd remote &&\n \t\tgit checkout -b unrelated &&\n@@ -258,22 +223,20 @@ test_expect_success 'merge-msg with nothing to merge' '\n \t\tgit fmt-merge-msg <.git/FETCH_HEAD >../actual\n \t) &&\n \n-\ttest_cmp /dev/null actual\n+\ttest_cmp empty actual\n '\n \n-cat >expected <<\\EOF\n-Merge tag 'tag-r3'\n-\n-* tag 'tag-r3':\n-  Right #3\n-  Common #2\n-  Common #1\n-EOF\n-\n test_expect_success 'merge-msg tag' '\n+\tcat >expected <<-EOF &&\n+\tMerge tag ${apos}tag-r3${apos}\n \n-\tgit config --unset-all merge.log\n-\tgit config --unset-all merge.summary\n+\t* tag ${apos}tag-r3${apos}:\n+\t  Right #3\n+\t  Common #2\n+\t  Common #1\n+\tEOF\n+\n+\ttest_might_fail git config --unset-all merge.log &&\n \tgit config merge.summary yes &&\n \n \tgit checkout master &&\n@@ -284,26 +247,24 @@ test_expect_success 'merge-msg tag' '\n \ttest_cmp expected actual\n '\n \n-cat >expected <<\\EOF\n-Merge tags 'tag-r3' and 'tag-l5'\n-\n-* tag 'tag-r3':\n-  Right #3\n-  Common #2\n-  Common #1\n-\n-* tag 'tag-l5':\n-  Left #5\n-  Left #4\n-  Left #3\n-  Common #2\n-  Common #1\n-EOF\n-\n test_expect_success 'merge-msg two tags' '\n+\tcat >expected <<-EOF &&\n+\tMerge tags ${apos}tag-r3${apos} and ${apos}tag-l5${apos}\n \n-\tgit config --unset-all merge.log\n-\tgit config --unset-all merge.summary\n+\t* tag ${apos}tag-r3${apos}:\n+\t  Right #3\n+\t  Common #2\n+\t  Common #1\n+\n+\t* tag ${apos}tag-l5${apos}:\n+\t  Left #5\n+\t  Left #4\n+\t  Left #3\n+\t  Common #2\n+\t  Common #1\n+\tEOF\n+\n+\ttest_might_fail git config --unset-all merge.log &&\n \tgit config merge.summary yes &&\n \n \tgit checkout master &&\n@@ -314,26 +275,24 @@ test_expect_success 'merge-msg two tags' '\n \ttest_cmp expected actual\n '\n \n-cat >expected <<\\EOF\n-Merge branch 'left', tag 'tag-r3'\n-\n-* tag 'tag-r3':\n-  Right #3\n-  Common #2\n-  Common #1\n-\n-* left:\n-  Left #5\n-  Left #4\n-  Left #3\n-  Common #2\n-  Common #1\n-EOF\n-\n test_expect_success 'merge-msg tag and branch' '\n+\tcat >expected <<-EOF &&\n+\tMerge branch ${apos}left${apos}, tag ${apos}tag-r3${apos}\n \n-\tgit config --unset-all merge.log\n-\tgit config --unset-all merge.summary\n+\t* tag ${apos}tag-r3${apos}:\n+\t  Right #3\n+\t  Common #2\n+\t  Common #1\n+\n+\t* left:\n+\t  Left #5\n+\t  Left #4\n+\t  Left #3\n+\t  Common #2\n+\t  Common #1\n+\tEOF\n+\n+\ttest_might_fail git config --unset-all merge.log &&\n \tgit config merge.summary yes &&\n \n \tgit checkout master &&\n@@ -344,26 +303,27 @@ test_expect_success 'merge-msg tag and branch' '\n \ttest_cmp expected actual\n '\n \n-cat >expected <<\\EOF\n-Merge branch 'long'\n-\n-* long: (35 commits)\n-EOF\n-\n test_expect_success 'merge-msg lots of commits' '\n+\t{\n+\t\tcat <<-EOF &&\n+\t\tMerge branch ${apos}long${apos}\n+\n+\t\t* long: (35 commits)\n+\t\tEOF\n+\n+\t\ti=29 &&\n+\t\twhile test $i -gt 9\n+\t\tdo\n+\t\t\techo \"  $i\" &&\n+\t\t\ti=$(($i-1))\n+\t\tdone &&\n+\t\techo \"  ...\"\n+\t} >expected &&\n \n \tgit checkout master &&\n \ttest_tick &&\n \tgit fetch . long &&\n \n-\ti=29 &&\n-\twhile test $i -gt 9\n-\tdo\n-\t\techo \"  $i\" &&\n-\t\ti=$(($i-1))\n-\tdone >>expected &&\n-\techo \"  ...\" >>expected\n-\n \tgit fmt-merge-msg <.git/FETCH_HEAD >actual &&\n \ttest_cmp expected actual\n '\n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"148239","messageId":"20100817065955.GH22057@burratino","threadId":"24765","inReplyTo":"20100817065147.GA18293@burratino","subject":"[PATCH 08/24] Documentation: add a SEE ALSO section for merge-base","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T06:59:55Z","receivedAt":"2010-08-17T06:59:55Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"For example, a person reading the merge-base man page might wonder\nabout the fastest way to check if one commit is an ancestor of\nanother (which would require rev-list).\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n Documentation/git-merge-base.txt |    6 ++++++\n 1 files changed, 6 insertions(+), 0 deletions(-)\n\ndiff --git a/Documentation/git-merge-base.txt b/Documentation/git-merge-base.txt\nindex ce5b369..09b34b0 100644\n--- a/Documentation/git-merge-base.txt\n+++ b/Documentation/git-merge-base.txt\n@@ -96,6 +96,12 @@ Documentation\n --------------\n Documentation by David Greaves, Junio C Hamano and the git-list <git@vger.kernel.org>.\n \n+See also\n+--------\n+linkgit:git-rev-list[1],\n+linkgit:git-show-branch[1],\n+linkgit:git-merge[1]\n+\n GIT\n ---\n Part of the linkgit:git[1] suite\n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"148240","messageId":"20100817070115.GI22057@burratino","threadId":"24765","inReplyTo":"20100817065147.GA18293@burratino","subject":"[PATCH 09/24] merge-base --octopus to mimic show-branch --merge-base","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T07:01:15Z","receivedAt":"2010-08-17T07:01:15Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"While show-branch --merge-base does not support more than MAX_REVS\nrevs, git supports more with a different algorithm\n(v1.6.0-rc0~51^2~13, Introduce get_octopus_merge_bases() in commit.c,\n2008-06-27).  Expose that functionality.\n\nThis should help scripts to catch up with builtin merge in supporting\ndodecapus.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n Documentation/git-merge-base.txt |   19 ++++++++++++-------\n builtin/merge-base.c             |   35 ++++++++++++++++++++++++++++++++---\n t/t6010-merge-base.sh            |    2 ++\n 3 files changed, 46 insertions(+), 10 deletions(-)\n\ndiff --git a/Documentation/git-merge-base.txt b/Documentation/git-merge-base.txt\nindex 09b34b0..125207e 100644\n--- a/Documentation/git-merge-base.txt\n+++ b/Documentation/git-merge-base.txt\n@@ -8,7 +8,7 @@ git-merge-base - Find as good common ancestors as possible for a merge\n \n SYNOPSIS\n --------\n-'git merge-base' [-a|--all] <commit> <commit>...\n+'git merge-base' [-a|--all] [--octopus] <commit> <commit>...\n \n DESCRIPTION\n -----------\n@@ -20,12 +20,12 @@ that does not have any better common ancestor is a 'best common\n ancestor', i.e. a 'merge base'.  Note that there can be more than one\n merge base for a pair of commits.\n \n-Among the two commits to compute the merge base from, one is specified by\n-the first commit argument on the command line; the other commit is a\n-(possibly hypothetical) commit that is a merge across all the remaining\n-commits on the command line.  As the most common special case, specifying only\n-two commits on the command line means computing the merge base between\n-the given two commits.\n+Unless `--octopus` is given, among the two commits to compute the merge\n+base from, one is specified by the first commit argument on the command\n+line; the other commit is a (possibly hypothetical) commit that is a merge\n+across all the remaining commits on the command line.  As the most common\n+special case, specifying only two commits on the command line means\n+computing the merge base between the given two commits.\n \n As a consequence, the 'merge base' is not necessarily contained in each of the\n commit arguments if more than two commits are specified. This is different\n@@ -37,6 +37,11 @@ OPTIONS\n --all::\n \tOutput all merge bases for the commits, instead of just one.\n \n+--octopus::\n+\tCompute the best common ancestors of all supplied commits,\n+\tin preparation for an n-way merge.  This mimics the behavior\n+\tof 'git show-branch --merge-base'.\n+\n DISCUSSION\n ----------\n \ndiff --git a/builtin/merge-base.c b/builtin/merge-base.c\nindex 54e7ec2..c301286 100644\n--- a/builtin/merge-base.c\n+++ b/builtin/merge-base.c\n@@ -23,7 +23,7 @@ static int show_merge_base(struct commit **rev, int rev_nr, int show_all)\n }\n \n static const char * const merge_base_usage[] = {\n-\t\"git merge-base [-a|--all] <commit> <commit>...\",\n+\t\"git merge-base [-a|--all] [--octopus] <commit> <commit>...\",\n \tNULL\n };\n \n@@ -41,21 +41,50 @@ static struct commit *get_commit_reference(const char *arg)\n \treturn r;\n }\n \n+static int show_octopus_merge_bases(int count, const char **args, int show_all)\n+{\n+\tstruct commit_list *revs = NULL;\n+\tstruct commit_list *result;\n+\tint i;\n+\n+\tfor (i = count - 1; i >= 0; i++)\n+\t\tcommit_list_insert(get_commit_reference(args[i]), &revs);\n+\tresult = get_octopus_merge_bases(revs);\n+\n+\tif (!result)\n+\t\treturn 1;\n+\n+\twhile (result) {\n+\t\tprintf(\"%s\\n\", sha1_to_hex(result->item->object.sha1));\n+\t\tif (!show_all)\n+\t\t\treturn 0;\n+\t\tresult = result->next;\n+\t}\n+\n+\treturn 0;\n+}\n+\n int cmd_merge_base(int argc, const char **argv, const char *prefix)\n {\n \tstruct commit **rev;\n \tint rev_nr = 0;\n \tint show_all = 0;\n+\tint octopus = 0;\n \n \tstruct option options[] = {\n-\t\tOPT_BOOLEAN('a', \"all\", &show_all, \"outputs all common ancestors\"),\n+\t\tOPT_BOOLEAN('a', \"all\", &show_all, \"output all common ancestors\"),\n+\t\tOPT_BOOLEAN(0, \"octopus\", &octopus, \"find ancestors for a single n-way merge\"),\n \t\tOPT_END()\n \t};\n \n \tgit_config(git_default_config, NULL);\n \targc = parse_options(argc, argv, prefix, options, merge_base_usage, 0);\n-\tif (argc < 2)\n+\tif (!octopus && argc < 2)\n \t\tusage_with_options(merge_base_usage, options);\n+\n+\tif (octopus)\n+\t\treturn show_octopus_merge_bases(argc, argv, show_all);\n+\n \trev = xmalloc(argc * sizeof(*rev));\n \twhile (argc-- > 0)\n \t\trev[rev_nr++] = get_commit_reference(*argv++);\ndiff --git a/t/t6010-merge-base.sh b/t/t6010-merge-base.sh\nindex 4466e45..001431b 100755\n--- a/t/t6010-merge-base.sh\n+++ b/t/t6010-merge-base.sh\n@@ -164,9 +164,11 @@ test_expect_success 'merge-base A B C' '\n \tgit rev-parse --verify MMR >expected.sb &&\n \n \tgit merge-base --all MMA MMB MMC >actual &&\n+\tgit merge-base --all --octopus MMA MMB MMC >actual.common &&\n \tgit show-branch --merge-base MMA MMB MMC >actual.sb &&\n \n \ttest_cmp expected actual &&\n+\ttest_cmp expected.sb actual.common &&\n \ttest_cmp expected.sb actual.sb\n '\n \n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"148241","messageId":"20100817070154.GJ22057@burratino","threadId":"24765","inReplyTo":"20100817065147.GA18293@burratino","subject":"[PATCH 10/24] merge-base --independent to print reduced parent list in a merge","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T07:01:54Z","receivedAt":"2010-08-17T07:01:54Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"While show-branch --independent does not support more than MAX_REVS\nrevs, git internally supports more with a different algorithm.\nExpose that functionality as \"git merge-base --independent\".\n\nThis should help scripts to catch up with builtin merge in supporting\ndodecapus.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n Documentation/git-merge-base.txt |    9 ++++++++\n builtin/merge-base.c             |   21 ++++++++++++++-----\n t/t6010-merge-base.sh            |   39 +++++++++++++++++++++++++++++++++++++-\n 3 files changed, 62 insertions(+), 7 deletions(-)\n\ndiff --git a/Documentation/git-merge-base.txt b/Documentation/git-merge-base.txt\nindex 125207e..eedef1b 100644\n--- a/Documentation/git-merge-base.txt\n+++ b/Documentation/git-merge-base.txt\n@@ -8,7 +8,9 @@ git-merge-base - Find as good common ancestors as possible for a merge\n \n SYNOPSIS\n --------\n+[verse]\n 'git merge-base' [-a|--all] [--octopus] <commit> <commit>...\n+'git merge-base' --independent <commit>...\n \n DESCRIPTION\n -----------\n@@ -42,6 +44,13 @@ OPTIONS\n \tin preparation for an n-way merge.  This mimics the behavior\n \tof 'git show-branch --merge-base'.\n \n+--independent::\n+\tInstead of printing merge bases, print a minimal subset of\n+\tthe supplied commits with the same ancestors.  In other words,\n+\tamong the commits given, list those which cannot be reached\n+\tfrom any other.  This mimics the behavior of 'git show-branch\n+\t--independent'.\n+\n DISCUSSION\n ----------\n \ndiff --git a/builtin/merge-base.c b/builtin/merge-base.c\nindex c301286..96dd160 100644\n--- a/builtin/merge-base.c\n+++ b/builtin/merge-base.c\n@@ -24,6 +24,7 @@ static int show_merge_base(struct commit **rev, int rev_nr, int show_all)\n \n static const char * const merge_base_usage[] = {\n \t\"git merge-base [-a|--all] [--octopus] <commit> <commit>...\",\n+\t\"git merge-base --independent <commit>...\",\n \tNULL\n };\n \n@@ -41,15 +42,19 @@ static struct commit *get_commit_reference(const char *arg)\n \treturn r;\n }\n \n-static int show_octopus_merge_bases(int count, const char **args, int show_all)\n+static int handle_octopus(int count, const char **args, int reduce, int show_all)\n {\n \tstruct commit_list *revs = NULL;\n \tstruct commit_list *result;\n \tint i;\n \n-\tfor (i = count - 1; i >= 0; i++)\n+\tif (reduce)\n+\t\tshow_all = 1;\n+\n+\tfor (i = count - 1; i >= 0; i--)\n \t\tcommit_list_insert(get_commit_reference(args[i]), &revs);\n-\tresult = get_octopus_merge_bases(revs);\n+\n+\tresult = reduce ? reduce_heads(revs) : get_octopus_merge_bases(revs);\n \n \tif (!result)\n \t\treturn 1;\n@@ -70,20 +75,24 @@ int cmd_merge_base(int argc, const char **argv, const char *prefix)\n \tint rev_nr = 0;\n \tint show_all = 0;\n \tint octopus = 0;\n+\tint reduce = 0;\n \n \tstruct option options[] = {\n \t\tOPT_BOOLEAN('a', \"all\", &show_all, \"output all common ancestors\"),\n \t\tOPT_BOOLEAN(0, \"octopus\", &octopus, \"find ancestors for a single n-way merge\"),\n+\t\tOPT_BOOLEAN(0, \"independent\", &reduce, \"list revs not reachable from others\"),\n \t\tOPT_END()\n \t};\n \n \tgit_config(git_default_config, NULL);\n \targc = parse_options(argc, argv, prefix, options, merge_base_usage, 0);\n-\tif (!octopus && argc < 2)\n+\tif (!octopus && !reduce && argc < 2)\n \t\tusage_with_options(merge_base_usage, options);\n+\tif (reduce && (show_all || octopus))\n+\t\tdie(\"--independent cannot be used with other options\");\n \n-\tif (octopus)\n-\t\treturn show_octopus_merge_bases(argc, argv, show_all);\n+\tif (octopus || reduce)\n+\t\treturn handle_octopus(argc, argv, reduce, show_all);\n \n \trev = xmalloc(argc * sizeof(*rev));\n \twhile (argc-- > 0)\ndiff --git a/t/t6010-merge-base.sh b/t/t6010-merge-base.sh\nindex 001431b..62197a3 100755\n--- a/t/t6010-merge-base.sh\n+++ b/t/t6010-merge-base.sh\n@@ -3,7 +3,7 @@\n # Copyright (c) 2005 Junio C Hamano\n #\n \n-test_description='Merge base computation.\n+test_description='Merge base and parent list computation.\n '\n \n . ./test-lib.sh\n@@ -75,6 +75,26 @@ test_expect_success 'merge-base G H' '\n \ttest_cmp expected actual.sb\n '\n \n+test_expect_success 'merge-base/show-branch --independent' '\n+\tgit name-rev \"$H\" >expected1 &&\n+\tgit name-rev \"$H\" \"$G\" >expected2 &&\n+\n+\tparents=$(git merge-base --independent H) &&\n+\tgit name-rev $parents >actual1.mb &&\n+\tparents=$(git merge-base --independent A H G) &&\n+\tgit name-rev $parents >actual2.mb &&\n+\n+\tparents=$(git show-branch --independent H) &&\n+\tgit name-rev $parents >actual1.sb &&\n+\tparents=$(git show-branch --independent A H G) &&\n+\tgit name-rev $parents >actual2.sb &&\n+\n+\ttest_cmp expected1 actual1.mb &&\n+\ttest_cmp expected2 actual2.mb &&\n+\ttest_cmp expected1 actual1.sb &&\n+\ttest_cmp expected2 actual2.sb\n+'\n+\n test_expect_success 'unsynchronized clocks' '\n \t# This test is to demonstrate that relying on timestamps in a distributed\n \t# SCM to provide a _consistent_ partial ordering of commits leads to\n@@ -125,6 +145,23 @@ test_expect_success 'unsynchronized clocks' '\n \ttest_cmp expected actual.all\n '\n \n+test_expect_success '--independent with unsynchronized clocks' '\n+\tIB=$(doit 0 IB) &&\n+\tI1=$(doit -10 I1 $IB) &&\n+\tI2=$(doit  -9 I2 $I1) &&\n+\tI3=$(doit  -8 I3 $I2) &&\n+\tI4=$(doit  -7 I4 $I3) &&\n+\tI5=$(doit  -6 I5 $I4) &&\n+\tI6=$(doit  -5 I6 $I5) &&\n+\tI7=$(doit  -4 I7 $I6) &&\n+\tI8=$(doit  -3 I8 $I7) &&\n+\tIH=$(doit  -2 IH $I8) &&\n+\n+\techo $IH >expected &&\n+\tgit merge-base --independent IB IH >actual &&\n+\ttest_cmp expected actual\n+'\n+\n test_expect_success 'merge-base for octopus-step (setup)' '\n \t# Another set to demonstrate base between one commit and a merge\n \t# in the documentation.\n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"148242","messageId":"20100817070245.GK22057@burratino","threadId":"24765","inReplyTo":"20100817065147.GA18293@burratino","subject":"[PATCH 11/24] fmt-merge-msg -m to override subject line","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T07:02:45Z","receivedAt":"2010-08-17T07:02:45Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"The fmt-merge-msg backend has supported a custom subject line and\nmessage beginning since v1.7.1.1~23^2 (merge: --log appends shortlog\nto message if specified, 2010-05-11).  Expose the functionality for\nscripted callers.\n\nCc: Tay Ray Chuan <rctay89@gmail.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n Documentation/git-fmt-merge-msg.txt |    9 +++++++--\n builtin/fmt-merge-msg.c             |   18 ++++++++++++++++--\n t/t6200-fmt-merge-msg.sh            |   32 ++++++++++++++++++++++++++++++++\n 3 files changed, 55 insertions(+), 4 deletions(-)\n\ndiff --git a/Documentation/git-fmt-merge-msg.txt b/Documentation/git-fmt-merge-msg.txt\nindex a585dbe..96a06ee 100644\n--- a/Documentation/git-fmt-merge-msg.txt\n+++ b/Documentation/git-fmt-merge-msg.txt\n@@ -9,8 +9,8 @@ git-fmt-merge-msg - Produce a merge commit message\n SYNOPSIS\n --------\n [verse]\n-'git fmt-merge-msg' [--log | --no-log] <$GIT_DIR/FETCH_HEAD\n-'git fmt-merge-msg' [--log | --no-log] -F <file>\n+'git fmt-merge-msg' [-m <subject>] [--log | --no-log] <$GIT_DIR/FETCH_HEAD\n+'git fmt-merge-msg' [-m <subject>] [--log ]| --no-log] -F <file>\n \n DESCRIPTION\n -----------\n@@ -38,6 +38,11 @@ OPTIONS\n \tSynonyms to --log and --no-log; these are deprecated and will be\n \tremoved in the future.\n \n+-m <subject>::\n+--message <subject>::\n+\tUse <subject> instead of the branch names for the first line\n+\tof the log message.  For use with `--log`.\n+\n -F <file>::\n --file <file>::\n \tTake the list of merged objects from <file> instead of\ndiff --git a/builtin/fmt-merge-msg.c b/builtin/fmt-merge-msg.c\nindex 4420425..2782086 100644\n--- a/builtin/fmt-merge-msg.c\n+++ b/builtin/fmt-merge-msg.c\n@@ -7,7 +7,7 @@\n #include \"string-list.h\"\n \n static const char * const fmt_merge_msg_usage[] = {\n-\t\"git fmt-merge-msg [--log|--no-log] [--file <file>]\",\n+\t\"git fmt-merge-msg [-m <online>] [--log|--no-log] [--file <file>]\",\n \tNULL\n };\n \n@@ -319,11 +319,14 @@ int fmt_merge_msg_shortlog(struct strbuf *in, struct strbuf *out) {\n int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)\n {\n \tconst char *inpath = NULL;\n+\tconst char *oneline_msg = NULL;\n \tstruct option options[] = {\n \t\tOPT_BOOLEAN(0, \"log\",     &merge_summary, \"populate log with the shortlog\"),\n \t\t{ OPTION_BOOLEAN, 0, \"summary\", &merge_summary, NULL,\n \t\t  \"alias for --log (deprecated)\",\n \t\t  PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },\n+\t\tOPT_STRING('m', \"message\", &oneline_msg, \"oneline\",\n+\t\t\t\"use <oneline> as subject line\"),\n \t\tOPT_FILENAME('F', \"file\", &inpath, \"file to read from\"),\n \t\tOPT_END()\n \t};\n@@ -337,6 +340,12 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)\n \t\t\t     0);\n \tif (argc > 0)\n \t\tusage_with_options(fmt_merge_msg_usage, options);\n+\tif (oneline_msg && !merge_summary) {\n+\t\tchar nl = '\\n';\n+\t\twrite_in_full(STDOUT_FILENO, oneline_msg, strlen(oneline_msg));\n+\t\twrite_in_full(STDOUT_FILENO, &nl, 1);\n+\t\treturn 0;\n+\t}\n \n \tif (inpath && strcmp(inpath, \"-\")) {\n \t\tin = fopen(inpath, \"r\");\n@@ -346,7 +355,12 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)\n \n \tif (strbuf_read(&input, fileno(in), 0) < 0)\n \t\tdie_errno(\"could not read input file\");\n-\tret = fmt_merge_msg(merge_summary, &input, &output);\n+\tif (oneline_msg) {\n+\t\tstrbuf_addstr(&output, oneline_msg);\n+\t\tret = fmt_merge_msg_shortlog(&input, &output);\n+\t} else {\n+\t\tret = fmt_merge_msg(merge_summary, &input, &output);\n+\t}\n \tif (ret)\n \t\treturn ret;\n \twrite_in_full(STDOUT_FILENO, output.buf, output.len);\ndiff --git a/t/t6200-fmt-merge-msg.sh b/t/t6200-fmt-merge-msg.sh\nindex 5553dff..71f6cad 100755\n--- a/t/t6200-fmt-merge-msg.sh\n+++ b/t/t6200-fmt-merge-msg.sh\n@@ -129,6 +129,38 @@ test_expect_success '[merge] summary/log configuration' '\n \ttest_cmp expected actual2\n '\n \n+test_expect_success 'fmt-merge-msg -m' '\n+\techo \"Sync with left\" >expected &&\n+\tcat >expected.log <<-EOF &&\n+\tSync with left\n+\n+\t* ${apos}left${apos} of $(pwd):\n+\t  Left #5\n+\t  Left #4\n+\t  Left #3\n+\t  Common #2\n+\t  Common #1\n+\tEOF\n+\n+\ttest_might_fail git config --unset merge.log &&\n+\ttest_might_fail git config --unset merge.summary &&\n+\tgit checkout master &&\n+\tgit fetch \"$(pwd)\" left &&\n+\tgit fmt-merge-msg -m \"Sync with left\" <.git/FETCH_HEAD >actual &&\n+\tgit fmt-merge-msg --log -m \"Sync with left\" \\\n+\t\t\t\t\t<.git/FETCH_HEAD >actual.log &&\n+\tgit config merge.log true &&\n+\tgit fmt-merge-msg -m \"Sync with left\" \\\n+\t\t\t\t\t<.git/FETCH_HEAD >actual.log-config &&\n+\tgit fmt-merge-msg --no-log -m \"Sync with left\" \\\n+\t\t\t\t\t<.git/FETCH_HEAD >actual.nolog &&\n+\n+\ttest_cmp expected actual &&\n+\ttest_cmp expected.log actual.log &&\n+\ttest_cmp expected.log actual.log-config &&\n+\ttest_cmp expected actual.nolog\n+'\n+\n test_expect_success 'setup: expected shortlog for two branches' '\n \tcat >expected <<-EOF\n \tMerge branches ${apos}left${apos} and ${apos}right${apos}\n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"148243","messageId":"20100817070307.GL22057@burratino","threadId":"24765","inReplyTo":"20100817065147.GA18293@burratino","subject":"[PATCH 12/24] merge script: --squash, --ff from unborn branch are errors","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T07:03:07Z","receivedAt":"2010-08-17T07:03:07Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Port v1.6.1-rc1~319 (provide more errors for the \"merge into empty\nhead\" case, 2008-08-21) to the example merge script.\n\nNoticed by comparison with builtin merge.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n contrib/examples/git-merge.sh |    4 ++++\n 1 files changed, 4 insertions(+), 0 deletions(-)\n\ndiff --git a/contrib/examples/git-merge.sh b/contrib/examples/git-merge.sh\nindex 8f617fc..72853cf 100755\n--- a/contrib/examples/git-merge.sh\n+++ b/contrib/examples/git-merge.sh\n@@ -245,6 +245,10 @@ then\n \t\texit 1\n \tfi\n \n+\ttest \"$squash\" != t ||\n+\t\tdie \"Squash commit into empty head not supported yet\"\n+\ttest \"$allow_fast_forward\" = t ||\n+\t\tdie \"Non-fast-forward into an empty head does not make sense\"\n \trh=$(git rev-parse --verify \"$1^0\") ||\n \t\tdie \"$1 - not something we can merge\"\n \n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"148244","messageId":"20100817070336.GM22057@burratino","threadId":"24765","inReplyTo":"20100817065147.GA18293@burratino","subject":"[PATCH 13/24] merge script: tweak unmerged files message to match builtin","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T07:03:36Z","receivedAt":"2010-08-17T07:03:36Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Before:\n\n\tYou are in the middle of a conflicted merge.\n\nAfter:\n\n\tMerge is not possible because you have unmerged files.\n\nI prefer the old message, but the new one is more consistent with\nother commands and tests expect it.  In particular, without this\nchange the scripted merge does not pass t3030.\n\nBased on v1.7.0-rc0~66^2 (Be more user-friendly when refusing to do\nsomething because of conflict., 2010-01-12).\n\nCc: Matthieu Moy <Matthieu.Moy@imag.fr>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n contrib/examples/git-merge.sh |    2 +-\n 1 files changed, 1 insertions(+), 1 deletions(-)\n\ndiff --git a/contrib/examples/git-merge.sh b/contrib/examples/git-merge.sh\nindex 72853cf..99fe1f2 100755\n--- a/contrib/examples/git-merge.sh\n+++ b/contrib/examples/git-merge.sh\n@@ -25,7 +25,7 @@ require_work_tree\n cd_to_toplevel\n \n test -z \"$(git ls-files -u)\" ||\n-\tdie \"You are in the middle of a conflicted merge.\"\n+\tdie \"Merge is not possible because you have unmerged files.\"\n \n LF='\n '\n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"148245","messageId":"20100817070358.GN22057@burratino","threadId":"24765","inReplyTo":"20100817065147.GA18293@burratino","subject":"[PATCH 14/24] merge script: refuse to merge during merge","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T07:03:58Z","receivedAt":"2010-08-17T07:03:58Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Check MERGE_HEAD and bail out if it exists.  Based on v1.6.3.3~3^2\n(refuse to merge during a merge, 2009-06-01).  Without this change,\nthe scripted merge does not pass t3030.\n\nCc: Clemens Buchacher <drizzd@aon.at>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n contrib/examples/git-merge.sh |    3 +++\n 1 files changed, 3 insertions(+), 0 deletions(-)\n\ndiff --git a/contrib/examples/git-merge.sh b/contrib/examples/git-merge.sh\nindex 99fe1f2..50042df 100755\n--- a/contrib/examples/git-merge.sh\n+++ b/contrib/examples/git-merge.sh\n@@ -27,6 +27,9 @@ cd_to_toplevel\n test -z \"$(git ls-files -u)\" ||\n \tdie \"Merge is not possible because you have unmerged files.\"\n \n+! test -e \"$GIT_DIR/MERGE_HEAD\" ||\n+\tdie 'You have not concluded your merge (MERGE_HEAD exists).'\n+\n LF='\n '\n \n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"148246","messageId":"20100817070443.GO22057@burratino","threadId":"24765","inReplyTo":"20100817065147.GA18293@burratino","subject":"[PATCH 15/24] merge script: improve log message subject","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T07:04:43Z","receivedAt":"2010-08-17T07:04:43Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":" - point out remote-tracking branches as \"remote branch\n   'upstream/master'\";\n - avoid misleading log messages when a tag and branch\n   share a name.\n\nThis approximates the builtin merge command's behavior well\nenough to pass the relevant tests.\n\nBased roughly on v1.6.4.2~10^2 (merge: indicate remote tracking\nbranches in merge message, 2009-08-09) and v1.6.4.2~10^2~1 (merge: fix\nincorrect merge message for ambiguous tag/branch, 2009-08-09).\n\nCc: Jeff King <peff@peff.net>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n contrib/examples/git-merge.sh |   27 +++++++++++++++++++--------\n 1 files changed, 19 insertions(+), 8 deletions(-)\n\ndiff --git a/contrib/examples/git-merge.sh b/contrib/examples/git-merge.sh\nindex 50042df..d491566 100755\n--- a/contrib/examples/git-merge.sh\n+++ b/contrib/examples/git-merge.sh\n@@ -134,21 +134,32 @@ finish () {\n merge_name () {\n \tremote=\"$1\"\n \trh=$(git rev-parse --verify \"$remote^0\" 2>/dev/null) || return\n-\tbh=$(git show-ref -s --verify \"refs/heads/$remote\" 2>/dev/null)\n-\tif test \"$rh\" = \"$bh\"\n-\tthen\n-\t\techo \"$rh\t\tbranch '$remote' of .\"\n-\telif truname=$(expr \"$remote\" : '\\(.*\\)~[1-9][0-9]*$') &&\n+\tif truname=$(expr \"$remote\" : '\\(.*\\)~[0-9]*$') &&\n \t\tgit show-ref -q --verify \"refs/heads/$truname\" 2>/dev/null\n \tthen\n \t\techo \"$rh\t\tbranch '$truname' (early part) of .\"\n-\telif test \"$remote\" = \"FETCH_HEAD\" -a -r \"$GIT_DIR/FETCH_HEAD\"\n+\t\treturn\n+\tfi\n+\tif found_ref=$(git rev-parse --symbolic-full-name --verify \\\n+\t\t\t\t\t\t\t\"$remote\" 2>/dev/null)\n+\tthen\n+\t\tif test \"${found_ref#refs/heads/}\" != \"$found_ref\"\n+\t\tthen\n+\t\t\techo \"$rh\t\tbranch '$remote' of .\"\n+\t\t\treturn\n+\t\telif test \"${found_ref#refs/remotes/}\" != \"$found_ref\"\n+\t\tthen\n+\t\t\techo \"$rh\t\tremote branch '$remote' of .\"\n+\t\t\treturn\n+\t\tfi\n+\tfi\n+\tif test \"$remote\" = \"FETCH_HEAD\" -a -r \"$GIT_DIR/FETCH_HEAD\"\n \tthen\n \t\tsed -e 's/\tnot-for-merge\t/\t\t/' -e 1q \\\n \t\t\t\"$GIT_DIR/FETCH_HEAD\"\n-\telse\n-\t\techo \"$rh\t\tcommit '$remote'\"\n+\t\treturn\n \tfi\n+\techo \"$rh\t\tcommit '$remote'\"\n }\n \n parse_config () {\n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"148247","messageId":"20100817070510.GP22057@burratino","threadId":"24765","inReplyTo":"20100817065147.GA18293@burratino","subject":"[PATCH 16/24] merge script: merge -X<option>","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T07:05:10Z","receivedAt":"2010-08-17T07:05:10Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Without this support, the scripted merge cannot pass t6037.\n\nBased on v1.7.0-rc0~55^2~5 (git merge -X<option>, 2009-11-25).\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n contrib/examples/git-merge.sh |    8 +++++++-\n 1 files changed, 7 insertions(+), 1 deletions(-)\n\ndiff --git a/contrib/examples/git-merge.sh b/contrib/examples/git-merge.sh\nindex d491566..0d53735 100755\n--- a/contrib/examples/git-merge.sh\n+++ b/contrib/examples/git-merge.sh\n@@ -16,6 +16,7 @@ squash               create a single commit instead of doing a merge\n commit               perform a commit if the merge succeeds (default)\n ff                   allow fast-forward (default)\n s,strategy=          merge strategy to use\n+X=                   option for selected merge strategy\n m,message=           message to be used for the merge commit (if any)\n \"\n \n@@ -40,6 +41,7 @@ default_octopus_strategies='octopus'\n no_fast_forward_strategies='subtree ours'\n no_trivial_strategies='recursive recur subtree ours recursive-ours recursive-theirs'\n use_strategies=\n+xopt=\n \n allow_fast_forward=t\n allow_trivial_merge=t\n@@ -196,6 +198,10 @@ parse_config () {\n \t\t\t\tdie \"available strategies are: $all_strategies\" ;;\n \t\t\tesac\n \t\t\t;;\n+\t\t-X)\n+\t\t\tshift\n+\t\t\txopt=\"${xopt:+$xopt }$(git rev-parse --sq-quote \"--$1\")\"\n+\t\t\t;;\n \t\t-m|--message)\n \t\t\tshift\n \t\t\tmerge_msg=\"$1\"\n@@ -469,7 +475,7 @@ do\n     # Remember which strategy left the state in the working tree\n     wt_strategy=$strategy\n \n-    git-merge-$strategy $common -- \"$head_arg\" \"$@\"\n+    eval 'git-merge-$strategy '\"$xopt\"' $common -- \"$head_arg\" \"$@\"'\n     exit=$?\n     if test \"$no_commit\" = t && test \"$exit\" = 0\n     then\n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"148248","messageId":"20100817070532.GQ22057@burratino","threadId":"24765","inReplyTo":"20100817065147.GA18293@burratino","subject":"[PATCH 17/24] merge script: allow custom strategies","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T07:05:32Z","receivedAt":"2010-08-17T07:05:32Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"The idea comes from v1.6.1-rc1~294^2~7 (builtin-merge: allow using a\ncustom strategy, 2008-07-30).\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n contrib/examples/git-merge.sh |    8 ++++++--\n 1 files changed, 6 insertions(+), 2 deletions(-)\n\ndiff --git a/contrib/examples/git-merge.sh b/contrib/examples/git-merge.sh\nindex 0d53735..49d8265 100755\n--- a/contrib/examples/git-merge.sh\n+++ b/contrib/examples/git-merge.sh\n@@ -193,9 +193,13 @@ parse_config () {\n \t\t\tshift\n \t\t\tcase \" $all_strategies \" in\n \t\t\t*\" $1 \"*)\n-\t\t\t\tuse_strategies=\"$use_strategies$1 \" ;;\n+\t\t\t\tuse_strategies=\"$use_strategies$1 \"\n+\t\t\t\t;;\n \t\t\t*)\n-\t\t\t\tdie \"available strategies are: $all_strategies\" ;;\n+\t\t\t\ttype \"git-merge-$1\" >/dev/null 2>&1 ||\n+\t\t\t\t\tdie \"available strategies are: $all_strategies\"\n+\t\t\t\tuse_strategies=\"$use_strategies$1 \"\n+\t\t\t\t;;\n \t\t\tesac\n \t\t\t;;\n \t\t-X)\n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"148249","messageId":"20100817070606.GR22057@burratino","threadId":"24765","inReplyTo":"20100817065147.GA18293@burratino","subject":"[PATCH 18/24] merge script: forbid merge -s index","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T07:06:06Z","receivedAt":"2010-08-17T07:06:06Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Some git-merge-* commands are not merge strategies.  This is based on\nv1.6.1-rc1~294^2~7 (builtin-merge: allow using a custom strategy,\n2008-07-30) but it is less smart: we just use a hard-coded list of\nforbidden strategy names.  It is okay if this falls out of date, since\nthe code is just an example.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n contrib/examples/git-merge.sh |    5 +++++\n 1 files changed, 5 insertions(+), 0 deletions(-)\n\ndiff --git a/contrib/examples/git-merge.sh b/contrib/examples/git-merge.sh\nindex 49d8265..bab3da9 100755\n--- a/contrib/examples/git-merge.sh\n+++ b/contrib/examples/git-merge.sh\n@@ -36,6 +36,7 @@ LF='\n \n all_strategies='recur recursive octopus resolve stupid ours subtree'\n all_strategies=\"$all_strategies recursive-ours recursive-theirs\"\n+not_strategies='base file index tree'\n default_twohead_strategies='recursive'\n default_octopus_strategies='octopus'\n no_fast_forward_strategies='subtree ours'\n@@ -196,6 +197,10 @@ parse_config () {\n \t\t\t\tuse_strategies=\"$use_strategies$1 \"\n \t\t\t\t;;\n \t\t\t*)\n+\t\t\t\tcase \" $not_strategies \" in\n+\t\t\t\t*\" $1 \"*)\n+\t\t\t\t\tfalse\n+\t\t\t\tesac &&\n \t\t\t\ttype \"git-merge-$1\" >/dev/null 2>&1 ||\n \t\t\t\t\tdie \"available strategies are: $all_strategies\"\n \t\t\t\tuse_strategies=\"$use_strategies$1 \"\n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"148250","messageId":"20100817070656.GS22057@burratino","threadId":"24765","inReplyTo":"20100817065147.GA18293@burratino","subject":"[PATCH 19/24] merge script: handle -m --log correctly","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T07:06:56Z","receivedAt":"2010-08-17T07:06:56Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Based on v1.7.1.1~23^2 (merge: --log appends shortlog to message if\nspecified, 2010-05-11).  Without this change, the scripted\n(non-builtin) merge does not pass t7604.\n\nCc: Tay Ray Chuan <rctay89@gmail.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n contrib/examples/git-merge.sh |   14 ++++++++++----\n 1 files changed, 10 insertions(+), 4 deletions(-)\n\ndiff --git a/contrib/examples/git-merge.sh b/contrib/examples/git-merge.sh\nindex bab3da9..91e33a3 100755\n--- a/contrib/examples/git-merge.sh\n+++ b/contrib/examples/git-merge.sh\n@@ -294,12 +294,18 @@ else\n \t# the given message.  If remote is invalid we will die\n \t# later in the common codepath so we discard the error\n \t# in this loop.\n-\tmerge_name=$(for remote\n+\tmerge_msg=\"$(\n+\t\tfor remote\n \t\tdo\n \t\t\tmerge_name \"$remote\"\n-\t\tdone | git fmt-merge-msg $log_arg\n-\t)\n-\tmerge_msg=\"${merge_msg:+$merge_msg$LF$LF}$merge_name\"\n+\t\tdone |\n+\t\tif test \"$have_message\" = t\n+\t\tthen\n+\t\t\tgit fmt-merge-msg -m \"$merge_msg\" $log_arg\n+\t\telse\n+\t\t\tgit fmt-merge-msg $log_arg\n+\t\tfi\n+\t)\"\n fi\n head=$(git rev-parse --verify \"$head_arg\"^0) || usage\n \n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"148251","messageId":"20100817070958.GT22057@burratino","threadId":"24765","inReplyTo":"20100817065147.GA18293@burratino","subject":"[PATCH 20/24] merge script: handle many-way octopus","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T07:09:58Z","receivedAt":"2010-08-17T07:09:58Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Based on v1.6.0-rc0~51^2~5 (Build in merge, 2008-07-07).\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n contrib/examples/git-merge.sh |    6 +++---\n 1 files changed, 3 insertions(+), 3 deletions(-)\n\ndiff --git a/contrib/examples/git-merge.sh b/contrib/examples/git-merge.sh\nindex 91e33a3..410fa3c 100755\n--- a/contrib/examples/git-merge.sh\n+++ b/contrib/examples/git-merge.sh\n@@ -374,7 +374,7 @@ case \"$#\" in\n \tcommon=$(git merge-base --all $head \"$@\")\n \t;;\n *)\n-\tcommon=$(git show-branch --merge-base $head \"$@\")\n+\tcommon=$(git merge-base --all --octopus $head \"$@\")\n \t;;\n esac\n echo \"$head\" >\"$GIT_DIR/ORIG_HEAD\"\n@@ -528,9 +528,9 @@ if test '' != \"$result_tree\"\n then\n     if test \"$allow_fast_forward\" = \"t\"\n     then\n-        parents=$(git show-branch --independent \"$head\" \"$@\")\n+\tparents=$(git merge-base --independent \"$head\" \"$@\")\n     else\n-        parents=$(git rev-parse \"$head\" \"$@\")\n+\tparents=$(git rev-parse \"$head\" \"$@\")\n     fi\n     parents=$(echo \"$parents\" | sed -e 's/^/-p /')\n     result_commit=$(printf '%s\\n' \"$merge_msg\" | git commit-tree $result_tree $parents) || exit\n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"148252","messageId":"20100817071017.GU22057@burratino","threadId":"24765","inReplyTo":"20100817065147.GA18293@burratino","subject":"[PATCH 21/24] merge script: --ff-only to disallow true merge","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T07:10:17Z","receivedAt":"2010-08-17T07:10:17Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Port v1.6.6-rc0~62^2 (Teach 'git merge' and 'git pull' the option\n--ff-only, 2009-10-29) to the old merge script.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n contrib/examples/git-merge.sh |   17 +++++++++++++++--\n 1 files changed, 15 insertions(+), 2 deletions(-)\n\ndiff --git a/contrib/examples/git-merge.sh b/contrib/examples/git-merge.sh\nindex 410fa3c..dfd6e17 100755\n--- a/contrib/examples/git-merge.sh\n+++ b/contrib/examples/git-merge.sh\n@@ -15,6 +15,7 @@ log                  add list of one-line log to merge commit message\n squash               create a single commit instead of doing a merge\n commit               perform a commit if the merge succeeds (default)\n ff                   allow fast-forward (default)\n+ff-only              abort if fast-forward is not possible\n s,strategy=          merge strategy to use\n X=                   option for selected merge strategy\n m,message=           message to be used for the merge commit (if any)\n@@ -45,6 +46,7 @@ use_strategies=\n xopt=\n \n allow_fast_forward=t\n+fast_forward_only=\n allow_trivial_merge=t\n squash= no_commit= log_arg=\n \n@@ -189,7 +191,13 @@ parse_config () {\n \t\t--no-ff)\n \t\t\ttest \"$squash\" != t ||\n \t\t\t\tdie \"You cannot combine --squash with --no-ff.\"\n+\t\t\ttest \"$fast_forward_only\" != t ||\n+\t\t\t\tdie \"You cannot combine --ff-only with --no-ff.\"\n \t\t\tallow_fast_forward=f ;;\n+\t\t--ff-only)\n+\t\t\ttest \"$allow_fast_forward\" != f ||\n+\t\t\t\tdie \"You cannot combine --ff-only with --no-ff.\"\n+\t\t\tfast_forward_only=t ;;\n \t\t-s|--strategy)\n \t\t\tshift\n \t\t\tcase \" $all_strategies \" in\n@@ -412,8 +420,8 @@ t,1,\"$head\",*)\n \t# We are not doing octopus, not fast-forward, and have only\n \t# one common.\n \tgit update-index --refresh 2>/dev/null\n-\tcase \"$allow_trivial_merge\" in\n-\tt)\n+\tcase \"$allow_trivial_merge,$fast_forward_only\" in\n+\tt,)\n \t\t# See if it is really trivial.\n \t\tgit var GIT_COMMITTER_IDENT >/dev/null || exit\n \t\techo \"Trying really trivial in-index merge...\"\n@@ -452,6 +460,11 @@ t,1,\"$head\",*)\n \t;;\n esac\n \n+if test \"$fast_forward_only\" = t\n+then\n+\tdie \"Not possible to fast-forward, aborting.\"\n+fi\n+\n # We are going to make a new commit.\n git var GIT_COMMITTER_IDENT >/dev/null || exit\n \n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"148253","messageId":"20100817071103.GV22057@burratino","threadId":"24765","inReplyTo":"20100817065147.GA18293@burratino","subject":"[PATCH 22/24] merge script: handle --no-ff --no-commit correctly","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T07:11:03Z","receivedAt":"2010-08-17T07:11:03Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"In a --no-ff merge with conflicts, \"git commit\" used to forget the\n--no-ff when used to complete the merge.  That was fixed by\nv1.6.1-rc1~134^2 (builtin-commit: use reduce_heads() only when\nappropriate, 2008-10-03) for the builtin merge.  Port the change to\nthe merge script in contrib/examples.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n contrib/examples/git-merge.sh |   12 ++++++++++--\n 1 files changed, 10 insertions(+), 2 deletions(-)\n\ndiff --git a/contrib/examples/git-merge.sh b/contrib/examples/git-merge.sh\nindex dfd6e17..5a2addd 100755\n--- a/contrib/examples/git-merge.sh\n+++ b/contrib/examples/git-merge.sh\n@@ -52,7 +52,7 @@ squash= no_commit= log_arg=\n \n dropsave() {\n \trm -f -- \"$GIT_DIR/MERGE_HEAD\" \"$GIT_DIR/MERGE_MSG\" \\\n-\t\t \"$GIT_DIR/MERGE_STASH\" || exit 1\n+\t\t \"$GIT_DIR/MERGE_STASH\" \"$GIT_DIR/MERGE_MODE\" || exit 1\n }\n \n savestate() {\n@@ -585,7 +585,15 @@ else\n \tdo\n \t\techo $remote\n \tdone >\"$GIT_DIR/MERGE_HEAD\"\n-\tprintf '%s\\n' \"$merge_msg\" >\"$GIT_DIR/MERGE_MSG\"\n+\tprintf '%s\\n' \"$merge_msg\" >\"$GIT_DIR/MERGE_MSG\" ||\n+\t\tdie \"Could not write to $GIT_DIR/MERGE_MSG\"\n+\tif test \"$allow_fast_forward\" != t\n+\tthen\n+\t\tprintf \"%s\" no-ff\n+\telse\n+\t\t:\n+\tfi >\"$GIT_DIR/MERGE_MODE\" ||\n+\t\tdie \"Could not write to $GIT_DIR/MERGE_MODE\"\n fi\n \n if test \"$merge_was_ok\" = t\n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"148254","messageId":"20100817071130.GW22057@burratino","threadId":"24765","inReplyTo":"20100817065147.GA18293@burratino","subject":"[PATCH 23/24] merge script: notice @{-1} shorthand","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T07:11:30Z","receivedAt":"2010-08-17T07:11:30Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Port v1.6.2-rc1~10^2 (Teach @{-1} to git merge, 2009-02-13) to\nthe old merge script.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\n contrib/examples/git-merge.sh |    6 ++++--\n 1 files changed, 4 insertions(+), 2 deletions(-)\n\ndiff --git a/contrib/examples/git-merge.sh b/contrib/examples/git-merge.sh\nindex 5a2addd..bed55a4 100755\n--- a/contrib/examples/git-merge.sh\n+++ b/contrib/examples/git-merge.sh\n@@ -148,13 +148,15 @@ merge_name () {\n \tif found_ref=$(git rev-parse --symbolic-full-name --verify \\\n \t\t\t\t\t\t\t\"$remote\" 2>/dev/null)\n \tthen\n+\t\texpanded=$(git check-ref-format --branch \"$remote\") ||\n+\t\t\texit\n \t\tif test \"${found_ref#refs/heads/}\" != \"$found_ref\"\n \t\tthen\n-\t\t\techo \"$rh\t\tbranch '$remote' of .\"\n+\t\t\techo \"$rh\t\tbranch '$expanded' of .\"\n \t\t\treturn\n \t\telif test \"${found_ref#refs/remotes/}\" != \"$found_ref\"\n \t\tthen\n-\t\t\techo \"$rh\t\tremote branch '$remote' of .\"\n+\t\t\techo \"$rh\t\tremote branch '$expanded' of .\"\n \t\t\treturn\n \t\tfi\n \tfi\n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"148255","messageId":"20100817071340.GX22057@burratino","threadId":"24765","inReplyTo":"20100817065147.GA18293@burratino","subject":"[PATCH 24/24] merge script: learn --[no-]rerere-autoupdate","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T07:13:40Z","receivedAt":"2010-08-17T07:13:40Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Port v1.7.0-rc0~83^2 (Teach --[no-]rerere-autoupdate option to\nmerge, revert and friends, 2009-12-04) to the example merge script.\n\nAfter this change, all tests pass for me with the scripted\nmerge.\n\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\nTo test: remove cmd_merge from the builtins list in git.c,\nbuild git, and then run:\n\n cp contrib/examples/git-merge.sh .\n make SCRIPT_SH=git-merge.sh git-merge\n cd t && make\n\nThat's the end of the series.  Thanks for reading.\n\n contrib/examples/git-merge.sh |    7 +++++--\n 1 files changed, 5 insertions(+), 2 deletions(-)\n\ndiff --git a/contrib/examples/git-merge.sh b/contrib/examples/git-merge.sh\nindex bed55a4..7b922c3 100755\n--- a/contrib/examples/git-merge.sh\n+++ b/contrib/examples/git-merge.sh\n@@ -16,6 +16,7 @@ squash               create a single commit instead of doing a merge\n commit               perform a commit if the merge succeeds (default)\n ff                   allow fast-forward (default)\n ff-only              abort if fast-forward is not possible\n+rerere-autoupdate    update index with any reused conflict resolution\n s,strategy=          merge strategy to use\n X=                   option for selected merge strategy\n m,message=           message to be used for the merge commit (if any)\n@@ -48,7 +49,7 @@ xopt=\n allow_fast_forward=t\n fast_forward_only=\n allow_trivial_merge=t\n-squash= no_commit= log_arg=\n+squash= no_commit= log_arg= rr_arg=\n \n dropsave() {\n \trm -f -- \"$GIT_DIR/MERGE_HEAD\" \"$GIT_DIR/MERGE_MSG\" \\\n@@ -200,6 +201,8 @@ parse_config () {\n \t\t\ttest \"$allow_fast_forward\" != f ||\n \t\t\t\tdie \"You cannot combine --ff-only with --no-ff.\"\n \t\t\tfast_forward_only=t ;;\n+\t\t--rerere-autoupdate|--no-rerere-autoupdate)\n+\t\t\trr_arg=$1 ;;\n \t\t-s|--strategy)\n \t\t\tshift\n \t\t\tcase \" $all_strategies \" in\n@@ -612,6 +615,6 @@ Conflicts:\n \t\tsed -e 's/^[^\t]*\t/\t/' |\n \t\tuniq\n \t} >>\"$GIT_DIR/MERGE_MSG\"\n-\tgit rerere\n+\tgit rerere $rr_arg\n \tdie \"Automatic merge failed; fix conflicts and then commit the result.\"\n fi\n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"148256","messageId":"AANLkTimx2bn_Z+MMK_abYin9vdNaBnw7egjdszu4PqGx@mail.gmail.com","threadId":"24765","inReplyTo":"20100817065459.GC22057@burratino","subject":"Re: [PATCH 03/24] t7600 (merge): do not launch gitk for --debug","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-08-17T07:31:55Z","receivedAt":"2010-08-17T07:31:55Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Tue, Aug 17, 2010 at 06:54, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> Probably as a development aid, this test script runs gitk --all\n> to allow the driver to inspect history between tests when run\n> with --debug.  As a result, running all tests with --debug\n> requires closing a long series of gitk displays, one at a time.\n\nYes!, I was going to fix that myself sometime. Thanks for doing it,\nthat behavior was very annoying.\n"},{"id":"148257","messageId":"AANLkTi=CTzhzO+mZ9hw4pbVaEpegZCt56bo0FzHgie36@mail.gmail.com","threadId":"24765","inReplyTo":"20100817070336.GM22057@burratino","subject":"Re: [PATCH 13/24] merge script: tweak unmerged files message to match builtin","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-08-17T07:36:37Z","receivedAt":"2010-08-17T07:36:37Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Tue, Aug 17, 2010 at 07:03, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> Before:\n>\n>        You are in the middle of a conflicted merge.\n>\n> After:\n>\n>        Merge is not possible because you have unmerged files.\n>\n> I prefer the old message.\n\nI prefer the new one, thanks :)\n"},{"id":"148259","messageId":"AANLkTikf-do4nyQO=W93BxKxDekQJpExLtop__tz1n8o@mail.gmail.com","threadId":"24765","inReplyTo":"20100817065147.GA18293@burratino","subject":"Re: [PATCH/RFC] updating examples/git-merge (plus a builtin/merge fix)","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-08-17T07:46:12Z","receivedAt":"2010-08-17T07:46:12Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Tue, Aug 17, 2010 at 06:51, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> While preparing to make some minor \"git merge\" changes, I noticed that\n> the old merge script does not pass all tests any more.  Since it can\n> be easier to prototype in shell and then port to C, I think that is\n> worth fixing.\n>\n> Of course this is not urgent at all.\n\n> Patches 2-7 are minor test changes.  They are early in the series\n> to give flexibility about when to merge them.\n\nThose all looked good, thanks for tackling that.\n\n> Patches 8-10 expose functionality used by merge when handling octopus\n> merges.\n\nYou mean 9-10, 8 looks good. I don't have the familiarity to comment\non 9-10.\n\n> Patches 12 and later are ports of various patches to builtin/merge.c.\n> I did the bare minimum to make tests pass. :)\n\nThose also look good to my untrained eye.\n\nHow do you run the tests against git-merge.sh? Is there some make\ntarget to use it instead of git-merge.c, or do you manually move it in\nplace?\n\nIf it's the latter a switch somewhere to run the test suite against\nthese .sh alternatives might compliment this series nicely.\n"},{"id":"148261","messageId":"20100817081033.GB28476@burratino","threadId":"24765","inReplyTo":"AANLkTikf-do4nyQO=W93BxKxDekQJpExLtop__tz1n8o@mail.gmail.com","subject":"Re: [PATCH/RFC] updating examples/git-merge (plus a builtin/merge fix)","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T08:10:33Z","receivedAt":"2010-08-17T08:10:33Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Ævar Arnfjörð Bjarmason wrote:\n> On Tue, Aug 17, 2010 at 06:51, Jonathan Nieder <jrnieder@gmail.com> wrote:\n\n>> Patches 8-10 expose functionality used by merge when handling octopus\n>> merges.\n>\n> You mean 9-10, 8 looks good. I don't have the familiarity to comment\n> on 9-10.\n\nI would be especially interested in feedback on the interface from\nthose two. ;-)\n\nIs merge-base the right command to learn --independent?\n\nIs --independent the right name for \"reduced parent list\"?\n\nIs merge-base --octopus generally useful at all, or should we change\nthe API for custom octopus strategies (maybe at the same time as\nteaching them to declare NO_TRIVIAL and NO_FAST_FORWARD preferences)\nto leave the list of merge bases out?\n\n>> Patches 12 and later are ports of various patches to builtin/merge.c.\n>> I did the bare minimum to make tests pass. :)\n>\n> Those also look good to my untrained eye.\n\nThanks for looking them over.\n\n> How do you run the tests against git-merge.sh? Is there some make\n> target to use it instead of git-merge.c, or do you manually move it in\n> place?\n\nAh, yes, I should have made that information more prominent.\n\nTo test: remove cmd_merge from the builtins list in git.c,\nbuild git, and then run:\n\n cp contrib/examples/git-merge.sh .\n make SCRIPT_SH=git-merge.sh git-merge\n cd t && make\n\n> If it's the latter a switch somewhere to run the test suite against\n> these .sh alternatives might compliment this series nicely.\n\nYes, that sounds like an good idea.  Of course most of the retired\nscripts are bitrotted by now.\n"},{"id":"148271","messageId":"AANLkTimrrfVsP=yduEmstuhm=Y-Km=HmoYgAvRkmQf91@mail.gmail.com","threadId":"24765","inReplyTo":"20100817070656.GS22057@burratino","subject":"Re: [PATCH 19/24] merge script: handle -m --log correctly","fromName":"Tay Ray Chuan","fromEmail":"rctay89@gmail.com","sentAt":"2010-08-17T09:55:22Z","receivedAt":"2010-08-17T09:55:22Z","isPatch":true,"sender":{"key":"rctay89@gmail.com","avatar":"https://avatars.githubusercontent.com/u/61553?v=4"},"body":"On Tue, Aug 17, 2010 at 3:06 PM, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> Based on v1.7.1.1~23^2 (merge: --log appends shortlog to message if\n> specified, 2010-05-11).  Without this change, the scripted\n> (non-builtin) merge does not pass t7604.\n>\n> Cc: Tay Ray Chuan <rctay89@gmail.com>\n> Signed-off-by: Jonathan Nieder <jrnieder@gmail.com>\n\nThanks for the heads up.\n\n> diff --git a/contrib/examples/git-merge.sh b/contrib/examples/git-merge.sh\n> index bab3da9..91e33a3 100755\n> --- a/contrib/examples/git-merge.sh\n> +++ b/contrib/examples/git-merge.sh\n> @@ -294,12 +294,18 @@ else\n>        # the given message.  If remote is invalid we will die\n>        # later in the common codepath so we discard the error\n>        # in this loop.\n> -       merge_name=$(for remote\n> +       merge_msg=\"$(\n> +               for remote\n>                do\n>                        merge_name \"$remote\"\n> -               done | git fmt-merge-msg $log_arg\n> -       )\n> -       merge_msg=\"${merge_msg:+$merge_msg$LF$LF}$merge_name\"\n> +               done |\n> +               if test \"$have_message\" = t\n> +               then\n> +                       git fmt-merge-msg -m \"$merge_msg\" $log_arg\n\nhmm, when did git-fmt-merge-msg learn -m? Mine (1.7.2.1.219.gf2a27) doesn't.\n\n-- \nCheers,\nRay Chuan\n"},{"id":"148297","messageId":"AANLkTi=1Fz_wdf-grxFB17zUXpW+d26MudbbJP5K=fO_@mail.gmail.com","threadId":"24765","inReplyTo":"20100817065459.GC22057@burratino","subject":"Re: [PATCH 03/24] t7600 (merge): do not launch gitk for --debug","fromName":"Sverre Rabbelier","fromEmail":"srabbelier@gmail.com","sentAt":"2010-08-17T17:50:03Z","receivedAt":"2010-08-17T17:50:03Z","isPatch":true,"sender":{"key":"srabbelier@gmail.com","avatar":"https://avatars.githubusercontent.com/u/3098?v=4"},"body":"Heya,\n\nOn Tue, Aug 17, 2010 at 01:54, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> -test_debug 'gitk --all'\n> +test_debug 'git log --graph --decorate --oneline --all'\n\n\n> -test_debug 'gitk --all'\n> +test_debug 'git log --graph --decorate --oneline --all'\n\n> -test_debug 'gitk --all'\n> +test_debug 'git log --graph --decorate --oneline --all'\n\nReally? Why can't you stuff the command to execute in a variable? On\nthat note, why wasn't that done in the first place?! This kind of\nrepetition is not very DRY.\n\n-- \nCheers,\n\nSverre Rabbelier\n"},{"id":"148311","messageId":"20100817215404.GC2221@burratino","threadId":"24765","inReplyTo":"AANLkTimrrfVsP=yduEmstuhm=Y-Km=HmoYgAvRkmQf91@mail.gmail.com","subject":"Re: [PATCH 19/24] merge script: handle -m --log correctly","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T21:54:04Z","receivedAt":"2010-08-17T21:54:04Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Tay Ray Chuan wrote:\n\n> Thanks for the heads up.\n\nThanks for adding the feature in the first place. :)\n\n> On Tue, Aug 17, 2010 at 3:06 PM, Jonathan Nieder <jrnieder@gmail.com> wrote:\n\n>> +++ b/contrib/examples/git-merge.sh\n[...]\n>> -               done | git fmt-merge-msg $log_arg\n>> -       )\n>> -       merge_msg=\"${merge_msg:+$merge_msg$LF$LF}$merge_name\"\n>> +               done |\n>> +               if test \"$have_message\" = t\n>> +               then\n>> +                       git fmt-merge-msg -m \"$merge_msg\" $log_arg\n>\n> hmm, when did git-fmt-merge-msg learn -m? Mine (1.7.2.1.219.gf2a27) doesn't.\n\nPatch 11 from this series (\"fmt-merge-msg -m to override subject line\")\nshould do it, assuming it works correctly.\n"},{"id":"148313","messageId":"20100817230034.GG2221@burratino","threadId":"24765","inReplyTo":"20100817070245.GK22057@burratino","subject":"[PATCH 11/24 v2] fmt-merge-msg -m to override merge title","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-17T23:00:34Z","receivedAt":"2010-08-17T23:00:34Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Since v1.7.1.1~23^2 (merge: --log appends shortlog to message if\nspecified, 2010-05-11), the fmt-merge-msg backend supports custom text\nto override the merge title \"Merge <foo> into <bar>\".\n\nExpose this functionality for scripted callers.  Example:\n\n git fmt-merge-msg --log -m \\\n\t\"$(printf '%s\\n' \\\n\t    \"Merge branch 'api-cleanup' into feature\" \\\n\t    '' \\\n\t    'This is to use a few functions refactored for this purpose.'\n\t)\" <.git/FETCH_HEAD\n\nCc: Tay Ray Chuan <rctay89@gmail.com>\nSigned-off-by: Jonathan Nieder <jrnieder@gmail.com>\n---\nJonathan Nieder wrote:\n\n> +'git fmt-merge-msg' [-m <subject>] [--log ]| --no-log] -F <file>\n\nOops.\n\n> +-m <subject>::\n> +--message <subject>::\n\nSince the message is used to start the body of the message in\naddition to the subject, the generic word <message> seems clearer.\n\n> -\t\"git fmt-merge-msg [--log|--no-log] [--file <file>]\",\n> +\t\"git fmt-merge-msg [-m <online>] [--log|--no-log] [--file <file>]\",\n\nLikewise.\n\n> +\t\tOPT_STRING('m', \"message\", &oneline_msg, \"oneline\",\n> +\t\t\t\"use <oneline> as subject line\"),\n\nLikewise.\n\n Documentation/git-fmt-merge-msg.txt |    9 +++++++--\n builtin/fmt-merge-msg.c             |   18 ++++++++++++++++--\n t/t6200-fmt-merge-msg.sh            |   32 ++++++++++++++++++++++++++++++++\n 3 files changed, 55 insertions(+), 4 deletions(-)\n\ndiff --git a/Documentation/git-fmt-merge-msg.txt b/Documentation/git-fmt-merge-msg.txt\nindex a585dbe..302f56b 100644\n--- a/Documentation/git-fmt-merge-msg.txt\n+++ b/Documentation/git-fmt-merge-msg.txt\n@@ -9,8 +9,8 @@ git-fmt-merge-msg - Produce a merge commit message\n SYNOPSIS\n --------\n [verse]\n-'git fmt-merge-msg' [--log | --no-log] <$GIT_DIR/FETCH_HEAD\n-'git fmt-merge-msg' [--log | --no-log] -F <file>\n+'git fmt-merge-msg' [-m <message>] [--log | --no-log] <$GIT_DIR/FETCH_HEAD\n+'git fmt-merge-msg' [-m <message>] [--log | --no-log] -F <file>\n \n DESCRIPTION\n -----------\n@@ -38,6 +38,11 @@ OPTIONS\n \tSynonyms to --log and --no-log; these are deprecated and will be\n \tremoved in the future.\n \n+-m <message>::\n+--message <message>::\n+\tUse <message> instead of the branch names for the first line\n+\tof the log message.  For use with `--log`.\n+\n -F <file>::\n --file <file>::\n \tTake the list of merged objects from <file> instead of\ndiff --git a/builtin/fmt-merge-msg.c b/builtin/fmt-merge-msg.c\nindex bc3c5e6..937d5a7 100644\n--- a/builtin/fmt-merge-msg.c\n+++ b/builtin/fmt-merge-msg.c\n@@ -7,7 +7,7 @@\n #include \"string-list.h\"\n \n static const char * const fmt_merge_msg_usage[] = {\n-\t\"git fmt-merge-msg [--log|--no-log] [--file <file>]\",\n+\t\"git fmt-merge-msg [-m <message>] [--log|--no-log] [--file <file>]\",\n \tNULL\n };\n \n@@ -319,11 +319,14 @@ int fmt_merge_msg_shortlog(struct strbuf *in, struct strbuf *out) {\n int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)\n {\n \tconst char *inpath = NULL;\n+\tconst char *message = NULL;\n \tstruct option options[] = {\n \t\tOPT_BOOLEAN(0, \"log\",     &merge_summary, \"populate log with the shortlog\"),\n \t\t{ OPTION_BOOLEAN, 0, \"summary\", &merge_summary, NULL,\n \t\t  \"alias for --log (deprecated)\",\n \t\t  PARSE_OPT_NOARG | PARSE_OPT_HIDDEN },\n+\t\tOPT_STRING('m', \"message\", &message, \"text\",\n+\t\t\t\"use <text> as start of message\"),\n \t\tOPT_FILENAME('F', \"file\", &inpath, \"file to read from\"),\n \t\tOPT_END()\n \t};\n@@ -337,6 +340,12 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)\n \t\t\t     0);\n \tif (argc > 0)\n \t\tusage_with_options(fmt_merge_msg_usage, options);\n+\tif (message && !merge_summary) {\n+\t\tchar nl = '\\n';\n+\t\twrite_in_full(STDOUT_FILENO, message, strlen(message));\n+\t\twrite_in_full(STDOUT_FILENO, &nl, 1);\n+\t\treturn 0;\n+\t}\n \n \tif (inpath && strcmp(inpath, \"-\")) {\n \t\tin = fopen(inpath, \"r\");\n@@ -346,7 +355,12 @@ int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix)\n \n \tif (strbuf_read(&input, fileno(in), 0) < 0)\n \t\tdie_errno(\"could not read input file\");\n-\tret = fmt_merge_msg(merge_summary, &input, &output);\n+\tif (message) {\n+\t\tstrbuf_addstr(&output, message);\n+\t\tret = fmt_merge_msg_shortlog(&input, &output);\n+\t} else {\n+\t\tret = fmt_merge_msg(merge_summary, &input, &output);\n+\t}\n \tif (ret)\n \t\treturn ret;\n \twrite_in_full(STDOUT_FILENO, output.buf, output.len);\ndiff --git a/t/t6200-fmt-merge-msg.sh b/t/t6200-fmt-merge-msg.sh\nindex 5553dff..71f6cad 100755\n--- a/t/t6200-fmt-merge-msg.sh\n+++ b/t/t6200-fmt-merge-msg.sh\n@@ -129,6 +129,38 @@ test_expect_success '[merge] summary/log configuration' '\n \ttest_cmp expected actual2\n '\n \n+test_expect_success 'fmt-merge-msg -m' '\n+\techo \"Sync with left\" >expected &&\n+\tcat >expected.log <<-EOF &&\n+\tSync with left\n+\n+\t* ${apos}left${apos} of $(pwd):\n+\t  Left #5\n+\t  Left #4\n+\t  Left #3\n+\t  Common #2\n+\t  Common #1\n+\tEOF\n+\n+\ttest_might_fail git config --unset merge.log &&\n+\ttest_might_fail git config --unset merge.summary &&\n+\tgit checkout master &&\n+\tgit fetch \"$(pwd)\" left &&\n+\tgit fmt-merge-msg -m \"Sync with left\" <.git/FETCH_HEAD >actual &&\n+\tgit fmt-merge-msg --log -m \"Sync with left\" \\\n+\t\t\t\t\t<.git/FETCH_HEAD >actual.log &&\n+\tgit config merge.log true &&\n+\tgit fmt-merge-msg -m \"Sync with left\" \\\n+\t\t\t\t\t<.git/FETCH_HEAD >actual.log-config &&\n+\tgit fmt-merge-msg --no-log -m \"Sync with left\" \\\n+\t\t\t\t\t<.git/FETCH_HEAD >actual.nolog &&\n+\n+\ttest_cmp expected actual &&\n+\ttest_cmp expected.log actual.log &&\n+\ttest_cmp expected.log actual.log-config &&\n+\ttest_cmp expected actual.nolog\n+'\n+\n test_expect_success 'setup: expected shortlog for two branches' '\n \tcat >expected <<-EOF\n \tMerge branches ${apos}left${apos} and ${apos}right${apos}\n-- \n1.7.2.1.544.ga752d.dirty\n"},{"id":"148331","messageId":"20100818022931.GA19868@burratino","threadId":"24765","inReplyTo":"AANLkTi=1Fz_wdf-grxFB17zUXpW+d26MudbbJP5K=fO_@mail.gmail.com","subject":"Re: [PATCH 03/24] t7600 (merge): do not launch gitk for --debug","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-18T02:29:31Z","receivedAt":"2010-08-18T02:29:31Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Sverre Rabbelier wrote:\n> On Tue, Aug 17, 2010 at 01:54, Jonathan Nieder <jrnieder@gmail.com> wrote:\n\n>> -test_debug 'gitk --all'\n>> +test_debug 'git log --graph --decorate --oneline --all'\n>\n>> -test_debug 'gitk --all'\n>> +test_debug 'git log --graph --decorate --oneline --all'\n[...]\n> Really? Why can't you stuff the command to execute in a variable? On\n> that note, why wasn't that done in the first place?! This kind of\n> repetition is not very DRY.\n\nMy thought was that\n\n test_debug '$debug_command'\n ...\n test_debug '$debug_command'\n ...\n [etc]\n\nis not very DRY either, so I am hoping some configurable version of\n\n-- 8< --\ndiff --git a/t/test-lib.sh b/t/test-lib.sh\nindex e8f21d5..65b0e35 100644\n--- a/t/test-lib.sh\n+++ b/t/test-lib.sh\n@@ -373,6 +373,7 @@ test_run_ () {\n \tif test \"$verbose\" = \"t\" && test -n \"$HARNESS_ACTIVE\"; then\n \t\techo \"\"\n \tfi\n+\ttest_debug \"git log --graph --decorate --oneline --all\"\n \treturn 0\n }\n \n-- >8 --\n\nappears to replace it.  In the short term, the \"s/gitk --all/git log\n--graph --decorate --oneline --all/\" was just meant as a quick fix\nso as not to drop the feature.  Ideas?\n"},{"id":"148346","messageId":"AANLkTikBmYH1xC_7iiXQK8-vo0yavwX_ELR=z1kfVSLj@mail.gmail.com","threadId":"24765","inReplyTo":"20100818022931.GA19868@burratino","subject":"Re: [PATCH 03/24] t7600 (merge): do not launch gitk for --debug","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-08-18T08:55:59Z","receivedAt":"2010-08-18T08:55:59Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"On Wed, Aug 18, 2010 at 02:29, Jonathan Nieder <jrnieder@gmail.com> wrote:\n> Sverre Rabbelier wrote:\n>> On Tue, Aug 17, 2010 at 01:54, Jonathan Nieder <jrnieder@gmail.com> wrote:\n>\n>>> -test_debug 'gitk --all'\n>>> +test_debug 'git log --graph --decorate --oneline --all'\n>>\n>>> -test_debug 'gitk --all'\n>>> +test_debug 'git log --graph --decorate --oneline --all'\n> [...]\n>> Really? Why can't you stuff the command to execute in a variable? On\n>> that note, why wasn't that done in the first place?! This kind of\n>> repetition is not very DRY.\n>\n> My thought was that\n>\n>  test_debug '$debug_command'\n>  ...\n>  test_debug '$debug_command'\n>  ...\n>  [etc]\n>\n> is not very DRY either, so I am hoping some configurable version of\n>\n> -- 8< --\n> diff --git a/t/test-lib.sh b/t/test-lib.sh\n> index e8f21d5..65b0e35 100644\n> --- a/t/test-lib.sh\n> +++ b/t/test-lib.sh\n> @@ -373,6 +373,7 @@ test_run_ () {\n>        if test \"$verbose\" = \"t\" && test -n \"$HARNESS_ACTIVE\"; then\n>                echo \"\"\n>        fi\n> +       test_debug \"git log --graph --decorate --oneline --all\"\n>        return 0\n>  }\n>\n> -- >8 --\n>\n> appears to replace it.  In the short term, the \"s/gitk --all/git log\n> --graph --decorate --oneline --all/\" was just meant as a quick fix\n> so as not to drop the feature.  Ideas?\n\nThe main issue here is that --debug means two things. It runs\ntest_debug() code AND instructs the test-lib not to remove the trash\ndirectory when it's done.\n\nIf we had a separate --keep-trash option most of this problem would go\naway, no?\n\nAside from that it's better to use git log rather than gitk in\ntest_debug, since it's in text form it can be easily sent along with a\nfailing test, which is not the case for dozens of gitk invocations.\n"},{"id":"148357","messageId":"20100818104432.GF6263@burratino","threadId":"24765","inReplyTo":"AANLkTikBmYH1xC_7iiXQK8-vo0yavwX_ELR=z1kfVSLj@mail.gmail.com","subject":"Re: [PATCH 03/24] t7600 (merge): do not launch gitk for --debug","fromName":"Jonathan Nieder","fromEmail":"jrnieder@gmail.com","sentAt":"2010-08-18T10:44:32Z","receivedAt":"2010-08-18T10:44:32Z","isPatch":true,"sender":{"key":"jrnieder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/281595?v=4"},"body":"Ævar Arnfjörð Bjarmason wrote:\n\n> The main issue here is that --debug means two things. It runs\n> test_debug() code AND instructs the test-lib not to remove the trash\n> directory when it's done.\n\nMost of the time I use --immediate, insert an explicit \"exit\", or hit\n^C instead of waiting for the test to complete anyway.  --debug always\nstruck me as a theoretically useful thing (more useful output!) though\nI never used it much.\n\n> If we had a separate --keep-trash option most of this problem would go\n> away, no?\n\nThat might be useful for e.g. automatically re-running tests with\nexpected failures or unexpected successes and tarring up the test\nrepo.\n\n> Aside from that it's better to use git log rather than gitk in\n> test_debug, since it's in text form it can be easily sent along with a\n> failing test, which is not the case for dozens of gitk invocations.\n\nRight, the effect of this patch is good though I agree with Sverre\nthat its method is ugly.\n\nMaybe unconditionally printing a log between tests would be good\nbehavior for --debug after all.  Not sure.\n"}]}