{"thread":{"id":"39695","subject":"[PATCH v3 1/6] bisect: correction of typo","startedAt":"2015-06-22T21:00:31Z","lastAt":"2015-06-26T20:18:27Z","messageCount":48,"participants":["Antoine Delaite","Matthieu Moy","Eric Sunshine","Junio C Hamano","Remi Galan Alfonso","Christian Couder"],"isPatch":true,"patchVersion":3,"patchTotal":6},"messages":[{"id":"264582","messageId":"1435006836-18182-1-git-send-email-antoine.delaite@ensimag.grenoble-inp.fr","threadId":"39695","inReplyTo":null,"subject":"[PATCH v3 1/6] bisect: correction of typo","fromName":"Antoine Delaite","fromEmail":"antoine.delaite@ensimag.grenoble-inp.fr","sentAt":"2015-06-22T21:00:31Z","receivedAt":"2015-06-22T21:00:31Z","isPatch":true,"sender":{"key":"antoine.delaite@ensimag.grenoble-inp.fr","avatar":"https://avatars.githubusercontent.com/u/12510393?v=4"},"body":"Signed-off-by: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\n---\n bisect.c                    |    2 +-\n t/t6030-bisect-porcelain.sh |    2 +-\n 2 files changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/bisect.c b/bisect.c\nindex 03d5cd9..5b8357d 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -743,7 +743,7 @@ static void handle_bad_merge_base(void)\n \n \tfprintf(stderr, \"Some good revs are not ancestor of the bad rev.\\n\"\n \t\t\"git bisect cannot work properly in this case.\\n\"\n-\t\t\"Maybe you mistake good and bad revs?\\n\");\n+\t\t\"Maybe you mistook good and bad revs?\\n\");\n \texit(1);\n }\n \ndiff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh\nindex 06b4868..9e2c203 100755\n--- a/t/t6030-bisect-porcelain.sh\n+++ b/t/t6030-bisect-porcelain.sh\n@@ -362,7 +362,7 @@ test_expect_success 'bisect starting with a detached HEAD' '\n test_expect_success 'bisect errors out if bad and good are mistaken' '\n \tgit bisect reset &&\n \ttest_must_fail git bisect start $HASH2 $HASH4 2> rev_list_error &&\n-\tgrep \"mistake good and bad\" rev_list_error &&\n+\tgrep \"mistook good and bad\" rev_list_error &&\n \tgit bisect reset\n '\n \n-- \n1.7.1\n"},{"id":"264587","messageId":"1435006836-18182-2-git-send-email-antoine.delaite@ensimag.grenoble-inp.fr","threadId":"39695","inReplyTo":"1435006836-18182-1-git-send-email-antoine.delaite@ensimag.grenoble-inp.fr","subject":"[PATCH v3 2/6] bisect: replace hardcoded \"bad|good\" by variables","fromName":"Antoine Delaite","fromEmail":"antoine.delaite@ensimag.grenoble-inp.fr","sentAt":"2015-06-22T21:00:32Z","receivedAt":"2015-06-22T21:00:32Z","isPatch":true,"sender":{"key":"antoine.delaite@ensimag.grenoble-inp.fr","avatar":"https://avatars.githubusercontent.com/u/12510393?v=4"},"body":"To add new tags like old/new and have keywords less confusing, the\nfirst step is to avoid hardcoding the keywords.\n\nThe default mode is still bad/good.\n\nSigned-off-by: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\nSigned-off-by: Louis Stuber <stuberl@ensimag.grenoble-inp.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\n---\n bisect.c      |   51 ++++++++++++++++++++++++++++++++++-----------------\n git-bisect.sh |   57 +++++++++++++++++++++++++++++++--------------------------\n 2 files changed, 65 insertions(+), 43 deletions(-)\n mode change 100755 => 100644 git-bisect.sh\n\ndiff --git a/bisect.c b/bisect.c\nindex 5b8357d..cda30fa 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -21,6 +21,9 @@ static const char *argv_checkout[] = {\"checkout\", \"-q\", NULL, \"--\", NULL};\n static const char *argv_show_branch[] = {\"show-branch\", NULL, NULL};\n static const char *argv_update_ref[] = {\"update-ref\", \"--no-deref\", \"BISECT_HEAD\", NULL, NULL};\n \n+static const char *name_bad;\n+static const char *name_good;\n+\n /* Remember to update object flag allocation in object.h */\n #define COUNTED\t\t(1u<<16)\n \n@@ -403,15 +406,21 @@ struct commit_list *find_bisection(struct commit_list *list,\n static int register_ref(const char *refname, const struct object_id *oid,\n \t\t\tint flags, void *cb_data)\n {\n-\tif (!strcmp(refname, \"bad\")) {\n+\tstruct strbuf good_prefix = STRBUF_INIT;\n+\tstrbuf_addstr(&good_prefix, name_good);\n+\tstrbuf_addstr(&good_prefix, \"-\");\n+\n+\tif (!strcmp(refname, name_bad)) {\n \t\tcurrent_bad_oid = xmalloc(sizeof(*current_bad_oid));\n \t\toidcpy(current_bad_oid, oid);\n-\t} else if (starts_with(refname, \"good-\")) {\n+\t} else if (starts_with(refname, good_prefix.buf)) {\n \t\tsha1_array_append(&good_revs, oid->hash);\n \t} else if (starts_with(refname, \"skip-\")) {\n \t\tsha1_array_append(&skipped_revs, oid->hash);\n \t}\n \n+\tstrbuf_release(&good_prefix);\n+\n \treturn 0;\n }\n \n@@ -634,7 +643,7 @@ static void exit_if_skipped_commits(struct commit_list *tried,\n \t\treturn;\n \n \tprintf(\"There are only 'skip'ped commits left to test.\\n\"\n-\t       \"The first bad commit could be any of:\\n\");\n+\t       \"The first %s commit could be any of:\\n\", name_bad);\n \tprint_commit_list(tried, \"%s\\n\", \"%s\\n\");\n \tif (bad)\n \t\tprintf(\"%s\\n\", oid_to_hex(bad));\n@@ -732,18 +741,21 @@ static void handle_bad_merge_base(void)\n \tif (is_expected_rev(current_bad_oid)) {\n \t\tchar *bad_hex = oid_to_hex(current_bad_oid);\n \t\tchar *good_hex = join_sha1_array_hex(&good_revs, ' ');\n-\n-\t\tfprintf(stderr, \"The merge base %s is bad.\\n\"\n-\t\t\t\"This means the bug has been fixed \"\n-\t\t\t\"between %s and [%s].\\n\",\n-\t\t\tbad_hex, bad_hex, good_hex);\n-\n+\t\tif (!strcmp(name_bad, \"bad\")) {\n+\t\t\tfprintf(stderr, \"The merge base %s is bad.\\n\"\n+\t\t\t\t\"This means the bug has been fixed \"\n+\t\t\t\t\"between %s and [%s].\\n\",\n+\t\t\t\tbad_hex, bad_hex, good_hex);\n+\t\t} else {\n+\t\t\tdie(\"BUG: terms %s/%s not managed\", name_bad, name_good);\n+\t\t}\n \t\texit(3);\n \t}\n \n-\tfprintf(stderr, \"Some good revs are not ancestor of the bad rev.\\n\"\n+\tfprintf(stderr, \"Some %s revs are not ancestor of the %s rev.\\n\"\n \t\t\"git bisect cannot work properly in this case.\\n\"\n-\t\t\"Maybe you mistook good and bad revs?\\n\");\n+\t\t\"Maybe you mistook %s and %s revs?\\n\",\n+\t\tname_good, name_bad, name_good, name_bad);\n \texit(1);\n }\n \n@@ -755,10 +767,10 @@ static void handle_skipped_merge_base(const unsigned char *mb)\n \n \twarning(\"the merge base between %s and [%s] \"\n \t\t\"must be skipped.\\n\"\n-\t\t\"So we cannot be sure the first bad commit is \"\n+\t\t\"So we cannot be sure the first %s commit is \"\n \t\t\"between %s and %s.\\n\"\n \t\t\"We continue anyway.\",\n-\t\tbad_hex, good_hex, mb_hex, bad_hex);\n+\t\tbad_hex, good_hex, name_bad, mb_hex, bad_hex);\n \tfree(good_hex);\n }\n \n@@ -839,7 +851,7 @@ static void check_good_are_ancestors_of_bad(const char *prefix, int no_checkout)\n \tint fd;\n \n \tif (!current_bad_oid)\n-\t\tdie(\"a bad revision is needed\");\n+\t\tdie(\"a %s revision is needed\", name_bad);\n \n \t/* Check if file BISECT_ANCESTORS_OK exists. */\n \tif (!stat(filename, &st) && S_ISREG(st.st_mode))\n@@ -905,6 +917,8 @@ int bisect_next_all(const char *prefix, int no_checkout)\n \tconst unsigned char *bisect_rev;\n \tchar bisect_rev_hex[GIT_SHA1_HEXSZ + 1];\n \n+\tname_bad=\"bad\";\n+\tname_good=\"good\";\n \tif (read_bisect_refs())\n \t\tdie(\"reading bisect refs failed\");\n \n@@ -926,8 +940,10 @@ int bisect_next_all(const char *prefix, int no_checkout)\n \t\t */\n \t\texit_if_skipped_commits(tried, NULL);\n \n-\t\tprintf(\"%s was both good and bad\\n\",\n-\t\t       oid_to_hex(current_bad_oid));\n+\t\tprintf(\"%s was both %s and %s\\n\",\n+\t\t       oid_to_hex(current_bad_oid),\n+\t\t       name_good,\n+\t\t       name_bad);\n \t\texit(1);\n \t}\n \n@@ -942,7 +958,8 @@ int bisect_next_all(const char *prefix, int no_checkout)\n \n \tif (!hashcmp(bisect_rev, current_bad_oid->hash)) {\n \t\texit_if_skipped_commits(tried, current_bad_oid);\n-\t\tprintf(\"%s is the first bad commit\\n\", bisect_rev_hex);\n+\t\tprintf(\"%s is the first %s commit\\n\", bisect_rev_hex,\n+\t\t\tname_bad);\n \t\tshow_diff_tree(prefix, revs.commits->item);\n \t\t/* This means the bisection process succeeded. */\n \t\texit(10);\ndiff --git a/git-bisect.sh b/git-bisect.sh\nold mode 100755\nnew mode 100644\nindex ae3fec2..ce6412f\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -32,6 +32,8 @@ OPTIONS_SPEC=\n \n _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'\n _x40=\"$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40\"\n+NAME_BAD=bad\n+NAME_GOOD=good\n \n bisect_head()\n {\n@@ -100,8 +102,8 @@ bisect_start() {\n \t\t\t\tbreak\n \t\t\t}\n \t\t\tcase $bad_seen in\n-\t\t\t0) state='bad' ; bad_seen=1 ;;\n-\t\t\t*) state='good' ;;\n+\t\t\t0) state=$NAME_BAD ; bad_seen=1 ;;\n+\t\t\t*) state=$NAME_GOOD ;;\n \t\t\tesac\n \t\t\teval=\"$eval bisect_write '$state' '$rev' 'nolog' &&\"\n \t\t\tshift\n@@ -184,9 +186,12 @@ bisect_write() {\n \trev=\"$2\"\n \tnolog=\"$3\"\n \tcase \"$state\" in\n-\t\tbad)\t\ttag=\"$state\" ;;\n-\t\tgood|skip)\ttag=\"$state\"-\"$rev\" ;;\n-\t\t*)\t\tdie \"$(eval_gettext \"Bad bisect_write argument: \\$state\")\" ;;\n+\t\t\"$NAME_BAD\")\n+\t\t\ttag=\"$state\" ;;\n+\t\t\"$NAME_GOOD\"|skip)\n+\t\t\ttag=\"$state\"-\"$rev\" ;;\n+\t\t*)\n+\t\t\tdie \"$(eval_gettext \"Bad bisect_write argument: \\$state\")\" ;;\n \tesac\n \tgit update-ref \"refs/bisect/$tag\" \"$rev\" || exit\n \techo \"# $state: $(git show-branch $rev)\" >>\"$GIT_DIR/BISECT_LOG\"\n@@ -230,12 +235,12 @@ bisect_state() {\n \tcase \"$#,$state\" in\n \t0,*)\n \t\tdie \"$(gettext \"Please call 'bisect_state' with at least one argument.\")\" ;;\n-\t1,bad|1,good|1,skip)\n+\t1,\"$NAME_BAD\"|1,\"$NAME_GOOD\"|1,skip)\n \t\trev=$(git rev-parse --verify $(bisect_head)) ||\n \t\t\tdie \"$(gettext \"Bad rev input: $(bisect_head)\")\"\n \t\tbisect_write \"$state\" \"$rev\"\n \t\tcheck_expected_revs \"$rev\" ;;\n-\t2,bad|*,good|*,skip)\n+\t2,\"$NAME_BAD\"|*,\"$NAME_GOOD\"|*,skip)\n \t\tshift\n \t\thash_list=''\n \t\tfor rev in \"$@\"\n@@ -249,8 +254,8 @@ bisect_state() {\n \t\t\tbisect_write \"$state\" \"$rev\"\n \t\tdone\n \t\tcheck_expected_revs $hash_list ;;\n-\t*,bad)\n-\t\tdie \"$(gettext \"'git bisect bad' can take only one argument.\")\" ;;\n+\t*,\"$NAME_BAD\")\n+\t\tdie \"$(eval_gettext \"'git bisect \\$NAME_BAD' can take only one argument.\")\" ;;\n \t*)\n \t\tusage ;;\n \tesac\n@@ -259,21 +264,21 @@ bisect_state() {\n \n bisect_next_check() {\n \tmissing_good= missing_bad=\n-\tgit show-ref -q --verify refs/bisect/bad || missing_bad=t\n-\ttest -n \"$(git for-each-ref \"refs/bisect/good-*\")\" || missing_good=t\n+\tgit show-ref -q --verify refs/bisect/$NAME_BAD || missing_bad=t\n+\ttest -n \"$(git for-each-ref \"refs/bisect/$NAME_GOOD-*\")\" || missing_good=t\n \n \tcase \"$missing_good,$missing_bad,$1\" in\n \t,,*)\n-\t\t: have both good and bad - ok\n+\t\t: have both $NAME_GOOD and $NAME_BAD - ok\n \t\t;;\n \t*,)\n \t\t# do not have both but not asked to fail - just report.\n \t\tfalse\n \t\t;;\n-\tt,,good)\n+\tt,,\"$NAME_GOOD\")\n \t\t# have bad but not good.  we could bisect although\n \t\t# this is less optimum.\n-\t\tgettextln \"Warning: bisecting only with a bad commit.\" >&2\n+\t\teval_gettextln \"Warning: bisecting only with a \\$NAME_BAD commit.\" >&2\n \t\tif test -t 0\n \t\tthen\n \t\t\t# TRANSLATORS: Make sure to include [Y] and [n] in your\n@@ -283,7 +288,7 @@ bisect_next_check() {\n \t\t\tread yesno\n \t\t\tcase \"$yesno\" in [Nn]*) exit 1 ;; esac\n \t\tfi\n-\t\t: bisect without good...\n+\t\t: bisect without $NAME_GOOD...\n \t\t;;\n \t*)\n \n@@ -307,7 +312,7 @@ bisect_auto_next() {\n bisect_next() {\n \tcase \"$#\" in 0) ;; *) usage ;; esac\n \tbisect_autostart\n-\tbisect_next_check good\n+\tbisect_next_check $NAME_GOOD\n \n \t# Perform all bisection computation, display and checkout\n \tgit bisect--helper --next-all $(test -f \"$GIT_DIR/BISECT_HEAD\" && echo --no-checkout)\n@@ -316,18 +321,18 @@ bisect_next() {\n \t# Check if we should exit because bisection is finished\n \tif test $res -eq 10\n \tthen\n-\t\tbad_rev=$(git show-ref --hash --verify refs/bisect/bad)\n+\t\tbad_rev=$(git show-ref --hash --verify refs/bisect/$NAME_BAD)\n \t\tbad_commit=$(git show-branch $bad_rev)\n-\t\techo \"# first bad commit: $bad_commit\" >>\"$GIT_DIR/BISECT_LOG\"\n+\t\techo \"# first $NAME_BAD commit: $bad_commit\" >>\"$GIT_DIR/BISECT_LOG\"\n \t\texit 0\n \telif test $res -eq 2\n \tthen\n \t\techo \"# only skipped commits left to test\" >>\"$GIT_DIR/BISECT_LOG\"\n-\t\tgood_revs=$(git for-each-ref --format=\"%(objectname)\" \"refs/bisect/good-*\")\n-\t\tfor skipped in $(git rev-list refs/bisect/bad --not $good_revs)\n+\t\tgood_revs=$(git for-each-ref --format=\"%(objectname)\" \"refs/bisect/$NAME_GOOD-*\")\n+\t\tfor skipped in $(git rev-list refs/bisect/$NAME_BAD --not $good_revs)\n \t\tdo\n \t\t\tskipped_commit=$(git show-branch $skipped)\n-\t\t\techo \"# possible first bad commit: $skipped_commit\" >>\"$GIT_DIR/BISECT_LOG\"\n+\t\t\techo \"# possible first $NAME_BAD commit: $skipped_commit\" >>\"$GIT_DIR/BISECT_LOG\"\n \t\tdone\n \t\texit $res\n \tfi\n@@ -421,7 +426,7 @@ bisect_replay () {\n \t\tstart)\n \t\t\tcmd=\"bisect_start $rev\"\n \t\t\teval \"$cmd\" ;;\n-\t\tgood|bad|skip)\n+\t\t$NAME_GOOD|$NAME_BAD|skip)\n \t\t\tbisect_write \"$command\" \"$rev\" ;;\n \t\t*)\n \t\t\tdie \"$(gettext \"?? what are you talking about?\")\" ;;\n@@ -455,9 +460,9 @@ exit code \\$res from '\\$command' is < 0 or >= 128\" >&2\n \t\t\tstate='skip'\n \t\telif [ $res -gt 0 ]\n \t\tthen\n-\t\t\tstate='bad'\n+\t\t\tstate=\"$NAME_BAD\"\n \t\telse\n-\t\t\tstate='good'\n+\t\t\tstate=\"$NAME_GOOD\"\n \t\tfi\n \n \t\t# We have to use a subshell because \"bisect_state\" can exit.\n@@ -466,7 +471,7 @@ exit code \\$res from '\\$command' is < 0 or >= 128\" >&2\n \n \t\tcat \"$GIT_DIR/BISECT_RUN\"\n \n-\t\tif sane_grep \"first bad commit could be any of\" \"$GIT_DIR/BISECT_RUN\" \\\n+\t\tif sane_grep \"first $NAME_BAD commit could be any of\" \"$GIT_DIR/BISECT_RUN\" \\\n \t\t\t>/dev/null\n \t\tthen\n \t\t\tgettextln \"bisect run cannot continue any more\" >&2\n@@ -480,7 +485,7 @@ exit code \\$res from '\\$command' is < 0 or >= 128\" >&2\n \t\t\texit $res\n \t\tfi\n \n-\t\tif sane_grep \"is the first bad commit\" \"$GIT_DIR/BISECT_RUN\" >/dev/null\n+\t\tif sane_grep \"is the first $NAME_BAD commit\" \"$GIT_DIR/BISECT_RUN\" >/dev/null\n \t\tthen\n \t\t\tgettextln \"bisect run success\"\n \t\t\texit 0;\n-- \n1.7.1\n"},{"id":"264588","messageId":"1435006836-18182-3-git-send-email-antoine.delaite@ensimag.grenoble-inp.fr","threadId":"39695","inReplyTo":"1435006836-18182-1-git-send-email-antoine.delaite@ensimag.grenoble-inp.fr","subject":"[PATCH v3 3/6] bisect: simplify the addition of new bisect terms","fromName":"Antoine Delaite","fromEmail":"antoine.delaite@ensimag.grenoble-inp.fr","sentAt":"2015-06-22T21:00:33Z","receivedAt":"2015-06-22T21:00:33Z","isPatch":true,"sender":{"key":"antoine.delaite@ensimag.grenoble-inp.fr","avatar":"https://avatars.githubusercontent.com/u/12510393?v=4"},"body":"We create a file BISECT_TERMS in the repository .git to be read during a\nbisection. The fonctions to be changed if we add new terms are quite\nfew.\nIn git-bisect.sh :\n\tcheck_and_set_terms\n\tbisect_voc\n\nSigned-off-by: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\nSigned-off-by: Louis Stuber <stuberl@ensimag.grenoble-inp.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\n---\n bisect.c      |   38 ++++++++++++++++++++++++++++--\n git-bisect.sh |   70 +++++++++++++++++++++++++++++++++++++++++++++++++++-----\n 2 files changed, 98 insertions(+), 10 deletions(-)\n\ndiff --git a/bisect.c b/bisect.c\nindex cda30fa..2fc8a78 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -747,7 +747,10 @@ static void handle_bad_merge_base(void)\n \t\t\t\t\"between %s and [%s].\\n\",\n \t\t\t\tbad_hex, bad_hex, good_hex);\n \t\t} else {\n-\t\t\tdie(\"BUG: terms %s/%s not managed\", name_bad, name_good);\n+\t\t\tfprintf(stderr, \"The merge base %s is %s.\\n\"\n+\t\t\t\t\"This means the first commit marked %s is \"\n+\t\t\t\t\"between %s and [%s].\\n\",\n+\t\t\t\tbad_hex, name_bad, name_bad, bad_hex, good_hex);\n \t\t}\n \t\texit(3);\n \t}\n@@ -902,6 +905,36 @@ static void show_diff_tree(const char *prefix, struct commit *commit)\n }\n \n /*\n+ * The terms used for this bisect session are stored in BISECT_TERMS.\n+ * We read them and store them to adapt the messages accordingly.\n+ * Default is bad/good.\n+ */\n+void read_bisect_terms(const char **read_bad, const char **read_good)\n+{\n+\tstruct strbuf str = STRBUF_INIT;\n+\tconst char *filename = git_path(\"BISECT_TERMS\");\n+\tFILE *fp = fopen(filename, \"r\");\n+\n+\tif (!fp) {\n+\t\tif (errno==2) {\n+\t\t\t*read_bad = \"bad\";\n+\t\t\t*read_good = \"good\";\n+\t\t\treturn;\n+\t\t} else {\n+\t\t\tdie(\"could not read file '%s': %s\", filename,\n+\t\t\t\tstrerror(errno));\n+\t\t}\n+\t} else {\n+\t\tstrbuf_getline(&str, fp, '\\n');\n+\t\t*read_bad = strbuf_detach(&str, NULL);\n+\t\tstrbuf_getline(&str, fp, '\\n');\n+\t\t*read_good = strbuf_detach(&str, NULL);\n+\t}\n+\tstrbuf_release(&str);\n+\tfclose(fp);\n+}\n+\n+/*\n  * We use the convention that exiting with an exit code 10 means that\n  * the bisection process finished successfully.\n  * In this case the calling shell script should exit 0.\n@@ -917,8 +950,7 @@ int bisect_next_all(const char *prefix, int no_checkout)\n \tconst unsigned char *bisect_rev;\n \tchar bisect_rev_hex[GIT_SHA1_HEXSZ + 1];\n \n-\tname_bad=\"bad\";\n-\tname_good=\"good\";\n+\tread_bisect_terms(&name_bad, &name_good);\n \tif (read_bisect_refs())\n \t\tdie(\"reading bisect refs failed\");\n \ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex ce6412f..55b9ebd 100644\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -77,6 +77,9 @@ bisect_start() {\n \torig_args=$(git rev-parse --sq-quote \"$@\")\n \tbad_seen=0\n \teval=''\n+\t# revision_seen is true if a git bisect start\n+\t# has revision as arguments\n+\trevision_seen=0\n \tif test \"z$(git rev-parse --is-bare-repository)\" != zfalse\n \tthen\n \t\tmode=--no-checkout\n@@ -101,6 +104,9 @@ bisect_start() {\n \t\t\t\tdie \"$(eval_gettext \"'\\$arg' does not appear to be a valid revision\")\"\n \t\t\t\tbreak\n \t\t\t}\n+\n+\t\t\trevision_seen=1\n+\n \t\t\tcase $bad_seen in\n \t\t\t0) state=$NAME_BAD ; bad_seen=1 ;;\n \t\t\t*) state=$NAME_GOOD ;;\n@@ -172,6 +178,11 @@ bisect_start() {\n \t} &&\n \tgit rev-parse --sq-quote \"$@\" >\"$GIT_DIR/BISECT_NAMES\" &&\n \teval \"$eval true\" &&\n+\tif test $revision_seen -eq 1 && test ! -s \"$GIT_DIR/BISECT_TERMS\"\n+\tthen\n+\t\techo \"$NAME_BAD\" >\"$GIT_DIR/BISECT_TERMS\" &&\n+\t\techo \"$NAME_GOOD\" >>\"$GIT_DIR/BISECT_TERMS\"\n+\tfi &&\n \techo \"git bisect start$orig_args\" >>\"$GIT_DIR/BISECT_LOG\" || exit\n \t#\n \t# Check if we can proceed to the next bisect state.\n@@ -232,6 +243,7 @@ bisect_skip() {\n bisect_state() {\n \tbisect_autostart\n \tstate=$1\n+\tcheck_and_set_terms $state\n \tcase \"$#,$state\" in\n \t0,*)\n \t\tdie \"$(gettext \"Please call 'bisect_state' with at least one argument.\")\" ;;\n@@ -291,15 +303,17 @@ bisect_next_check() {\n \t\t: bisect without $NAME_GOOD...\n \t\t;;\n \t*)\n-\n+\t\tbad_syn=$(bisect_voc bad)\n+\t\tgood_syn=$(bisect_voc good)\n \t\tif test -s \"$GIT_DIR/BISECT_START\"\n \t\tthen\n-\t\t\tgettextln \"You need to give me at least one good and one bad revision.\n-(You can use \\\"git bisect bad\\\" and \\\"git bisect good\\\" for that.)\" >&2\n+\n+\t\t\teval_gettextln \"You need to give me at least one \\$bad_syn and one \\$good_syn revision.\n+(You can use \\\"git bisect \\$bad_syn\\\" and \\\"git bisect \\$good_syn\\\" for that.)\" >&2\n \t\telse\n-\t\t\tgettextln \"You need to start by \\\"git bisect start\\\".\n-You then need to give me at least one good and one bad revision.\n-(You can use \\\"git bisect bad\\\" and \\\"git bisect good\\\" for that.)\" >&2\n+\t\t\teval_gettextln \"You need to start by \\\"git bisect start\\\".\n+You then need to give me at least one \\$good_syn and one \\$bad_syn revision.\n+(You can use \\\"git bisect \\$bad_syn\\\" and \\\"git bisect \\$good_syn\\\" for that.)\" >&2\n \t\tfi\n \t\texit 1 ;;\n \tesac\n@@ -402,6 +416,7 @@ bisect_clean_state() {\n \trm -f \"$GIT_DIR/BISECT_LOG\" &&\n \trm -f \"$GIT_DIR/BISECT_NAMES\" &&\n \trm -f \"$GIT_DIR/BISECT_RUN\" &&\n+\trm -f \"$GIT_DIR/BISECT_TERMS\" &&\n \t# Cleanup head-name if it got left by an old version of git-bisect\n \trm -f \"$GIT_DIR/head-name\" &&\n \tgit update-ref -d --no-deref BISECT_HEAD &&\n@@ -422,11 +437,13 @@ bisect_replay () {\n \t\t\trev=\"$command\"\n \t\t\tcommand=\"$bisect\"\n \t\tfi\n+\t\tget_terms\n+\t\tcheck_and_set_terms \"$command\"\n \t\tcase \"$command\" in\n \t\tstart)\n \t\t\tcmd=\"bisect_start $rev\"\n \t\t\teval \"$cmd\" ;;\n-\t\t$NAME_GOOD|$NAME_BAD|skip)\n+\t\t\"$NAME_GOOD\"|\"$NAME_BAD\"|skip)\n \t\t\tbisect_write \"$command\" \"$rev\" ;;\n \t\t*)\n \t\t\tdie \"$(gettext \"?? what are you talking about?\")\" ;;\n@@ -499,11 +516,50 @@ bisect_log () {\n \tcat \"$GIT_DIR/BISECT_LOG\"\n }\n \n+get_terms () {\n+\tif test -s \"$GIT_DIR/BISECT_TERMS\"\n+\tthen\n+\t\t{\n+\t\tread NAME_BAD\n+\t\tread NAME_GOOD\n+\t\t}<\"$GIT_DIR/BISECT_TERMS\"\t\n+\tfi\n+}\n+\n+check_and_set_terms () {\n+\tcmd=\"$1\"\n+\tcase \"$cmd\" in\n+\tbad|good)\n+\t\tif test -s \"$GIT_DIR/BISECT_TERMS\" && test \"$cmd\" != \"$NAME_BAD\" && test \"$cmd\" != \"$NAME_GOOD\"\n+\t\tthen\n+\t\t\tdie \"$(eval_gettext \"Invalid command: you're currently in a \\$NAME_BAD/\\$NAME_GOOD bisect.\")\"\n+\t\tfi\n+\t\tcase \"$cmd\" in\n+\t\tbad|good)\n+\t\t\tif ! test -s \"$GIT_DIR/BISECT_TERMS\"\n+\t\t\tthen\n+\t\t\t\techo \"bad\" >\"$GIT_DIR/BISECT_TERMS\" &&\n+\t\t\t\techo \"good\" >>\"$GIT_DIR/BISECT_TERMS\"\n+\t\t\tfi\n+\t\t\tNAME_BAD=\"bad\"\n+\t\t\tNAME_GOOD=\"good\" ;;\n+\t\tesac ;;\n+\tesac\n+}\n+\n+bisect_voc () {\n+\tcase \"$1\" in\n+\tbad) echo \"bad\" ;;\n+\tgood) echo \"good\" ;;\n+\tesac\n+}\n+\n case \"$#\" in\n 0)\n \tusage ;;\n *)\n \tcmd=\"$1\"\n+\tget_terms\n \tshift\n \tcase \"$cmd\" in\n \thelp)\n-- \n1.7.1\n"},{"id":"264586","messageId":"1435006836-18182-4-git-send-email-antoine.delaite@ensimag.grenoble-inp.fr","threadId":"39695","inReplyTo":"1435006836-18182-1-git-send-email-antoine.delaite@ensimag.grenoble-inp.fr","subject":"[PATCH v3 4/6] bisect: add the terms old/new","fromName":"Antoine Delaite","fromEmail":"antoine.delaite@ensimag.grenoble-inp.fr","sentAt":"2015-06-22T21:00:34Z","receivedAt":"2015-06-22T21:00:34Z","isPatch":true,"sender":{"key":"antoine.delaite@ensimag.grenoble-inp.fr","avatar":"https://avatars.githubusercontent.com/u/12510393?v=4"},"body":"When not looking for a regression during a bisect but for a fix or a\nchange in another given property, it can be confusing to use 'good'\nand 'bad'.\n\nThis patch introduce `git bisect new` and `git bisect old` as an\nalternative to 'bad' and good': the commits which have a certain\nproperty must be marked as `new` and the ones which do not as `old`.\n\nThe output will be the first commit after the change in the property.\nDuring a new/old bisect session you cannot use bad/good commands and\nvice-versa.\n\nSome commands are still not available for old/new:\n     * git rev-list --bisect does not treat the revs/bisect/new and\n       revs/bisect/old-SHA1 files.\n\nOld discussions:\n\t- http://thread.gmane.org/gmane.comp.version-control.git/86063\n\t\tintroduced bisect fix unfixed to find fix.\n\t- http://thread.gmane.org/gmane.comp.version-control.git/182398\n\t\tdiscussion around bisect yes/no or old/new.\n\t- http://thread.gmane.org/gmane.comp.version-control.git/199758\n\t\tlast discussion and reviews\nNew discussions:\n\t- http://thread.gmane.org/gmane.comp.version-control.git/271320\n\t\t( v2 1/7-4/7 )\n\t- http://comments.gmane.org/gmane.comp.version-control.git/271343\n\t\t( v2 5/7-7/7 )\n\nSigned-off-by: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\nSigned-off-by: Louis Stuber <stuberl@ensimag.grenoble-inp.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\n---\n Documentation/git-bisect.txt |   48 ++++++++++++++++++++++++++++++++++++++++-\n bisect.c                     |   11 +++++++--\n git-bisect.sh                |   30 +++++++++++++++++--------\n t/t6030-bisect-porcelain.sh  |   38 +++++++++++++++++++++++++++++++++\n 4 files changed, 112 insertions(+), 15 deletions(-)\n\ndiff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt\nindex 4cb52a7..3c3021a 100644\n--- a/Documentation/git-bisect.txt\n+++ b/Documentation/git-bisect.txt\n@@ -18,8 +18,8 @@ on the subcommand:\n \n  git bisect help\n  git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<paths>...]\n- git bisect bad [<rev>]\n- git bisect good [<rev>...]\n+ git bisect (bad|new) [<rev>]\n+ git bisect (good|old) [<rev>...]\n  git bisect skip [(<rev>|<range>)...]\n  git bisect reset [<commit>]\n  git bisect visualize\n@@ -104,6 +104,35 @@ For example, `git bisect reset HEAD` will leave you on the current\n bisection commit and avoid switching commits at all, while `git bisect\n reset bisect/bad` will check out the first bad revision.\n \n+\n+Alternative terms: bisect new and bisect old\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+If you are not at ease with the terms \"bad\" and \"good\", perhaps\n+because you are looking for the commit that introduced a fix, you can\n+alternatively use \"new\" and \"old\" instead.\n+But note that you cannot mix \"bad\" and good\" with \"new\" and \"old\".\n+\n+------------------------------------------------\n+git bisect new [<rev>]\n+------------------------------------------------\n+\n+Marks the commit as new, e.g. \"the bug is no longer there\", if you are looking\n+for a commit that fixed a bug, or \"the feature that used to work is now broken\n+at this point\", if you are looking for a commit that introduced a bug.\n+It is the equivalent of \"git bisect bad [<rev>]\".\n+\n+------------------------------------------------\n+git bisect old [<rev>...]\n+------------------------------------------------\n+\n+Marks the commit as old, as the opposite of 'git bisect new'.\n+It is the equivalent of \"git bisect good [<rev>...]\".\n+\n+You must run `git bisect start` without commits as argument and run\n+`git bisect new <rev>`/`git bisect old <rev>...` after to add the\n+commits.\n+\n Bisect visualize\n ~~~~~~~~~~~~~~~~\n \n@@ -379,6 +408,21 @@ In this case, when 'git bisect run' finishes, bisect/bad will refer to a commit\n has at least one parent whose reachable graph is fully traversable in the sense\n required by 'git pack objects'.\n \n+* Look for a fix instead of a regression in the code\n++\n+------------\n+$ git bisect start\n+$ git bisect new HEAD    # current commit is marked as new\n+$ git bisect old HEAD~10 # the tenth commit from now is marked as old\n+------------\n++\n+Let's consider the last commit has a given property, and that we are looking\n+for the commit which introduced this property. For each commit the bisection\n+guide us to, we will test if the property is present. If it is we will mark\n+the commit as new with 'git bisect new', otherwise we will mark it as old.\n+At the end of the bisect session, the result will be the first new commit (e.g\n+the first one with the property).\n+\n \n SEE ALSO\n --------\ndiff --git a/bisect.c b/bisect.c\nindex 2fc8a78..7492fdc 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -746,6 +746,11 @@ static void handle_bad_merge_base(void)\n \t\t\t\t\"This means the bug has been fixed \"\n \t\t\t\t\"between %s and [%s].\\n\",\n \t\t\t\tbad_hex, bad_hex, good_hex);\n+\t\t} else if (!strcmp(name_bad, \"new\")) {\n+\t\t\tfprintf(stderr, \"The merge base %s is new.\\n\"\n+\t\t\t\t\"The property has changed \"\n+\t\t\t\t\"between %s and [%s].\\n\",\n+\t\t\t\tbad_hex, bad_hex, good_hex);\n \t\t} else {\n \t\t\tfprintf(stderr, \"The merge base %s is %s.\\n\"\n \t\t\t\t\"This means the first commit marked %s is \"\n@@ -778,11 +783,11 @@ static void handle_skipped_merge_base(const unsigned char *mb)\n }\n \n /*\n- * \"check_merge_bases\" checks that merge bases are not \"bad\".\n+ * \"check_merge_bases\" checks that merge bases are not \"bad\" (or \"new\").\n  *\n- * - If one is \"bad\", it means the user assumed something wrong\n+ * - If one is \"bad\" (or \"new\"), it means the user assumed something wrong\n  * and we must exit with a non 0 error code.\n- * - If one is \"good\", that's good, we have nothing to do.\n+ * - If one is \"good\" (or \"old\"), that's good, we have nothing to do.\n  * - If one is \"skipped\", we can't know but we should warn.\n  * - If we don't know, we should check it out and ask the user to test.\n  */\ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex 55b9ebd..a11ca06 100644\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -1,14 +1,16 @@\n #!/bin/sh\n \n-USAGE='[help|start|bad|good|skip|next|reset|visualize|replay|log|run]'\n+USAGE='[help|start|bad|good|new|old|skip|next|reset|visualize|replay|log|run]'\n LONG_USAGE='git bisect help\n \tprint this long help message.\n git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<pathspec>...]\n \treset bisect state and start bisection.\n-git bisect bad [<rev>]\n-\tmark <rev> a known-bad revision.\n-git bisect good [<rev>...]\n-\tmark <rev>... known-good revisions.\n+git bisect (bad|new) [<rev>]\n+\tmark <rev> a known-bad revision/\n+\t\ta revision after change in a given property.\n+git bisect (good|old) [<rev>...]\n+\tmark <rev>... known-good revisions/\n+\t\trevisions before change in a given property.\n git bisect skip [(<rev>|<range>)...]\n \tmark <rev>... untestable revisions.\n git bisect next\n@@ -288,7 +290,7 @@ bisect_next_check() {\n \t\tfalse\n \t\t;;\n \tt,,\"$NAME_GOOD\")\n-\t\t# have bad but not good.  we could bisect although\n+\t\t# have bad (or new) but not good (or old).  we could bisect although\n \t\t# this is less optimum.\n \t\teval_gettextln \"Warning: bisecting only with a \\$NAME_BAD commit.\" >&2\n \t\tif test -t 0\n@@ -529,7 +531,7 @@ get_terms () {\n check_and_set_terms () {\n \tcmd=\"$1\"\n \tcase \"$cmd\" in\n-\tbad|good)\n+\tbad|good|new|old)\n \t\tif test -s \"$GIT_DIR/BISECT_TERMS\" && test \"$cmd\" != \"$NAME_BAD\" && test \"$cmd\" != \"$NAME_GOOD\"\n \t\tthen\n \t\t\tdie \"$(eval_gettext \"Invalid command: you're currently in a \\$NAME_BAD/\\$NAME_GOOD bisect.\")\"\n@@ -543,14 +545,22 @@ check_and_set_terms () {\n \t\t\tfi\n \t\t\tNAME_BAD=\"bad\"\n \t\t\tNAME_GOOD=\"good\" ;;\n+\t\tnew|old)\n+\t\t\tif ! test -s \"$GIT_DIR/BISECT_TERMS\"\n+\t\t\tthen\n+\t\t\t\techo \"new\" >\"$GIT_DIR/BISECT_TERMS\" &&\n+\t\t\t\techo \"old\" >>\"$GIT_DIR/BISECT_TERMS\"\n+\t\t\tfi\n+\t\t\tNAME_BAD=\"new\"\n+\t\t\tNAME_GOOD=\"old\" ;;\n \t\tesac ;;\n \tesac\n }\n \n bisect_voc () {\n \tcase \"$1\" in\n-\tbad) echo \"bad\" ;;\n-\tgood) echo \"good\" ;;\n+\tbad) echo \"bad|old\" ;;\n+\tgood) echo \"good|new\" ;;\n \tesac\n }\n \n@@ -566,7 +576,7 @@ case \"$#\" in\n \t\tgit bisect -h ;;\n \tstart)\n \t\tbisect_start \"$@\" ;;\n-\tbad|good)\n+\tbad|good|new|old)\n \t\tbisect_state \"$cmd\" \"$@\" ;;\n \tskip)\n \t\tbisect_skip \"$@\" ;;\ndiff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh\nindex 9e2c203..2f2143b 100755\n--- a/t/t6030-bisect-porcelain.sh\n+++ b/t/t6030-bisect-porcelain.sh\n@@ -759,4 +759,42 @@ test_expect_success '\"git bisect bad HEAD\" behaves as \"git bisect bad\"' '\n \tgit bisect reset\n '\n \n+test_expect_success 'bisect starts with only one new' '\n+\tgit bisect reset &&\n+\tgit bisect start &&\n+\tgit bisect new $HASH4 &&\n+\tgit bisect next\n+'\n+\n+test_expect_success 'bisect does not start with only one old' '\n+\tgit bisect reset &&\n+\tgit bisect start &&\n+\tgit bisect old $HASH1 &&\n+\ttest_must_fail git bisect next\n+'\n+\n+test_expect_success 'bisect start with one new and old' '\n+\tgit bisect reset &&\n+\tgit bisect start &&\n+\tgit bisect old $HASH1 &&\n+\tgit bisect new $HASH4 &&\n+\tgit bisect new &&\n+\tgit bisect new >bisect_result &&\n+\tgrep \"$HASH2 is the first new commit\" bisect_result &&\n+\tgit bisect log > log_to_replay.txt &&\n+\tgit bisect reset\n+'\n+\n+test_expect_success 'bisect replay with old and new' '\n+\tgit bisect replay log_to_replay.txt > bisect_result &&\n+\tgrep \"$HASH2 is the first new commit\" bisect_result &&\n+\tgit bisect reset\n+'\n+\n+test_expect_success 'bisect cannot mix old/new and good/bad' '\n+\tgit bisect start &&\n+\tgit bisect bad $HASH4 &&\n+\ttest_must_fail git bisect old $HASH1\n+'\n+\n test_done\n-- \n1.7.1\n"},{"id":"264584","messageId":"1435006836-18182-5-git-send-email-antoine.delaite@ensimag.grenoble-inp.fr","threadId":"39695","inReplyTo":"1435006836-18182-1-git-send-email-antoine.delaite@ensimag.grenoble-inp.fr","subject":"[PATCH v3 5/6] revision: fix rev-list --bisect in old/new mode","fromName":"Antoine Delaite","fromEmail":"antoine.delaite@ensimag.grenoble-inp.fr","sentAt":"2015-06-22T21:00:35Z","receivedAt":"2015-06-22T21:00:35Z","isPatch":true,"sender":{"key":"antoine.delaite@ensimag.grenoble-inp.fr","avatar":"https://avatars.githubusercontent.com/u/12510393?v=4"},"body":"From: Louis Stuber <stuberl@ensimag.grenoble-inp.fr>\n\nCalling git rev-list --bisect when an old/new mode bisection was started\nshows the help notice. This has been fixed by reading BISECT_TERMS in\nrevision.c to find the correct bisect refs path (which was always\nrefs/bisect/bad (or good) before and can be refs/bisect/new (old) now).\n\nSigned-off-by: Louis Stuber <stuberl@ensimag.grenoble-inp.fr>\nSigned-off-by: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\n---\n revision.c |   16 ++++++++++++++--\n 1 files changed, 14 insertions(+), 2 deletions(-)\n\ndiff --git a/revision.c b/revision.c\nindex 3ff8723..27750ac 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -21,6 +21,9 @@\n \n volatile show_early_output_fn_t show_early_output;\n \n+static const char *name_bad;\n+static const char *name_good;\n+\n char *path_name(const struct name_path *path, const char *name)\n {\n \tconst struct name_path *p;\n@@ -2076,14 +2079,22 @@ void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx,\n \tctx->argc -= n;\n }\n \n+extern void read_bisect_terms(const char **bad, const char **good);\n+\n static int for_each_bad_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data)\n {\n-\treturn for_each_ref_in_submodule(submodule, \"refs/bisect/bad\", fn, cb_data);\n+\tchar bisect_refs_path[256];\n+\tstrcpy(bisect_refs_path, \"refs/bisect/\");\n+\tstrcat(bisect_refs_path, name_bad);\n+\treturn for_each_ref_in_submodule(submodule, bisect_refs_path, fn, cb_data);\n }\n \n static int for_each_good_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data)\n {\n-\treturn for_each_ref_in_submodule(submodule, \"refs/bisect/good\", fn, cb_data);\n+\tchar bisect_refs_path[256];\n+\tstrcpy(bisect_refs_path, \"refs/bisect/\");\n+\tstrcat(bisect_refs_path, name_good);\n+\treturn for_each_ref_in_submodule(submodule, bisect_refs_path, fn, cb_data);\n }\n \n static int handle_revision_pseudo_opt(const char *submodule,\n@@ -2112,6 +2123,7 @@ static int handle_revision_pseudo_opt(const char *submodule,\n \t\thandle_refs(submodule, revs, *flags, for_each_branch_ref_submodule);\n \t\tclear_ref_exclusion(&revs->ref_excludes);\n \t} else if (!strcmp(arg, \"--bisect\")) {\n+\t\tread_bisect_terms(&name_bad, &name_good);\n \t\thandle_refs(submodule, revs, *flags, for_each_bad_bisect_ref);\n \t\thandle_refs(submodule, revs, *flags ^ (UNINTERESTING | BOTTOM), for_each_good_bisect_ref);\n \t\trevs->bisect = 1;\n-- \n1.7.1\n"},{"id":"264583","messageId":"1435006836-18182-6-git-send-email-antoine.delaite@ensimag.grenoble-inp.fr","threadId":"39695","inReplyTo":"1435006836-18182-1-git-send-email-antoine.delaite@ensimag.grenoble-inp.fr","subject":"[PATCH v3 6/6] bisect: allows any terms set by user","fromName":"Antoine Delaite","fromEmail":"antoine.delaite@ensimag.grenoble-inp.fr","sentAt":"2015-06-22T21:00:36Z","receivedAt":"2015-06-22T21:00:36Z","isPatch":true,"sender":{"key":"antoine.delaite@ensimag.grenoble-inp.fr","avatar":"https://avatars.githubusercontent.com/u/12510393?v=4"},"body":"Introduction of the git bisect terms function.\nThe user can set its own terms.\nIt will work exactly like before. The terms must be set\nbefore the start.\n\nSigned-off-by: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\nSigned-off-by: Louis Stuber <stuberl@ensimag.grenoble-inp.fr>\n---\n Documentation/git-bisect.txt |   19 ++++++++++++\n git-bisect.sh                |   68 ++++++++++++++++++++++++++++++++++++++---\n t/t6030-bisect-porcelain.sh  |   43 ++++++++++++++++++++++++++\n 3 files changed, 125 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt\nindex 3c3021a..ef0c03c 100644\n--- a/Documentation/git-bisect.txt\n+++ b/Documentation/git-bisect.txt\n@@ -133,6 +133,25 @@ You must run `git bisect start` without commits as argument and run\n `git bisect new <rev>`/`git bisect old <rev>...` after to add the\n commits.\n \n+Alternative terms: use your own terms\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+If the builtins terms bad/good and new/old do not satisfy you, you can\n+set your own terms.\n+\n+------------------------------------------------\n+git bisect terms term1 term2\n+------------------------------------------------\n+\n+This command has to be used before a bisection has started.\n+The term1 must be associated with the latest revisions and term2 with the\n+ancestors of term1.\n+\n+Only the first bisection following the 'git bisect terms' will use the terms.\n+If you mistyped one of the terms you can do again 'git bisect terms term1\n+term2'.\n+\n+\n Bisect visualize\n ~~~~~~~~~~~~~~~~\n \ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex a11ca06..7da22b1 100644\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -1,6 +1,6 @@\n #!/bin/sh\n \n-USAGE='[help|start|bad|good|new|old|skip|next|reset|visualize|replay|log|run]'\n+USAGE='[help|start|bad|good|new|old|terms|skip|next|reset|visualize|replay|log|run]'\n LONG_USAGE='git bisect help\n \tprint this long help message.\n git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<pathspec>...]\n@@ -11,6 +11,8 @@ git bisect (bad|new) [<rev>]\n git bisect (good|old) [<rev>...]\n \tmark <rev>... known-good revisions/\n \t\trevisions before change in a given property.\n+git bisect terms term1 term2\n+\tset up term1 and term2 as bisection terms.\n git bisect skip [(<rev>|<range>)...]\n \tmark <rev>... untestable revisions.\n git bisect next\n@@ -82,6 +84,14 @@ bisect_start() {\n \t# revision_seen is true if a git bisect start\n \t# has revision as arguments\n \trevision_seen=0\n+\t# terms_defined is used to detect if the user\n+\t# defined his own terms with git bisect terms\n+\tterms_defined=0\n+\tif test -s \"$GIT_DIR/TERMS_DEFINED\"\n+\tthen\n+\t\tterms_defined=1\n+\t\tget_terms\n+\tfi\n \tif test \"z$(git rev-parse --is-bare-repository)\" != zfalse\n \tthen\n \t\tmode=--no-checkout\n@@ -180,10 +190,14 @@ bisect_start() {\n \t} &&\n \tgit rev-parse --sq-quote \"$@\" >\"$GIT_DIR/BISECT_NAMES\" &&\n \teval \"$eval true\" &&\n-\tif test $revision_seen -eq 1 && test ! -s \"$GIT_DIR/BISECT_TERMS\"\n+\tif test $revision_seen -eq 1 && test ! -s \"$GIT_DIR/BISECT_TERMS\" || test $terms_defined -eq 1\n \tthen\n \t\techo \"$NAME_BAD\" >\"$GIT_DIR/BISECT_TERMS\" &&\n-\t\techo \"$NAME_GOOD\" >>\"$GIT_DIR/BISECT_TERMS\"\n+\t\techo \"$NAME_GOOD\" >>\"$GIT_DIR/BISECT_TERMS\" &&\n+\t\tif test $terms_defined -eq 1\n+\t\tthen\n+\t\t\techo \"git bisect terms $NAME_BAD $NAME_GOOD\" >>\"$GIT_DIR/BISECT_LOG\" || exit\n+\t\tfi\n \tfi &&\n \techo \"git bisect start$orig_args\" >>\"$GIT_DIR/BISECT_LOG\" || exit\n \t#\n@@ -419,6 +433,7 @@ bisect_clean_state() {\n \trm -f \"$GIT_DIR/BISECT_NAMES\" &&\n \trm -f \"$GIT_DIR/BISECT_RUN\" &&\n \trm -f \"$GIT_DIR/BISECT_TERMS\" &&\n+\trm -f \"$GIT_DIR/TERMS_DEFINED\" &&\n \t# Cleanup head-name if it got left by an old version of git-bisect\n \trm -f \"$GIT_DIR/head-name\" &&\n \tgit update-ref -d --no-deref BISECT_HEAD &&\n@@ -447,6 +462,8 @@ bisect_replay () {\n \t\t\teval \"$cmd\" ;;\n \t\t\"$NAME_GOOD\"|\"$NAME_BAD\"|skip)\n \t\t\tbisect_write \"$command\" \"$rev\" ;;\n+\t\tterms)\n+\t\t\tbisect_terms $rev ;;\n \t\t*)\n \t\t\tdie \"$(gettext \"?? what are you talking about?\")\" ;;\n \t\tesac\n@@ -531,7 +548,8 @@ get_terms () {\n check_and_set_terms () {\n \tcmd=\"$1\"\n \tcase \"$cmd\" in\n-\tbad|good|new|old)\n+\tskip|start|terms) ;;\n+\t*)\n \t\tif test -s \"$GIT_DIR/BISECT_TERMS\" && test \"$cmd\" != \"$NAME_BAD\" && test \"$cmd\" != \"$NAME_GOOD\"\n \t\tthen\n \t\t\tdie \"$(eval_gettext \"Invalid command: you're currently in a \\$NAME_BAD/\\$NAME_GOOD bisect.\")\"\n@@ -564,6 +582,44 @@ bisect_voc () {\n \tesac\n }\n \n+bisect_terms () {\n+\tcase \"$#\" in\n+\t0)\n+\t\tif test -s \"$GIT_DIR/BISECT_TERMS\"\n+\t\tthen\n+\t\t\t{\n+\t\t\tread term1\n+\t\t\tread term2\n+\t\t\t}<\"$GIT_DIR/BISECT_TERMS\"\n+\t\t\tgettextln \"Your current terms are $term1 and $term2.\"\n+\t\telse\n+\t\t\tdie \"$(gettext \"No terms defined.\")\"\n+\t\tfi ;;\n+\t2)\n+\t\tcheck_term_format refs/bisect/\"$1\"\n+\t\tcheck_term_format refs/bisect/\"$2\"\n+\t\tif ! test -s \"$GIT_DIR/BISECT_START\"\n+\t\tthen\n+\t\t\techo $1 >\"$GIT_DIR/BISECT_TERMS\" &&\n+\t\t\techo $2 >>\"$GIT_DIR/BISECT_TERMS\" &&\n+\t\t\techo \"1\" >\"$GIT_DIR/TERMS_DEFINED\"\n+\t\t\techo \"git bisect terms $NAME_BAD $NAME_GOOD\" >>\"$GIT_DIR/BISECT_LOG\" || exit\n+\t\telse\n+\t\t\tdie \"$(gettext \"A bisection has already started, and you can't change terms in the middle of it. \n+Use 'git bisect terms' to see the current terms. \n+Otherwise, to start a new bisection with new terms, please use 'git bisect reset' and set the terms before the start\")\"\n+\t\tfi ;;\n+\t*)\n+\t\tusage ;;\n+\tesac\n+}\n+\n+check_term_format () {\n+\targ=\"$1\"\n+\tgit check-ref-format $arg ||\n+\tdie \"$(eval_gettext \"'\\$arg' is not a valid term\")\"\n+}\n+\n case \"$#\" in\n 0)\n \tusage ;;\n@@ -576,7 +632,7 @@ case \"$#\" in\n \t\tgit bisect -h ;;\n \tstart)\n \t\tbisect_start \"$@\" ;;\n-\tbad|good|new|old)\n+\tbad|good|new|old|\"$NAME_BAD\"|\"$NAME_GOOD\")\n \t\tbisect_state \"$cmd\" \"$@\" ;;\n \tskip)\n \t\tbisect_skip \"$@\" ;;\n@@ -593,6 +649,8 @@ case \"$#\" in\n \t\tbisect_log ;;\n \trun)\n \t\tbisect_run \"$@\" ;;\n+\tterms)\n+\t\tbisect_terms \"$@\" ;;\n \t*)\n \t\tusage ;;\n \tesac\ndiff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh\nindex 2f2143b..d91116e 100755\n--- a/t/t6030-bisect-porcelain.sh\n+++ b/t/t6030-bisect-porcelain.sh\n@@ -797,4 +797,47 @@ test_expect_success 'bisect cannot mix old/new and good/bad' '\n \ttest_must_fail git bisect old $HASH1\n '\n \n+test_expect_success 'bisect start with one term1 and term2' '\n+\tgit bisect reset &&\n+\tgit bisect terms term1 term2 &&\n+\tgit bisect start &&\n+\tgit bisect term2 $HASH1 &&\n+\tgit bisect term1 $HASH4 &&\n+\tgit bisect term1 &&\n+\tgit bisect term1 >bisect_result &&\n+\tgrep \"$HASH2 is the first term1 commit\" bisect_result &&\n+\tgit bisect log > log_to_replay.txt &&\n+\tgit bisect reset\n+'\n+\n+test_expect_success 'bisect replay with term1 and term2' '\n+\tgit bisect replay log_to_replay.txt > bisect_result &&\n+\tgrep \"$HASH2 is the first term1 commit\" bisect_result &&\n+\tgit bisect reset\n+'\n+\n+test_expect_success 'bisect start term1 term2' '\n+\tgit bisect reset &&\n+\tgit bisect terms term1 term2 &&\n+\tgit bisect start $HASH4 $HASH1 &&\n+\tgit bisect term1 &&\n+\tgit bisect term1 >bisect_result &&\n+\tgrep \"$HASH2 is the first term1 commit\" bisect_result &&\n+\tgit bisect log > log_to_replay.txt &&\n+\tgit bisect reset\n+'\n+\n+test_expect_success 'bisect cannot mix terms' '\n+\tgit bisect reset &&\n+\tgit bisect terms a b &&\n+\tgit bisect terms term1 term2 &&\n+\tgit bisect start $HASH4 $HASH1 &&\n+\ttest_must_fail git bisect a &&\n+\ttest_must_fail git bisect b &&\n+\ttest_must_fail git bisect bad &&\n+\ttest_must_fail git bisect good &&\n+\ttest_must_fail git bisect new &&\n+\ttest_must_fail git bisect old\n+'\n+\n test_done\n-- \n1.7.1\n"},{"id":"264638","messageId":"1435064084-5554-1-git-send-email-Matthieu.Moy@imag.fr","threadId":"39695","inReplyTo":"1435006836-18182-1-git-send-email-antoine.delaite@ensimag.grenoble-inp.fr","subject":"[PATCH v7 0/5] git bisect old/new","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-23T12:54:39Z","receivedAt":"2015-06-23T12:54:39Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"Hi,\n\nI fixed a few minor issues in v6. Patch between my version and v6 is\nbelow. I also pushed my branch here:\n\n  https://github.com/moy/git/tree/bisect-terms\n\nNot visible in the patch below: I squashed PATCH 5 into PATCH 3 to\navoid the pattern \"break stuff and then repair it\".\n\nThe first two patches seem ready.\n\nPATCH 4 (add old/new) is still buggy. When starting a bisection with\n\n  git bisect start $old $new\n\nthe command \"git bisect visualize\" does not work (it shows no commit).\n\nI consider PATCH 5 as WIP, I think it would need a lot of polishing\nand testing to be mergeable. I think a reasonable objective for now it\nto get old/new working in the user-interface, and drop PATCH 5 from\nthe series when it gets merged. The existance of PATCH 5 is a very\ngood thing even if it doesn't get merged:\n\n* The fact that it's possible to do it on top of the series shows that\n  we make the code more generic. I think it's important that\n  regardless of features, the code moves in the right direction.\n\n* The patch can be taken over later by someone else.\n\ndiff --git a/bisect.c b/bisect.c\nindex 7492fdc..ab09650 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -921,7 +921,7 @@ void read_bisect_terms(const char **read_bad, const char **read_good)\n \tFILE *fp = fopen(filename, \"r\");\n \n \tif (!fp) {\n-\t\tif (errno==2) {\n+\t\tif (errno == ENOENT) {\n \t\t\t*read_bad = \"bad\";\n \t\t\t*read_good = \"good\";\n \t\t\treturn;\ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex 7da22b1..8ef2b94 100644\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -541,7 +541,7 @@ get_terms () {\n \t\t{\n \t\tread NAME_BAD\n \t\tread NAME_GOOD\n-\t\t}<\"$GIT_DIR/BISECT_TERMS\"\t\n+\t\t} <\"$GIT_DIR/BISECT_TERMS\"\n \tfi\n }\n \n@@ -605,8 +605,8 @@ bisect_terms () {\n \t\t\techo \"1\" >\"$GIT_DIR/TERMS_DEFINED\"\n \t\t\techo \"git bisect terms $NAME_BAD $NAME_GOOD\" >>\"$GIT_DIR/BISECT_LOG\" || exit\n \t\telse\n-\t\t\tdie \"$(gettext \"A bisection has already started, and you can't change terms in the middle of it. \n-Use 'git bisect terms' to see the current terms. \n+\t\t\tdie \"$(gettext \"A bisection has already started, and you can't change terms in the middle of it.\n+Use 'git bisect terms' to see the current terms.\n Otherwise, to start a new bisection with new terms, please use 'git bisect reset' and set the terms before the start\")\"\n \t\tfi ;;\n \t*)\ndiff --git a/revision.c b/revision.c\nindex 27750ac..f22923f 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -2083,18 +2083,28 @@ extern void read_bisect_terms(const char **bad, const char **good);\n \n static int for_each_bad_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data)\n {\n-\tchar bisect_refs_path[256];\n-\tstrcpy(bisect_refs_path, \"refs/bisect/\");\n-\tstrcat(bisect_refs_path, name_bad);\n-\treturn for_each_ref_in_submodule(submodule, bisect_refs_path, fn, cb_data);\n+\tstruct strbuf bisect_refs_buf = STRBUF_INIT;\n+\tconst char *bisect_refs_str;\n+\tint status;\n+\tstrbuf_addstr(&bisect_refs_buf, \"refs/bisect/\");\n+\tstrbuf_addstr(&bisect_refs_buf, name_bad);\n+\tbisect_refs_str = strbuf_detach(&bisect_refs_buf, NULL);\n+\tstatus = for_each_ref_in_submodule(submodule, bisect_refs_str, fn, cb_data);\n+\tfree((char *)bisect_refs_str);\n+\treturn status;\n }\n \n static int for_each_good_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data)\n {\n-\tchar bisect_refs_path[256];\n-\tstrcpy(bisect_refs_path, \"refs/bisect/\");\n-\tstrcat(bisect_refs_path, name_good);\n-\treturn for_each_ref_in_submodule(submodule, bisect_refs_path, fn, cb_data);\n+\tstruct strbuf bisect_refs_buf = STRBUF_INIT;\n+\tconst char *bisect_refs_str;\n+\tint status;\n+\tstrbuf_addstr(&bisect_refs_buf, \"refs/bisect/\");\n+\tstrbuf_addstr(&bisect_refs_buf, name_bad);\n+\tbisect_refs_str = strbuf_detach(&bisect_refs_buf, NULL);\n+\tstatus = for_each_ref_in_submodule(submodule, bisect_refs_str, fn, cb_data);\n+\tfree((char *)bisect_refs_str);\n+\treturn status;\n }\n \n static int handle_revision_pseudo_opt(const char *submodule,\ndiff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh\nindex d91116e..289dbb0 100755\n--- a/t/t6030-bisect-porcelain.sh\n+++ b/t/t6030-bisect-porcelain.sh\n@@ -781,12 +781,12 @@ test_expect_success 'bisect start with one new and old' '\n \tgit bisect new &&\n \tgit bisect new >bisect_result &&\n \tgrep \"$HASH2 is the first new commit\" bisect_result &&\n-\tgit bisect log > log_to_replay.txt &&\n+\tgit bisect log >log_to_replay.txt &&\n \tgit bisect reset\n '\n \n test_expect_success 'bisect replay with old and new' '\n-\tgit bisect replay log_to_replay.txt > bisect_result &&\n+\tgit bisect replay log_to_replay.txt >bisect_result &&\n \tgrep \"$HASH2 is the first new commit\" bisect_result &&\n \tgit bisect reset\n '\n@@ -806,12 +806,12 @@ test_expect_success 'bisect start with one term1 and term2' '\n \tgit bisect term1 &&\n \tgit bisect term1 >bisect_result &&\n \tgrep \"$HASH2 is the first term1 commit\" bisect_result &&\n-\tgit bisect log > log_to_replay.txt &&\n+\tgit bisect log >log_to_replay.txt &&\n \tgit bisect reset\n '\n \n test_expect_success 'bisect replay with term1 and term2' '\n-\tgit bisect replay log_to_replay.txt > bisect_result &&\n+\tgit bisect replay log_to_replay.txt >bisect_result &&\n \tgrep \"$HASH2 is the first term1 commit\" bisect_result &&\n \tgit bisect reset\n '\n@@ -823,7 +823,7 @@ test_expect_success 'bisect start term1 term2' '\n \tgit bisect term1 &&\n \tgit bisect term1 >bisect_result &&\n \tgrep \"$HASH2 is the first term1 commit\" bisect_result &&\n-\tgit bisect log > log_to_replay.txt &&\n+\tgit bisect log >log_to_replay.txt &&\n \tgit bisect reset\n '\n \n\nSubject: [PATCH v7 0/5] git bisect old/new\n\nHi,\n\nI fixed a few minor issues in v6. Patch between my version and v6 is\nbelow. I also pushed my branch here:\n\n  https://github.com/moy/git/tree/bisect-terms\n\ndiff --git a/bisect.c b/bisect.c\nindex 7492fdc..ab09650 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -921,7 +921,7 @@ void read_bisect_terms(const char **read_bad, const char **read_good)\n \tFILE *fp = fopen(filename, \"r\");\n \n \tif (!fp) {\n-\t\tif (errno==2) {\n+\t\tif (errno == ENOENT) {\n \t\t\t*read_bad = \"bad\";\n \t\t\t*read_good = \"good\";\n \t\t\treturn;\ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex 7da22b1..8ef2b94 100644\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -541,7 +541,7 @@ get_terms () {\n \t\t{\n \t\tread NAME_BAD\n \t\tread NAME_GOOD\n-\t\t}<\"$GIT_DIR/BISECT_TERMS\"\t\n+\t\t} <\"$GIT_DIR/BISECT_TERMS\"\n \tfi\n }\n \n@@ -605,8 +605,8 @@ bisect_terms () {\n \t\t\techo \"1\" >\"$GIT_DIR/TERMS_DEFINED\"\n \t\t\techo \"git bisect terms $NAME_BAD $NAME_GOOD\" >>\"$GIT_DIR/BISECT_LOG\" || exit\n \t\telse\n-\t\t\tdie \"$(gettext \"A bisection has already started, and you can't change terms in the middle of it. \n-Use 'git bisect terms' to see the current terms. \n+\t\t\tdie \"$(gettext \"A bisection has already started, and you can't change terms in the middle of it.\n+Use 'git bisect terms' to see the current terms.\n Otherwise, to start a new bisection with new terms, please use 'git bisect reset' and set the terms before the start\")\"\n \t\tfi ;;\n \t*)\ndiff --git a/revision.c b/revision.c\nindex 27750ac..f22923f 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -2083,18 +2083,28 @@ extern void read_bisect_terms(const char **bad, const char **good);\n \n static int for_each_bad_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data)\n {\n-\tchar bisect_refs_path[256];\n-\tstrcpy(bisect_refs_path, \"refs/bisect/\");\n-\tstrcat(bisect_refs_path, name_bad);\n-\treturn for_each_ref_in_submodule(submodule, bisect_refs_path, fn, cb_data);\n+\tstruct strbuf bisect_refs_buf = STRBUF_INIT;\n+\tconst char *bisect_refs_str;\n+\tint status;\n+\tstrbuf_addstr(&bisect_refs_buf, \"refs/bisect/\");\n+\tstrbuf_addstr(&bisect_refs_buf, name_bad);\n+\tbisect_refs_str = strbuf_detach(&bisect_refs_buf, NULL);\n+\tstatus = for_each_ref_in_submodule(submodule, bisect_refs_str, fn, cb_data);\n+\tfree((char *)bisect_refs_str);\n+\treturn status;\n }\n \n static int for_each_good_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data)\n {\n-\tchar bisect_refs_path[256];\n-\tstrcpy(bisect_refs_path, \"refs/bisect/\");\n-\tstrcat(bisect_refs_path, name_good);\n-\treturn for_each_ref_in_submodule(submodule, bisect_refs_path, fn, cb_data);\n+\tstruct strbuf bisect_refs_buf = STRBUF_INIT;\n+\tconst char *bisect_refs_str;\n+\tint status;\n+\tstrbuf_addstr(&bisect_refs_buf, \"refs/bisect/\");\n+\tstrbuf_addstr(&bisect_refs_buf, name_bad);\n+\tbisect_refs_str = strbuf_detach(&bisect_refs_buf, NULL);\n+\tstatus = for_each_ref_in_submodule(submodule, bisect_refs_str, fn, cb_data);\n+\tfree((char *)bisect_refs_str);\n+\treturn status;\n }\n \n static int handle_revision_pseudo_opt(const char *submodule,\ndiff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh\nindex d91116e..289dbb0 100755\n--- a/t/t6030-bisect-porcelain.sh\n+++ b/t/t6030-bisect-porcelain.sh\n@@ -781,12 +781,12 @@ test_expect_success 'bisect start with one new and old' '\n \tgit bisect new &&\n \tgit bisect new >bisect_result &&\n \tgrep \"$HASH2 is the first new commit\" bisect_result &&\n-\tgit bisect log > log_to_replay.txt &&\n+\tgit bisect log >log_to_replay.txt &&\n \tgit bisect reset\n '\n \n test_expect_success 'bisect replay with old and new' '\n-\tgit bisect replay log_to_replay.txt > bisect_result &&\n+\tgit bisect replay log_to_replay.txt >bisect_result &&\n \tgrep \"$HASH2 is the first new commit\" bisect_result &&\n \tgit bisect reset\n '\n@@ -806,12 +806,12 @@ test_expect_success 'bisect start with one term1 and term2' '\n \tgit bisect term1 &&\n \tgit bisect term1 >bisect_result &&\n \tgrep \"$HASH2 is the first term1 commit\" bisect_result &&\n-\tgit bisect log > log_to_replay.txt &&\n+\tgit bisect log >log_to_replay.txt &&\n \tgit bisect reset\n '\n \n test_expect_success 'bisect replay with term1 and term2' '\n-\tgit bisect replay log_to_replay.txt > bisect_result &&\n+\tgit bisect replay log_to_replay.txt >bisect_result &&\n \tgrep \"$HASH2 is the first term1 commit\" bisect_result &&\n \tgit bisect reset\n '\n@@ -823,7 +823,7 @@ test_expect_success 'bisect start term1 term2' '\n \tgit bisect term1 &&\n \tgit bisect term1 >bisect_result &&\n \tgrep \"$HASH2 is the first term1 commit\" bisect_result &&\n-\tgit bisect log > log_to_replay.txt &&\n+\tgit bisect log >log_to_replay.txt &&\n \tgit bisect reset\n '\n \nAntoine Delaite (5):\n  bisect: correction of typo\n  bisect: replace hardcoded \"bad|good\" by variables\n  bisect: simplify the addition of new bisect terms\n  bisect: add the terms old/new\n  bisect: allows any terms set by user\n\n Documentation/git-bisect.txt |  67 +++++++++++++-\n bisect.c                     |  94 +++++++++++++++-----\n git-bisect.sh                | 207 +++++++++++++++++++++++++++++++++++--------\n revision.c                   |  26 +++++-\n t/t6030-bisect-porcelain.sh  |  83 ++++++++++++++++-\n 5 files changed, 413 insertions(+), 64 deletions(-)\n mode change 100755 => 100644 git-bisect.sh\n\n-- \n2.4.4.414.ge37915c\n"},{"id":"264639","messageId":"1435064084-5554-2-git-send-email-Matthieu.Moy@imag.fr","threadId":"39695","inReplyTo":"1435064084-5554-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH v7 1/5] bisect: correction of typo","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-23T12:54:40Z","receivedAt":"2015-06-23T12:54:40Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"From: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\n\nSigned-off-by: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n bisect.c                    | 2 +-\n t/t6030-bisect-porcelain.sh | 2 +-\n 2 files changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/bisect.c b/bisect.c\nindex 03d5cd9..5b8357d 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -743,7 +743,7 @@ static void handle_bad_merge_base(void)\n \n \tfprintf(stderr, \"Some good revs are not ancestor of the bad rev.\\n\"\n \t\t\"git bisect cannot work properly in this case.\\n\"\n-\t\t\"Maybe you mistake good and bad revs?\\n\");\n+\t\t\"Maybe you mistook good and bad revs?\\n\");\n \texit(1);\n }\n \ndiff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh\nindex 06b4868..9e2c203 100755\n--- a/t/t6030-bisect-porcelain.sh\n+++ b/t/t6030-bisect-porcelain.sh\n@@ -362,7 +362,7 @@ test_expect_success 'bisect starting with a detached HEAD' '\n test_expect_success 'bisect errors out if bad and good are mistaken' '\n \tgit bisect reset &&\n \ttest_must_fail git bisect start $HASH2 $HASH4 2> rev_list_error &&\n-\tgrep \"mistake good and bad\" rev_list_error &&\n+\tgrep \"mistook good and bad\" rev_list_error &&\n \tgit bisect reset\n '\n \n-- \n2.4.4.414.ge37915c\n"},{"id":"264640","messageId":"1435064084-5554-3-git-send-email-Matthieu.Moy@imag.fr","threadId":"39695","inReplyTo":"1435064084-5554-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH v7 2/5] bisect: replace hardcoded \"bad|good\" by variables","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-23T12:54:41Z","receivedAt":"2015-06-23T12:54:41Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"From: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\n\nTo add new tags like old/new and have keywords less confusing, the\nfirst step is to avoid hardcoding the keywords.\n\nThe default mode is still bad/good.\n\nSigned-off-by: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\nSigned-off-by: Louis Stuber <stuberl@ensimag.grenoble-inp.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n bisect.c      | 51 ++++++++++++++++++++++++++++++++++-----------------\n git-bisect.sh | 57 +++++++++++++++++++++++++++++++--------------------------\n 2 files changed, 65 insertions(+), 43 deletions(-)\n mode change 100755 => 100644 git-bisect.sh\n\ndiff --git a/bisect.c b/bisect.c\nindex 5b8357d..2d3dbdc 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -21,6 +21,9 @@ static const char *argv_checkout[] = {\"checkout\", \"-q\", NULL, \"--\", NULL};\n static const char *argv_show_branch[] = {\"show-branch\", NULL, NULL};\n static const char *argv_update_ref[] = {\"update-ref\", \"--no-deref\", \"BISECT_HEAD\", NULL, NULL};\n \n+static const char *name_bad;\n+static const char *name_good;\n+\n /* Remember to update object flag allocation in object.h */\n #define COUNTED\t\t(1u<<16)\n \n@@ -403,15 +406,21 @@ struct commit_list *find_bisection(struct commit_list *list,\n static int register_ref(const char *refname, const struct object_id *oid,\n \t\t\tint flags, void *cb_data)\n {\n-\tif (!strcmp(refname, \"bad\")) {\n+\tstruct strbuf good_prefix = STRBUF_INIT;\n+\tstrbuf_addstr(&good_prefix, name_good);\n+\tstrbuf_addstr(&good_prefix, \"-\");\n+\n+\tif (!strcmp(refname, name_bad)) {\n \t\tcurrent_bad_oid = xmalloc(sizeof(*current_bad_oid));\n \t\toidcpy(current_bad_oid, oid);\n-\t} else if (starts_with(refname, \"good-\")) {\n+\t} else if (starts_with(refname, good_prefix.buf)) {\n \t\tsha1_array_append(&good_revs, oid->hash);\n \t} else if (starts_with(refname, \"skip-\")) {\n \t\tsha1_array_append(&skipped_revs, oid->hash);\n \t}\n \n+\tstrbuf_release(&good_prefix);\n+\n \treturn 0;\n }\n \n@@ -634,7 +643,7 @@ static void exit_if_skipped_commits(struct commit_list *tried,\n \t\treturn;\n \n \tprintf(\"There are only 'skip'ped commits left to test.\\n\"\n-\t       \"The first bad commit could be any of:\\n\");\n+\t       \"The first %s commit could be any of:\\n\", name_bad);\n \tprint_commit_list(tried, \"%s\\n\", \"%s\\n\");\n \tif (bad)\n \t\tprintf(\"%s\\n\", oid_to_hex(bad));\n@@ -732,18 +741,21 @@ static void handle_bad_merge_base(void)\n \tif (is_expected_rev(current_bad_oid)) {\n \t\tchar *bad_hex = oid_to_hex(current_bad_oid);\n \t\tchar *good_hex = join_sha1_array_hex(&good_revs, ' ');\n-\n-\t\tfprintf(stderr, \"The merge base %s is bad.\\n\"\n-\t\t\t\"This means the bug has been fixed \"\n-\t\t\t\"between %s and [%s].\\n\",\n-\t\t\tbad_hex, bad_hex, good_hex);\n-\n+\t\tif (!strcmp(name_bad, \"bad\")) {\n+\t\t\tfprintf(stderr, \"The merge base %s is bad.\\n\"\n+\t\t\t\t\"This means the bug has been fixed \"\n+\t\t\t\t\"between %s and [%s].\\n\",\n+\t\t\t\tbad_hex, bad_hex, good_hex);\n+\t\t} else {\n+\t\t\tdie(\"BUG: terms %s/%s not managed\", name_bad, name_good);\n+\t\t}\n \t\texit(3);\n \t}\n \n-\tfprintf(stderr, \"Some good revs are not ancestor of the bad rev.\\n\"\n+\tfprintf(stderr, \"Some %s revs are not ancestor of the %s rev.\\n\"\n \t\t\"git bisect cannot work properly in this case.\\n\"\n-\t\t\"Maybe you mistook good and bad revs?\\n\");\n+\t\t\"Maybe you mistook %s and %s revs?\\n\",\n+\t\tname_good, name_bad, name_good, name_bad);\n \texit(1);\n }\n \n@@ -755,10 +767,10 @@ static void handle_skipped_merge_base(const unsigned char *mb)\n \n \twarning(\"the merge base between %s and [%s] \"\n \t\t\"must be skipped.\\n\"\n-\t\t\"So we cannot be sure the first bad commit is \"\n+\t\t\"So we cannot be sure the first %s commit is \"\n \t\t\"between %s and %s.\\n\"\n \t\t\"We continue anyway.\",\n-\t\tbad_hex, good_hex, mb_hex, bad_hex);\n+\t\tbad_hex, good_hex, name_bad, mb_hex, bad_hex);\n \tfree(good_hex);\n }\n \n@@ -839,7 +851,7 @@ static void check_good_are_ancestors_of_bad(const char *prefix, int no_checkout)\n \tint fd;\n \n \tif (!current_bad_oid)\n-\t\tdie(\"a bad revision is needed\");\n+\t\tdie(\"a %s revision is needed\", name_bad);\n \n \t/* Check if file BISECT_ANCESTORS_OK exists. */\n \tif (!stat(filename, &st) && S_ISREG(st.st_mode))\n@@ -905,6 +917,8 @@ int bisect_next_all(const char *prefix, int no_checkout)\n \tconst unsigned char *bisect_rev;\n \tchar bisect_rev_hex[GIT_SHA1_HEXSZ + 1];\n \n+\tname_bad = \"bad\";\n+\tname_good = \"good\";\n \tif (read_bisect_refs())\n \t\tdie(\"reading bisect refs failed\");\n \n@@ -926,8 +940,10 @@ int bisect_next_all(const char *prefix, int no_checkout)\n \t\t */\n \t\texit_if_skipped_commits(tried, NULL);\n \n-\t\tprintf(\"%s was both good and bad\\n\",\n-\t\t       oid_to_hex(current_bad_oid));\n+\t\tprintf(\"%s was both %s and %s\\n\",\n+\t\t       oid_to_hex(current_bad_oid),\n+\t\t       name_good,\n+\t\t       name_bad);\n \t\texit(1);\n \t}\n \n@@ -942,7 +958,8 @@ int bisect_next_all(const char *prefix, int no_checkout)\n \n \tif (!hashcmp(bisect_rev, current_bad_oid->hash)) {\n \t\texit_if_skipped_commits(tried, current_bad_oid);\n-\t\tprintf(\"%s is the first bad commit\\n\", bisect_rev_hex);\n+\t\tprintf(\"%s is the first %s commit\\n\", bisect_rev_hex,\n+\t\t\tname_bad);\n \t\tshow_diff_tree(prefix, revs.commits->item);\n \t\t/* This means the bisection process succeeded. */\n \t\texit(10);\ndiff --git a/git-bisect.sh b/git-bisect.sh\nold mode 100755\nnew mode 100644\nindex ae3fec2..ce6412f\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -32,6 +32,8 @@ OPTIONS_SPEC=\n \n _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'\n _x40=\"$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40\"\n+NAME_BAD=bad\n+NAME_GOOD=good\n \n bisect_head()\n {\n@@ -100,8 +102,8 @@ bisect_start() {\n \t\t\t\tbreak\n \t\t\t}\n \t\t\tcase $bad_seen in\n-\t\t\t0) state='bad' ; bad_seen=1 ;;\n-\t\t\t*) state='good' ;;\n+\t\t\t0) state=$NAME_BAD ; bad_seen=1 ;;\n+\t\t\t*) state=$NAME_GOOD ;;\n \t\t\tesac\n \t\t\teval=\"$eval bisect_write '$state' '$rev' 'nolog' &&\"\n \t\t\tshift\n@@ -184,9 +186,12 @@ bisect_write() {\n \trev=\"$2\"\n \tnolog=\"$3\"\n \tcase \"$state\" in\n-\t\tbad)\t\ttag=\"$state\" ;;\n-\t\tgood|skip)\ttag=\"$state\"-\"$rev\" ;;\n-\t\t*)\t\tdie \"$(eval_gettext \"Bad bisect_write argument: \\$state\")\" ;;\n+\t\t\"$NAME_BAD\")\n+\t\t\ttag=\"$state\" ;;\n+\t\t\"$NAME_GOOD\"|skip)\n+\t\t\ttag=\"$state\"-\"$rev\" ;;\n+\t\t*)\n+\t\t\tdie \"$(eval_gettext \"Bad bisect_write argument: \\$state\")\" ;;\n \tesac\n \tgit update-ref \"refs/bisect/$tag\" \"$rev\" || exit\n \techo \"# $state: $(git show-branch $rev)\" >>\"$GIT_DIR/BISECT_LOG\"\n@@ -230,12 +235,12 @@ bisect_state() {\n \tcase \"$#,$state\" in\n \t0,*)\n \t\tdie \"$(gettext \"Please call 'bisect_state' with at least one argument.\")\" ;;\n-\t1,bad|1,good|1,skip)\n+\t1,\"$NAME_BAD\"|1,\"$NAME_GOOD\"|1,skip)\n \t\trev=$(git rev-parse --verify $(bisect_head)) ||\n \t\t\tdie \"$(gettext \"Bad rev input: $(bisect_head)\")\"\n \t\tbisect_write \"$state\" \"$rev\"\n \t\tcheck_expected_revs \"$rev\" ;;\n-\t2,bad|*,good|*,skip)\n+\t2,\"$NAME_BAD\"|*,\"$NAME_GOOD\"|*,skip)\n \t\tshift\n \t\thash_list=''\n \t\tfor rev in \"$@\"\n@@ -249,8 +254,8 @@ bisect_state() {\n \t\t\tbisect_write \"$state\" \"$rev\"\n \t\tdone\n \t\tcheck_expected_revs $hash_list ;;\n-\t*,bad)\n-\t\tdie \"$(gettext \"'git bisect bad' can take only one argument.\")\" ;;\n+\t*,\"$NAME_BAD\")\n+\t\tdie \"$(eval_gettext \"'git bisect \\$NAME_BAD' can take only one argument.\")\" ;;\n \t*)\n \t\tusage ;;\n \tesac\n@@ -259,21 +264,21 @@ bisect_state() {\n \n bisect_next_check() {\n \tmissing_good= missing_bad=\n-\tgit show-ref -q --verify refs/bisect/bad || missing_bad=t\n-\ttest -n \"$(git for-each-ref \"refs/bisect/good-*\")\" || missing_good=t\n+\tgit show-ref -q --verify refs/bisect/$NAME_BAD || missing_bad=t\n+\ttest -n \"$(git for-each-ref \"refs/bisect/$NAME_GOOD-*\")\" || missing_good=t\n \n \tcase \"$missing_good,$missing_bad,$1\" in\n \t,,*)\n-\t\t: have both good and bad - ok\n+\t\t: have both $NAME_GOOD and $NAME_BAD - ok\n \t\t;;\n \t*,)\n \t\t# do not have both but not asked to fail - just report.\n \t\tfalse\n \t\t;;\n-\tt,,good)\n+\tt,,\"$NAME_GOOD\")\n \t\t# have bad but not good.  we could bisect although\n \t\t# this is less optimum.\n-\t\tgettextln \"Warning: bisecting only with a bad commit.\" >&2\n+\t\teval_gettextln \"Warning: bisecting only with a \\$NAME_BAD commit.\" >&2\n \t\tif test -t 0\n \t\tthen\n \t\t\t# TRANSLATORS: Make sure to include [Y] and [n] in your\n@@ -283,7 +288,7 @@ bisect_next_check() {\n \t\t\tread yesno\n \t\t\tcase \"$yesno\" in [Nn]*) exit 1 ;; esac\n \t\tfi\n-\t\t: bisect without good...\n+\t\t: bisect without $NAME_GOOD...\n \t\t;;\n \t*)\n \n@@ -307,7 +312,7 @@ bisect_auto_next() {\n bisect_next() {\n \tcase \"$#\" in 0) ;; *) usage ;; esac\n \tbisect_autostart\n-\tbisect_next_check good\n+\tbisect_next_check $NAME_GOOD\n \n \t# Perform all bisection computation, display and checkout\n \tgit bisect--helper --next-all $(test -f \"$GIT_DIR/BISECT_HEAD\" && echo --no-checkout)\n@@ -316,18 +321,18 @@ bisect_next() {\n \t# Check if we should exit because bisection is finished\n \tif test $res -eq 10\n \tthen\n-\t\tbad_rev=$(git show-ref --hash --verify refs/bisect/bad)\n+\t\tbad_rev=$(git show-ref --hash --verify refs/bisect/$NAME_BAD)\n \t\tbad_commit=$(git show-branch $bad_rev)\n-\t\techo \"# first bad commit: $bad_commit\" >>\"$GIT_DIR/BISECT_LOG\"\n+\t\techo \"# first $NAME_BAD commit: $bad_commit\" >>\"$GIT_DIR/BISECT_LOG\"\n \t\texit 0\n \telif test $res -eq 2\n \tthen\n \t\techo \"# only skipped commits left to test\" >>\"$GIT_DIR/BISECT_LOG\"\n-\t\tgood_revs=$(git for-each-ref --format=\"%(objectname)\" \"refs/bisect/good-*\")\n-\t\tfor skipped in $(git rev-list refs/bisect/bad --not $good_revs)\n+\t\tgood_revs=$(git for-each-ref --format=\"%(objectname)\" \"refs/bisect/$NAME_GOOD-*\")\n+\t\tfor skipped in $(git rev-list refs/bisect/$NAME_BAD --not $good_revs)\n \t\tdo\n \t\t\tskipped_commit=$(git show-branch $skipped)\n-\t\t\techo \"# possible first bad commit: $skipped_commit\" >>\"$GIT_DIR/BISECT_LOG\"\n+\t\t\techo \"# possible first $NAME_BAD commit: $skipped_commit\" >>\"$GIT_DIR/BISECT_LOG\"\n \t\tdone\n \t\texit $res\n \tfi\n@@ -421,7 +426,7 @@ bisect_replay () {\n \t\tstart)\n \t\t\tcmd=\"bisect_start $rev\"\n \t\t\teval \"$cmd\" ;;\n-\t\tgood|bad|skip)\n+\t\t$NAME_GOOD|$NAME_BAD|skip)\n \t\t\tbisect_write \"$command\" \"$rev\" ;;\n \t\t*)\n \t\t\tdie \"$(gettext \"?? what are you talking about?\")\" ;;\n@@ -455,9 +460,9 @@ exit code \\$res from '\\$command' is < 0 or >= 128\" >&2\n \t\t\tstate='skip'\n \t\telif [ $res -gt 0 ]\n \t\tthen\n-\t\t\tstate='bad'\n+\t\t\tstate=\"$NAME_BAD\"\n \t\telse\n-\t\t\tstate='good'\n+\t\t\tstate=\"$NAME_GOOD\"\n \t\tfi\n \n \t\t# We have to use a subshell because \"bisect_state\" can exit.\n@@ -466,7 +471,7 @@ exit code \\$res from '\\$command' is < 0 or >= 128\" >&2\n \n \t\tcat \"$GIT_DIR/BISECT_RUN\"\n \n-\t\tif sane_grep \"first bad commit could be any of\" \"$GIT_DIR/BISECT_RUN\" \\\n+\t\tif sane_grep \"first $NAME_BAD commit could be any of\" \"$GIT_DIR/BISECT_RUN\" \\\n \t\t\t>/dev/null\n \t\tthen\n \t\t\tgettextln \"bisect run cannot continue any more\" >&2\n@@ -480,7 +485,7 @@ exit code \\$res from '\\$command' is < 0 or >= 128\" >&2\n \t\t\texit $res\n \t\tfi\n \n-\t\tif sane_grep \"is the first bad commit\" \"$GIT_DIR/BISECT_RUN\" >/dev/null\n+\t\tif sane_grep \"is the first $NAME_BAD commit\" \"$GIT_DIR/BISECT_RUN\" >/dev/null\n \t\tthen\n \t\t\tgettextln \"bisect run success\"\n \t\t\texit 0;\n-- \n2.4.4.414.ge37915c\n"},{"id":"264637","messageId":"1435064084-5554-4-git-send-email-Matthieu.Moy@imag.fr","threadId":"39695","inReplyTo":"1435064084-5554-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH v7 3/5] bisect: simplify the addition of new bisect terms","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-23T12:54:42Z","receivedAt":"2015-06-23T12:54:42Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"From: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\n\nWe create a file BISECT_TERMS in the repository .git to be read during a\nbisection. The fonctions to be changed if we add new terms are quite\nfew.\nIn git-bisect.sh :\n\tcheck_and_set_terms\n\tbisect_voc\n\nCo-authored-by: Louis Stuber <stuberl@ensimag.grenoble-inp.fr>\nTweaked-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\nSigned-off-by: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\nSigned-off-by: Louis Stuber <stuberl@ensimag.grenoble-inp.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n bisect.c      | 38 +++++++++++++++++++++++++++++---\n git-bisect.sh | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++------\n revision.c    | 26 ++++++++++++++++++++--\n 3 files changed, 122 insertions(+), 12 deletions(-)\n\ndiff --git a/bisect.c b/bisect.c\nindex 2d3dbdc..08be634 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -747,7 +747,10 @@ static void handle_bad_merge_base(void)\n \t\t\t\t\"between %s and [%s].\\n\",\n \t\t\t\tbad_hex, bad_hex, good_hex);\n \t\t} else {\n-\t\t\tdie(\"BUG: terms %s/%s not managed\", name_bad, name_good);\n+\t\t\tfprintf(stderr, \"The merge base %s is %s.\\n\"\n+\t\t\t\t\"This means the first commit marked %s is \"\n+\t\t\t\t\"between %s and [%s].\\n\",\n+\t\t\t\tbad_hex, name_bad, name_bad, bad_hex, good_hex);\n \t\t}\n \t\texit(3);\n \t}\n@@ -902,6 +905,36 @@ static void show_diff_tree(const char *prefix, struct commit *commit)\n }\n \n /*\n+ * The terms used for this bisect session are stored in BISECT_TERMS.\n+ * We read them and store them to adapt the messages accordingly.\n+ * Default is bad/good.\n+ */\n+void read_bisect_terms(const char **read_bad, const char **read_good)\n+{\n+\tstruct strbuf str = STRBUF_INIT;\n+\tconst char *filename = git_path(\"BISECT_TERMS\");\n+\tFILE *fp = fopen(filename, \"r\");\n+\n+\tif (!fp) {\n+\t\tif (errno == ENOENT) {\n+\t\t\t*read_bad = \"bad\";\n+\t\t\t*read_good = \"good\";\n+\t\t\treturn;\n+\t\t} else {\n+\t\t\tdie(\"could not read file '%s': %s\", filename,\n+\t\t\t\tstrerror(errno));\n+\t\t}\n+\t} else {\n+\t\tstrbuf_getline(&str, fp, '\\n');\n+\t\t*read_bad = strbuf_detach(&str, NULL);\n+\t\tstrbuf_getline(&str, fp, '\\n');\n+\t\t*read_good = strbuf_detach(&str, NULL);\n+\t}\n+\tstrbuf_release(&str);\n+\tfclose(fp);\n+}\n+\n+/*\n  * We use the convention that exiting with an exit code 10 means that\n  * the bisection process finished successfully.\n  * In this case the calling shell script should exit 0.\n@@ -917,8 +950,7 @@ int bisect_next_all(const char *prefix, int no_checkout)\n \tconst unsigned char *bisect_rev;\n \tchar bisect_rev_hex[GIT_SHA1_HEXSZ + 1];\n \n-\tname_bad = \"bad\";\n-\tname_good = \"good\";\n+\tread_bisect_terms(&name_bad, &name_good);\n \tif (read_bisect_refs())\n \t\tdie(\"reading bisect refs failed\");\n \ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex ce6412f..7bb18db 100644\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -77,6 +77,9 @@ bisect_start() {\n \torig_args=$(git rev-parse --sq-quote \"$@\")\n \tbad_seen=0\n \teval=''\n+\t# revision_seen is true if a git bisect start\n+\t# has revision as arguments\n+\trevision_seen=0\n \tif test \"z$(git rev-parse --is-bare-repository)\" != zfalse\n \tthen\n \t\tmode=--no-checkout\n@@ -101,6 +104,9 @@ bisect_start() {\n \t\t\t\tdie \"$(eval_gettext \"'\\$arg' does not appear to be a valid revision\")\"\n \t\t\t\tbreak\n \t\t\t}\n+\n+\t\t\trevision_seen=1\n+\n \t\t\tcase $bad_seen in\n \t\t\t0) state=$NAME_BAD ; bad_seen=1 ;;\n \t\t\t*) state=$NAME_GOOD ;;\n@@ -172,6 +178,11 @@ bisect_start() {\n \t} &&\n \tgit rev-parse --sq-quote \"$@\" >\"$GIT_DIR/BISECT_NAMES\" &&\n \teval \"$eval true\" &&\n+\tif test $revision_seen -eq 1 && test ! -s \"$GIT_DIR/BISECT_TERMS\"\n+\tthen\n+\t\techo \"$NAME_BAD\" >\"$GIT_DIR/BISECT_TERMS\" &&\n+\t\techo \"$NAME_GOOD\" >>\"$GIT_DIR/BISECT_TERMS\"\n+\tfi &&\n \techo \"git bisect start$orig_args\" >>\"$GIT_DIR/BISECT_LOG\" || exit\n \t#\n \t# Check if we can proceed to the next bisect state.\n@@ -232,6 +243,7 @@ bisect_skip() {\n bisect_state() {\n \tbisect_autostart\n \tstate=$1\n+\tcheck_and_set_terms $state\n \tcase \"$#,$state\" in\n \t0,*)\n \t\tdie \"$(gettext \"Please call 'bisect_state' with at least one argument.\")\" ;;\n@@ -291,15 +303,17 @@ bisect_next_check() {\n \t\t: bisect without $NAME_GOOD...\n \t\t;;\n \t*)\n-\n+\t\tbad_syn=$(bisect_voc bad)\n+\t\tgood_syn=$(bisect_voc good)\n \t\tif test -s \"$GIT_DIR/BISECT_START\"\n \t\tthen\n-\t\t\tgettextln \"You need to give me at least one good and one bad revision.\n-(You can use \\\"git bisect bad\\\" and \\\"git bisect good\\\" for that.)\" >&2\n+\n+\t\t\teval_gettextln \"You need to give me at least one \\$bad_syn and one \\$good_syn revision.\n+(You can use \\\"git bisect \\$bad_syn\\\" and \\\"git bisect \\$good_syn\\\" for that.)\" >&2\n \t\telse\n-\t\t\tgettextln \"You need to start by \\\"git bisect start\\\".\n-You then need to give me at least one good and one bad revision.\n-(You can use \\\"git bisect bad\\\" and \\\"git bisect good\\\" for that.)\" >&2\n+\t\t\teval_gettextln \"You need to start by \\\"git bisect start\\\".\n+You then need to give me at least one \\$good_syn and one \\$bad_syn revision.\n+(You can use \\\"git bisect \\$bad_syn\\\" and \\\"git bisect \\$good_syn\\\" for that.)\" >&2\n \t\tfi\n \t\texit 1 ;;\n \tesac\n@@ -402,6 +416,7 @@ bisect_clean_state() {\n \trm -f \"$GIT_DIR/BISECT_LOG\" &&\n \trm -f \"$GIT_DIR/BISECT_NAMES\" &&\n \trm -f \"$GIT_DIR/BISECT_RUN\" &&\n+\trm -f \"$GIT_DIR/BISECT_TERMS\" &&\n \t# Cleanup head-name if it got left by an old version of git-bisect\n \trm -f \"$GIT_DIR/head-name\" &&\n \tgit update-ref -d --no-deref BISECT_HEAD &&\n@@ -422,11 +437,13 @@ bisect_replay () {\n \t\t\trev=\"$command\"\n \t\t\tcommand=\"$bisect\"\n \t\tfi\n+\t\tget_terms\n+\t\tcheck_and_set_terms \"$command\"\n \t\tcase \"$command\" in\n \t\tstart)\n \t\t\tcmd=\"bisect_start $rev\"\n \t\t\teval \"$cmd\" ;;\n-\t\t$NAME_GOOD|$NAME_BAD|skip)\n+\t\t\"$NAME_GOOD\"|\"$NAME_BAD\"|skip)\n \t\t\tbisect_write \"$command\" \"$rev\" ;;\n \t\t*)\n \t\t\tdie \"$(gettext \"?? what are you talking about?\")\" ;;\n@@ -499,11 +516,50 @@ bisect_log () {\n \tcat \"$GIT_DIR/BISECT_LOG\"\n }\n \n+get_terms () {\n+\tif test -s \"$GIT_DIR/BISECT_TERMS\"\n+\tthen\n+\t\t{\n+\t\tread NAME_BAD\n+\t\tread NAME_GOOD\n+\t\t} <\"$GIT_DIR/BISECT_TERMS\"\n+\tfi\n+}\n+\n+check_and_set_terms () {\n+\tcmd=\"$1\"\n+\tcase \"$cmd\" in\n+\tbad|good)\n+\t\tif test -s \"$GIT_DIR/BISECT_TERMS\" && test \"$cmd\" != \"$NAME_BAD\" && test \"$cmd\" != \"$NAME_GOOD\"\n+\t\tthen\n+\t\t\tdie \"$(eval_gettext \"Invalid command: you're currently in a \\$NAME_BAD/\\$NAME_GOOD bisect.\")\"\n+\t\tfi\n+\t\tcase \"$cmd\" in\n+\t\tbad|good)\n+\t\t\tif ! test -s \"$GIT_DIR/BISECT_TERMS\"\n+\t\t\tthen\n+\t\t\t\techo \"bad\" >\"$GIT_DIR/BISECT_TERMS\" &&\n+\t\t\t\techo \"good\" >>\"$GIT_DIR/BISECT_TERMS\"\n+\t\t\tfi\n+\t\t\tNAME_BAD=\"bad\"\n+\t\t\tNAME_GOOD=\"good\" ;;\n+\t\tesac ;;\n+\tesac\n+}\n+\n+bisect_voc () {\n+\tcase \"$1\" in\n+\tbad) echo \"bad\" ;;\n+\tgood) echo \"good\" ;;\n+\tesac\n+}\n+\n case \"$#\" in\n 0)\n \tusage ;;\n *)\n \tcmd=\"$1\"\n+\tget_terms\n \tshift\n \tcase \"$cmd\" in\n \thelp)\ndiff --git a/revision.c b/revision.c\nindex 3ff8723..f22923f 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -21,6 +21,9 @@\n \n volatile show_early_output_fn_t show_early_output;\n \n+static const char *name_bad;\n+static const char *name_good;\n+\n char *path_name(const struct name_path *path, const char *name)\n {\n \tconst struct name_path *p;\n@@ -2076,14 +2079,32 @@ void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx,\n \tctx->argc -= n;\n }\n \n+extern void read_bisect_terms(const char **bad, const char **good);\n+\n static int for_each_bad_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data)\n {\n-\treturn for_each_ref_in_submodule(submodule, \"refs/bisect/bad\", fn, cb_data);\n+\tstruct strbuf bisect_refs_buf = STRBUF_INIT;\n+\tconst char *bisect_refs_str;\n+\tint status;\n+\tstrbuf_addstr(&bisect_refs_buf, \"refs/bisect/\");\n+\tstrbuf_addstr(&bisect_refs_buf, name_bad);\n+\tbisect_refs_str = strbuf_detach(&bisect_refs_buf, NULL);\n+\tstatus = for_each_ref_in_submodule(submodule, bisect_refs_str, fn, cb_data);\n+\tfree((char *)bisect_refs_str);\n+\treturn status;\n }\n \n static int for_each_good_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data)\n {\n-\treturn for_each_ref_in_submodule(submodule, \"refs/bisect/good\", fn, cb_data);\n+\tstruct strbuf bisect_refs_buf = STRBUF_INIT;\n+\tconst char *bisect_refs_str;\n+\tint status;\n+\tstrbuf_addstr(&bisect_refs_buf, \"refs/bisect/\");\n+\tstrbuf_addstr(&bisect_refs_buf, name_bad);\n+\tbisect_refs_str = strbuf_detach(&bisect_refs_buf, NULL);\n+\tstatus = for_each_ref_in_submodule(submodule, bisect_refs_str, fn, cb_data);\n+\tfree((char *)bisect_refs_str);\n+\treturn status;\n }\n \n static int handle_revision_pseudo_opt(const char *submodule,\n@@ -2112,6 +2133,7 @@ static int handle_revision_pseudo_opt(const char *submodule,\n \t\thandle_refs(submodule, revs, *flags, for_each_branch_ref_submodule);\n \t\tclear_ref_exclusion(&revs->ref_excludes);\n \t} else if (!strcmp(arg, \"--bisect\")) {\n+\t\tread_bisect_terms(&name_bad, &name_good);\n \t\thandle_refs(submodule, revs, *flags, for_each_bad_bisect_ref);\n \t\thandle_refs(submodule, revs, *flags ^ (UNINTERESTING | BOTTOM), for_each_good_bisect_ref);\n \t\trevs->bisect = 1;\n-- \n2.4.4.414.ge37915c\n"},{"id":"264641","messageId":"1435064084-5554-5-git-send-email-Matthieu.Moy@imag.fr","threadId":"39695","inReplyTo":"1435064084-5554-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH v7 4/5] bisect: add the terms old/new","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-23T12:54:43Z","receivedAt":"2015-06-23T12:54:43Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"From: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\n\nWhen not looking for a regression during a bisect but for a fix or a\nchange in another given property, it can be confusing to use 'good'\nand 'bad'.\n\nThis patch introduce `git bisect new` and `git bisect old` as an\nalternative to 'bad' and good': the commits which have a certain\nproperty must be marked as `new` and the ones which do not as `old`.\n\nThe output will be the first commit after the change in the property.\nDuring a new/old bisect session you cannot use bad/good commands and\nvice-versa.\n\nSome commands are still not available for old/new:\n     * git rev-list --bisect does not treat the revs/bisect/new and\n       revs/bisect/old-SHA1 files.\n\nOld discussions:\n\t- http://thread.gmane.org/gmane.comp.version-control.git/86063\n\t\tintroduced bisect fix unfixed to find fix.\n\t- http://thread.gmane.org/gmane.comp.version-control.git/182398\n\t\tdiscussion around bisect yes/no or old/new.\n\t- http://thread.gmane.org/gmane.comp.version-control.git/199758\n\t\tlast discussion and reviews\nNew discussions:\n\t- http://thread.gmane.org/gmane.comp.version-control.git/271320\n\t\t( v2 1/7-4/7 )\n\t- http://comments.gmane.org/gmane.comp.version-control.git/271343\n\t\t( v2 5/7-7/7 )\n\nSigned-off-by: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\nSigned-off-by: Louis Stuber <stuberl@ensimag.grenoble-inp.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n Documentation/git-bisect.txt | 48 ++++++++++++++++++++++++++++++++++++++++++--\n bisect.c                     | 11 +++++++---\n git-bisect.sh                | 30 ++++++++++++++++++---------\n t/t6030-bisect-porcelain.sh  | 38 +++++++++++++++++++++++++++++++++++\n 4 files changed, 112 insertions(+), 15 deletions(-)\n\ndiff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt\nindex 4cb52a7..3c3021a 100644\n--- a/Documentation/git-bisect.txt\n+++ b/Documentation/git-bisect.txt\n@@ -18,8 +18,8 @@ on the subcommand:\n \n  git bisect help\n  git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<paths>...]\n- git bisect bad [<rev>]\n- git bisect good [<rev>...]\n+ git bisect (bad|new) [<rev>]\n+ git bisect (good|old) [<rev>...]\n  git bisect skip [(<rev>|<range>)...]\n  git bisect reset [<commit>]\n  git bisect visualize\n@@ -104,6 +104,35 @@ For example, `git bisect reset HEAD` will leave you on the current\n bisection commit and avoid switching commits at all, while `git bisect\n reset bisect/bad` will check out the first bad revision.\n \n+\n+Alternative terms: bisect new and bisect old\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+If you are not at ease with the terms \"bad\" and \"good\", perhaps\n+because you are looking for the commit that introduced a fix, you can\n+alternatively use \"new\" and \"old\" instead.\n+But note that you cannot mix \"bad\" and good\" with \"new\" and \"old\".\n+\n+------------------------------------------------\n+git bisect new [<rev>]\n+------------------------------------------------\n+\n+Marks the commit as new, e.g. \"the bug is no longer there\", if you are looking\n+for a commit that fixed a bug, or \"the feature that used to work is now broken\n+at this point\", if you are looking for a commit that introduced a bug.\n+It is the equivalent of \"git bisect bad [<rev>]\".\n+\n+------------------------------------------------\n+git bisect old [<rev>...]\n+------------------------------------------------\n+\n+Marks the commit as old, as the opposite of 'git bisect new'.\n+It is the equivalent of \"git bisect good [<rev>...]\".\n+\n+You must run `git bisect start` without commits as argument and run\n+`git bisect new <rev>`/`git bisect old <rev>...` after to add the\n+commits.\n+\n Bisect visualize\n ~~~~~~~~~~~~~~~~\n \n@@ -379,6 +408,21 @@ In this case, when 'git bisect run' finishes, bisect/bad will refer to a commit\n has at least one parent whose reachable graph is fully traversable in the sense\n required by 'git pack objects'.\n \n+* Look for a fix instead of a regression in the code\n++\n+------------\n+$ git bisect start\n+$ git bisect new HEAD    # current commit is marked as new\n+$ git bisect old HEAD~10 # the tenth commit from now is marked as old\n+------------\n++\n+Let's consider the last commit has a given property, and that we are looking\n+for the commit which introduced this property. For each commit the bisection\n+guide us to, we will test if the property is present. If it is we will mark\n+the commit as new with 'git bisect new', otherwise we will mark it as old.\n+At the end of the bisect session, the result will be the first new commit (e.g\n+the first one with the property).\n+\n \n SEE ALSO\n --------\ndiff --git a/bisect.c b/bisect.c\nindex 08be634..ab09650 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -746,6 +746,11 @@ static void handle_bad_merge_base(void)\n \t\t\t\t\"This means the bug has been fixed \"\n \t\t\t\t\"between %s and [%s].\\n\",\n \t\t\t\tbad_hex, bad_hex, good_hex);\n+\t\t} else if (!strcmp(name_bad, \"new\")) {\n+\t\t\tfprintf(stderr, \"The merge base %s is new.\\n\"\n+\t\t\t\t\"The property has changed \"\n+\t\t\t\t\"between %s and [%s].\\n\",\n+\t\t\t\tbad_hex, bad_hex, good_hex);\n \t\t} else {\n \t\t\tfprintf(stderr, \"The merge base %s is %s.\\n\"\n \t\t\t\t\"This means the first commit marked %s is \"\n@@ -778,11 +783,11 @@ static void handle_skipped_merge_base(const unsigned char *mb)\n }\n \n /*\n- * \"check_merge_bases\" checks that merge bases are not \"bad\".\n+ * \"check_merge_bases\" checks that merge bases are not \"bad\" (or \"new\").\n  *\n- * - If one is \"bad\", it means the user assumed something wrong\n+ * - If one is \"bad\" (or \"new\"), it means the user assumed something wrong\n  * and we must exit with a non 0 error code.\n- * - If one is \"good\", that's good, we have nothing to do.\n+ * - If one is \"good\" (or \"old\"), that's good, we have nothing to do.\n  * - If one is \"skipped\", we can't know but we should warn.\n  * - If we don't know, we should check it out and ask the user to test.\n  */\ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex 7bb18db..73763a2 100644\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -1,14 +1,16 @@\n #!/bin/sh\n \n-USAGE='[help|start|bad|good|skip|next|reset|visualize|replay|log|run]'\n+USAGE='[help|start|bad|good|new|old|skip|next|reset|visualize|replay|log|run]'\n LONG_USAGE='git bisect help\n \tprint this long help message.\n git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<pathspec>...]\n \treset bisect state and start bisection.\n-git bisect bad [<rev>]\n-\tmark <rev> a known-bad revision.\n-git bisect good [<rev>...]\n-\tmark <rev>... known-good revisions.\n+git bisect (bad|new) [<rev>]\n+\tmark <rev> a known-bad revision/\n+\t\ta revision after change in a given property.\n+git bisect (good|old) [<rev>...]\n+\tmark <rev>... known-good revisions/\n+\t\trevisions before change in a given property.\n git bisect skip [(<rev>|<range>)...]\n \tmark <rev>... untestable revisions.\n git bisect next\n@@ -288,7 +290,7 @@ bisect_next_check() {\n \t\tfalse\n \t\t;;\n \tt,,\"$NAME_GOOD\")\n-\t\t# have bad but not good.  we could bisect although\n+\t\t# have bad (or new) but not good (or old).  we could bisect although\n \t\t# this is less optimum.\n \t\teval_gettextln \"Warning: bisecting only with a \\$NAME_BAD commit.\" >&2\n \t\tif test -t 0\n@@ -529,7 +531,7 @@ get_terms () {\n check_and_set_terms () {\n \tcmd=\"$1\"\n \tcase \"$cmd\" in\n-\tbad|good)\n+\tbad|good|new|old)\n \t\tif test -s \"$GIT_DIR/BISECT_TERMS\" && test \"$cmd\" != \"$NAME_BAD\" && test \"$cmd\" != \"$NAME_GOOD\"\n \t\tthen\n \t\t\tdie \"$(eval_gettext \"Invalid command: you're currently in a \\$NAME_BAD/\\$NAME_GOOD bisect.\")\"\n@@ -543,14 +545,22 @@ check_and_set_terms () {\n \t\t\tfi\n \t\t\tNAME_BAD=\"bad\"\n \t\t\tNAME_GOOD=\"good\" ;;\n+\t\tnew|old)\n+\t\t\tif ! test -s \"$GIT_DIR/BISECT_TERMS\"\n+\t\t\tthen\n+\t\t\t\techo \"new\" >\"$GIT_DIR/BISECT_TERMS\" &&\n+\t\t\t\techo \"old\" >>\"$GIT_DIR/BISECT_TERMS\"\n+\t\t\tfi\n+\t\t\tNAME_BAD=\"new\"\n+\t\t\tNAME_GOOD=\"old\" ;;\n \t\tesac ;;\n \tesac\n }\n \n bisect_voc () {\n \tcase \"$1\" in\n-\tbad) echo \"bad\" ;;\n-\tgood) echo \"good\" ;;\n+\tbad) echo \"bad|old\" ;;\n+\tgood) echo \"good|new\" ;;\n \tesac\n }\n \n@@ -566,7 +576,7 @@ case \"$#\" in\n \t\tgit bisect -h ;;\n \tstart)\n \t\tbisect_start \"$@\" ;;\n-\tbad|good)\n+\tbad|good|new|old)\n \t\tbisect_state \"$cmd\" \"$@\" ;;\n \tskip)\n \t\tbisect_skip \"$@\" ;;\ndiff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh\nindex 9e2c203..983c503 100755\n--- a/t/t6030-bisect-porcelain.sh\n+++ b/t/t6030-bisect-porcelain.sh\n@@ -759,4 +759,42 @@ test_expect_success '\"git bisect bad HEAD\" behaves as \"git bisect bad\"' '\n \tgit bisect reset\n '\n \n+test_expect_success 'bisect starts with only one new' '\n+\tgit bisect reset &&\n+\tgit bisect start &&\n+\tgit bisect new $HASH4 &&\n+\tgit bisect next\n+'\n+\n+test_expect_success 'bisect does not start with only one old' '\n+\tgit bisect reset &&\n+\tgit bisect start &&\n+\tgit bisect old $HASH1 &&\n+\ttest_must_fail git bisect next\n+'\n+\n+test_expect_success 'bisect start with one new and old' '\n+\tgit bisect reset &&\n+\tgit bisect start &&\n+\tgit bisect old $HASH1 &&\n+\tgit bisect new $HASH4 &&\n+\tgit bisect new &&\n+\tgit bisect new >bisect_result &&\n+\tgrep \"$HASH2 is the first new commit\" bisect_result &&\n+\tgit bisect log >log_to_replay.txt &&\n+\tgit bisect reset\n+'\n+\n+test_expect_success 'bisect replay with old and new' '\n+\tgit bisect replay log_to_replay.txt >bisect_result &&\n+\tgrep \"$HASH2 is the first new commit\" bisect_result &&\n+\tgit bisect reset\n+'\n+\n+test_expect_success 'bisect cannot mix old/new and good/bad' '\n+\tgit bisect start &&\n+\tgit bisect bad $HASH4 &&\n+\ttest_must_fail git bisect old $HASH1\n+'\n+\n test_done\n-- \n2.4.4.414.ge37915c\n"},{"id":"264642","messageId":"1435064084-5554-6-git-send-email-Matthieu.Moy@imag.fr","threadId":"39695","inReplyTo":"1435064084-5554-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH v7 5/5] bisect: allows any terms set by user","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-23T12:54:44Z","receivedAt":"2015-06-23T12:54:44Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"From: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\n\nIntroduction of the git bisect terms function.\nThe user can set its own terms.\nIt will work exactly like before. The terms must be set\nbefore the start.\n\nSigned-off-by: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\nSigned-off-by: Louis Stuber <stuberl@ensimag.grenoble-inp.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n Documentation/git-bisect.txt | 19 +++++++++++++\n git-bisect.sh                | 68 ++++++++++++++++++++++++++++++++++++++++----\n t/t6030-bisect-porcelain.sh  | 43 ++++++++++++++++++++++++++++\n 3 files changed, 125 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt\nindex 3c3021a..ef0c03c 100644\n--- a/Documentation/git-bisect.txt\n+++ b/Documentation/git-bisect.txt\n@@ -133,6 +133,25 @@ You must run `git bisect start` without commits as argument and run\n `git bisect new <rev>`/`git bisect old <rev>...` after to add the\n commits.\n \n+Alternative terms: use your own terms\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+If the builtins terms bad/good and new/old do not satisfy you, you can\n+set your own terms.\n+\n+------------------------------------------------\n+git bisect terms term1 term2\n+------------------------------------------------\n+\n+This command has to be used before a bisection has started.\n+The term1 must be associated with the latest revisions and term2 with the\n+ancestors of term1.\n+\n+Only the first bisection following the 'git bisect terms' will use the terms.\n+If you mistyped one of the terms you can do again 'git bisect terms term1\n+term2'.\n+\n+\n Bisect visualize\n ~~~~~~~~~~~~~~~~\n \ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex 73763a2..8ef2b94 100644\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -1,6 +1,6 @@\n #!/bin/sh\n \n-USAGE='[help|start|bad|good|new|old|skip|next|reset|visualize|replay|log|run]'\n+USAGE='[help|start|bad|good|new|old|terms|skip|next|reset|visualize|replay|log|run]'\n LONG_USAGE='git bisect help\n \tprint this long help message.\n git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<pathspec>...]\n@@ -11,6 +11,8 @@ git bisect (bad|new) [<rev>]\n git bisect (good|old) [<rev>...]\n \tmark <rev>... known-good revisions/\n \t\trevisions before change in a given property.\n+git bisect terms term1 term2\n+\tset up term1 and term2 as bisection terms.\n git bisect skip [(<rev>|<range>)...]\n \tmark <rev>... untestable revisions.\n git bisect next\n@@ -82,6 +84,14 @@ bisect_start() {\n \t# revision_seen is true if a git bisect start\n \t# has revision as arguments\n \trevision_seen=0\n+\t# terms_defined is used to detect if the user\n+\t# defined his own terms with git bisect terms\n+\tterms_defined=0\n+\tif test -s \"$GIT_DIR/TERMS_DEFINED\"\n+\tthen\n+\t\tterms_defined=1\n+\t\tget_terms\n+\tfi\n \tif test \"z$(git rev-parse --is-bare-repository)\" != zfalse\n \tthen\n \t\tmode=--no-checkout\n@@ -180,10 +190,14 @@ bisect_start() {\n \t} &&\n \tgit rev-parse --sq-quote \"$@\" >\"$GIT_DIR/BISECT_NAMES\" &&\n \teval \"$eval true\" &&\n-\tif test $revision_seen -eq 1 && test ! -s \"$GIT_DIR/BISECT_TERMS\"\n+\tif test $revision_seen -eq 1 && test ! -s \"$GIT_DIR/BISECT_TERMS\" || test $terms_defined -eq 1\n \tthen\n \t\techo \"$NAME_BAD\" >\"$GIT_DIR/BISECT_TERMS\" &&\n-\t\techo \"$NAME_GOOD\" >>\"$GIT_DIR/BISECT_TERMS\"\n+\t\techo \"$NAME_GOOD\" >>\"$GIT_DIR/BISECT_TERMS\" &&\n+\t\tif test $terms_defined -eq 1\n+\t\tthen\n+\t\t\techo \"git bisect terms $NAME_BAD $NAME_GOOD\" >>\"$GIT_DIR/BISECT_LOG\" || exit\n+\t\tfi\n \tfi &&\n \techo \"git bisect start$orig_args\" >>\"$GIT_DIR/BISECT_LOG\" || exit\n \t#\n@@ -419,6 +433,7 @@ bisect_clean_state() {\n \trm -f \"$GIT_DIR/BISECT_NAMES\" &&\n \trm -f \"$GIT_DIR/BISECT_RUN\" &&\n \trm -f \"$GIT_DIR/BISECT_TERMS\" &&\n+\trm -f \"$GIT_DIR/TERMS_DEFINED\" &&\n \t# Cleanup head-name if it got left by an old version of git-bisect\n \trm -f \"$GIT_DIR/head-name\" &&\n \tgit update-ref -d --no-deref BISECT_HEAD &&\n@@ -447,6 +462,8 @@ bisect_replay () {\n \t\t\teval \"$cmd\" ;;\n \t\t\"$NAME_GOOD\"|\"$NAME_BAD\"|skip)\n \t\t\tbisect_write \"$command\" \"$rev\" ;;\n+\t\tterms)\n+\t\t\tbisect_terms $rev ;;\n \t\t*)\n \t\t\tdie \"$(gettext \"?? what are you talking about?\")\" ;;\n \t\tesac\n@@ -531,7 +548,8 @@ get_terms () {\n check_and_set_terms () {\n \tcmd=\"$1\"\n \tcase \"$cmd\" in\n-\tbad|good|new|old)\n+\tskip|start|terms) ;;\n+\t*)\n \t\tif test -s \"$GIT_DIR/BISECT_TERMS\" && test \"$cmd\" != \"$NAME_BAD\" && test \"$cmd\" != \"$NAME_GOOD\"\n \t\tthen\n \t\t\tdie \"$(eval_gettext \"Invalid command: you're currently in a \\$NAME_BAD/\\$NAME_GOOD bisect.\")\"\n@@ -564,6 +582,44 @@ bisect_voc () {\n \tesac\n }\n \n+bisect_terms () {\n+\tcase \"$#\" in\n+\t0)\n+\t\tif test -s \"$GIT_DIR/BISECT_TERMS\"\n+\t\tthen\n+\t\t\t{\n+\t\t\tread term1\n+\t\t\tread term2\n+\t\t\t}<\"$GIT_DIR/BISECT_TERMS\"\n+\t\t\tgettextln \"Your current terms are $term1 and $term2.\"\n+\t\telse\n+\t\t\tdie \"$(gettext \"No terms defined.\")\"\n+\t\tfi ;;\n+\t2)\n+\t\tcheck_term_format refs/bisect/\"$1\"\n+\t\tcheck_term_format refs/bisect/\"$2\"\n+\t\tif ! test -s \"$GIT_DIR/BISECT_START\"\n+\t\tthen\n+\t\t\techo $1 >\"$GIT_DIR/BISECT_TERMS\" &&\n+\t\t\techo $2 >>\"$GIT_DIR/BISECT_TERMS\" &&\n+\t\t\techo \"1\" >\"$GIT_DIR/TERMS_DEFINED\"\n+\t\t\techo \"git bisect terms $NAME_BAD $NAME_GOOD\" >>\"$GIT_DIR/BISECT_LOG\" || exit\n+\t\telse\n+\t\t\tdie \"$(gettext \"A bisection has already started, and you can't change terms in the middle of it.\n+Use 'git bisect terms' to see the current terms.\n+Otherwise, to start a new bisection with new terms, please use 'git bisect reset' and set the terms before the start\")\"\n+\t\tfi ;;\n+\t*)\n+\t\tusage ;;\n+\tesac\n+}\n+\n+check_term_format () {\n+\targ=\"$1\"\n+\tgit check-ref-format $arg ||\n+\tdie \"$(eval_gettext \"'\\$arg' is not a valid term\")\"\n+}\n+\n case \"$#\" in\n 0)\n \tusage ;;\n@@ -576,7 +632,7 @@ case \"$#\" in\n \t\tgit bisect -h ;;\n \tstart)\n \t\tbisect_start \"$@\" ;;\n-\tbad|good|new|old)\n+\tbad|good|new|old|\"$NAME_BAD\"|\"$NAME_GOOD\")\n \t\tbisect_state \"$cmd\" \"$@\" ;;\n \tskip)\n \t\tbisect_skip \"$@\" ;;\n@@ -593,6 +649,8 @@ case \"$#\" in\n \t\tbisect_log ;;\n \trun)\n \t\tbisect_run \"$@\" ;;\n+\tterms)\n+\t\tbisect_terms \"$@\" ;;\n \t*)\n \t\tusage ;;\n \tesac\ndiff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh\nindex 983c503..289dbb0 100755\n--- a/t/t6030-bisect-porcelain.sh\n+++ b/t/t6030-bisect-porcelain.sh\n@@ -797,4 +797,47 @@ test_expect_success 'bisect cannot mix old/new and good/bad' '\n \ttest_must_fail git bisect old $HASH1\n '\n \n+test_expect_success 'bisect start with one term1 and term2' '\n+\tgit bisect reset &&\n+\tgit bisect terms term1 term2 &&\n+\tgit bisect start &&\n+\tgit bisect term2 $HASH1 &&\n+\tgit bisect term1 $HASH4 &&\n+\tgit bisect term1 &&\n+\tgit bisect term1 >bisect_result &&\n+\tgrep \"$HASH2 is the first term1 commit\" bisect_result &&\n+\tgit bisect log >log_to_replay.txt &&\n+\tgit bisect reset\n+'\n+\n+test_expect_success 'bisect replay with term1 and term2' '\n+\tgit bisect replay log_to_replay.txt >bisect_result &&\n+\tgrep \"$HASH2 is the first term1 commit\" bisect_result &&\n+\tgit bisect reset\n+'\n+\n+test_expect_success 'bisect start term1 term2' '\n+\tgit bisect reset &&\n+\tgit bisect terms term1 term2 &&\n+\tgit bisect start $HASH4 $HASH1 &&\n+\tgit bisect term1 &&\n+\tgit bisect term1 >bisect_result &&\n+\tgrep \"$HASH2 is the first term1 commit\" bisect_result &&\n+\tgit bisect log >log_to_replay.txt &&\n+\tgit bisect reset\n+'\n+\n+test_expect_success 'bisect cannot mix terms' '\n+\tgit bisect reset &&\n+\tgit bisect terms a b &&\n+\tgit bisect terms term1 term2 &&\n+\tgit bisect start $HASH4 $HASH1 &&\n+\ttest_must_fail git bisect a &&\n+\ttest_must_fail git bisect b &&\n+\ttest_must_fail git bisect bad &&\n+\ttest_must_fail git bisect good &&\n+\ttest_must_fail git bisect new &&\n+\ttest_must_fail git bisect old\n+'\n+\n test_done\n-- \n2.4.4.414.ge37915c\n"},{"id":"264646","messageId":"CAPig+cSzymZ+JEO8sPrayQ+XNag0kAry_9_eH4=kSqPp=JKk7w@mail.gmail.com","threadId":"39695","inReplyTo":"1435064084-5554-4-git-send-email-Matthieu.Moy@imag.fr","subject":"Re: [PATCH v7 3/5] bisect: simplify the addition of new bisect terms","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2015-06-23T17:49:14Z","receivedAt":"2015-06-23T17:49:14Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Tue, Jun 23, 2015 at 8:54 AM, Matthieu Moy <Matthieu.Moy@imag.fr> wrote:\n> diff --git a/revision.c b/revision.c\n> index 3ff8723..f22923f 100644\n> --- a/revision.c\n> +++ b/revision.c\n> @@ -2076,14 +2079,32 @@ void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx,\n>         ctx->argc -= n;\n>  }\n>\n> +extern void read_bisect_terms(const char **bad, const char **good);\n> +\n>  static int for_each_bad_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data)\n>  {\n> -       return for_each_ref_in_submodule(submodule, \"refs/bisect/bad\", fn, cb_data);\n> +       struct strbuf bisect_refs_buf = STRBUF_INIT;\n> +       const char *bisect_refs_str;\n> +       int status;\n> +       strbuf_addstr(&bisect_refs_buf, \"refs/bisect/\");\n> +       strbuf_addstr(&bisect_refs_buf, name_bad);\n\nA single strbuf_addf() rather than two strbuf_addstr()s?\n\n> +       bisect_refs_str = strbuf_detach(&bisect_refs_buf, NULL);\n> +       status = for_each_ref_in_submodule(submodule, bisect_refs_str, fn, cb_data);\n> +       free((char *)bisect_refs_str);\n\nWhy the above rather than the simpler?\n\n    strbuf_addstr(&bisect_refs, ...);\n    status = for_each_ref_in_submodule(submodule, bisect_refs.buf, fn, cb_data);\n    strbuf_release(&bisect_refs);\n\nWhat am I missing?\n\n> +       return status;\n>  }\n>\n>  static int for_each_good_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data)\n>  {\n> -       return for_each_ref_in_submodule(submodule, \"refs/bisect/good\", fn, cb_data);\n> +       struct strbuf bisect_refs_buf = STRBUF_INIT;\n> +       const char *bisect_refs_str;\n> +       int status;\n> +       strbuf_addstr(&bisect_refs_buf, \"refs/bisect/\");\n> +       strbuf_addstr(&bisect_refs_buf, name_bad);\n> +       bisect_refs_str = strbuf_detach(&bisect_refs_buf, NULL);\n> +       status = for_each_ref_in_submodule(submodule, bisect_refs_str, fn, cb_data);\n> +       free((char *)bisect_refs_str);\n\nDitto.\n\n> +       return status;\n>  }\n"},{"id":"264648","messageId":"vpqsi9ixp8f.fsf@anie.imag.fr","threadId":"39695","inReplyTo":"CAPig+cSzymZ+JEO8sPrayQ+XNag0kAry_9_eH4=kSqPp=JKk7w@mail.gmail.com","subject":"Re: [PATCH v7 3/5] bisect: simplify the addition of new bisect terms","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2015-06-23T18:18:40Z","receivedAt":"2015-06-23T18:18:40Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Eric Sunshine <sunshine@sunshineco.com> writes:\n\n> On Tue, Jun 23, 2015 at 8:54 AM, Matthieu Moy <Matthieu.Moy@imag.fr> wrote:\n\n>> +       strbuf_addstr(&bisect_refs_buf, \"refs/bisect/\");\n>> +       strbuf_addstr(&bisect_refs_buf, name_bad);\n>\n> A single strbuf_addf() rather than two strbuf_addstr()s?\n\n>> +       bisect_refs_str = strbuf_detach(&bisect_refs_buf, NULL);\n>> +       status = for_each_ref_in_submodule(submodule, bisect_refs_str, fn, cb_data);\n>> +       free((char *)bisect_refs_str);\n>\n> Why the above rather than the simpler?\n>\n>     strbuf_addstr(&bisect_refs, ...);\n>     status = for_each_ref_in_submodule(submodule, bisect_refs.buf, fn, cb_data);\n>     strbuf_release(&bisect_refs);\n>\n> What am I missing?\n\nIndeed, your version is much better.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"264651","messageId":"xmqq8ubadzwp.fsf@gitster.dls.corp.google.com","threadId":"39695","inReplyTo":"1435064084-5554-6-git-send-email-Matthieu.Moy@imag.fr","subject":"Re: [PATCH v7 5/5] bisect: allows any terms set by user","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-06-23T18:48:22Z","receivedAt":"2015-06-23T18:48:22Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthieu Moy <Matthieu.Moy@imag.fr> writes:\n\n>Subject: Re: [PATCH v7 5/5] bisect: allows any terms set by user\n\ns/allows/allow/;\n\n> +Alternative terms: use your own terms\n> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n\nLengths of underline and the text must match.\n"},{"id":"264654","messageId":"xmqq381idz59.fsf@gitster.dls.corp.google.com","threadId":"39695","inReplyTo":"1435064084-5554-1-git-send-email-Matthieu.Moy@imag.fr","subject":"Re: [PATCH v7 0/5] git bisect old/new","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-06-23T19:04:50Z","receivedAt":"2015-06-23T19:04:50Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthieu Moy <Matthieu.Moy@imag.fr> writes:\n\n> I fixed a few minor issues in v6. Patch between my version and v6 is\n> below. I also pushed my branch here:\n>\n>   https://github.com/moy/git/tree/bisect-terms\n\nIt is somewhat confusing to see v3 yesterday and then this v7 next\nday.  How did I miss v4 thru v6?\n\n> Not visible in the patch below: I squashed PATCH 5 into PATCH 3 to\n> avoid the pattern \"break stuff and then repair it\".\n\nGood.\n\n> The first two patches seem ready.\n\nYeah, the first one is obviously fine ;-), and I agree the second\none looks more or less OK.\n\nRegarding the second and third one, the messages they give when the\nuser marked one tip of a side branch as old and the other new gave\nme a hiccup while reading them, though.\n\n\tif (!strcmp(name_bad, \"bad\")) {\n\t\tfprintf(stderr, \"The merge base %s is bad.\\n\"\n\t\t\t\"This means the bug has been fixed \"\n\t\t\t\"between %s and [%s].\\n\",\n\t\t\tbad_hex, bad_hex, good_hex);\n\t} else {\n\t\tfprintf(stderr, \"The merge base %s is %s.\\n\"\n\t\t\t\"This means the first commit marked %s is \"\n\t\t\t\"between %s and [%s].\\n\",\n\t\t\tbad_hex, name_bad, name_bad, bad_hex, good_hex);\n\nThe \"bad\" side is inherited from the original and not your fault,\nbut it was already very hard to understand. The other side is not\njust unreadable, but I think is incorrect and confusing to say\n\"first commit marked %(name_bad)s\"; you know there are history\nsegments whose oldest ends (i.e. merge base that is bad) are marked\nas 'bad', and the other ends are marked as 'good', and you haven't\nmarked any of the commits in between yet.  So there is no \"first\ncommit marked\" either as bad or good there between these endpoints\n(yet).\n\nAlso I was somewhat puzzled and disappointed to still see\nname_{bad,good} not name_{new,old} used as variable names even in\nthe endgame patch, though.  Is that intended?\n\n> PATCH 4 (add old/new) is still buggy. When starting a bisection with\n>\n>   git bisect start $old $new\n>\n> the command \"git bisect visualize\" does not work (it shows no commit).\n>\n> I consider PATCH 5 as WIP, I think it would need a lot of polishing\n> and testing to be mergeable. I think a reasonable objective for now it\n> to get old/new working in the user-interface, and drop PATCH 5 from\n> the series when it gets merged. The existance of PATCH 5 is a very\n> good thing even if it doesn't get merged:\n>\n> * The fact that it's possible to do it on top of the series shows that\n>   we make the code more generic. I think it's important that\n>   regardless of features, the code moves in the right direction.\n>\n> * The patch can be taken over later by someone else.\n\nYeah, if I may rephrase to make sure we are on the same page, in\norder for 5/5 to be done sanely, 1-4/5 must be giving a good\nfoundation to build on.  I agree with that, I agree that including a\npolished 5/5 would be a good thing, and then I further agree that\n1-4/5 could be delivered before 5/5 is ready.\n\nThanks.\n"},{"id":"264658","messageId":"303519671.732577.1435087672353.JavaMail.zimbra@ensimag.grenoble-inp.fr","threadId":"39695","inReplyTo":"1435064084-5554-5-git-send-email-Matthieu.Moy@imag.fr","subject":"Re: [PATCH v7 4/5] bisect: add the terms old/new","fromName":"Remi Galan Alfonso","fromEmail":"remi.galan-alfonso@ensimag.grenoble-inp.fr","sentAt":"2015-06-23T19:27:52Z","receivedAt":"2015-06-23T19:27:52Z","isPatch":true,"sender":{"key":"remi.galan-alfonso@ensimag.grenoble-inp.fr","avatar":"https://avatars.githubusercontent.com/u/12509162?v=4"},"body":"Matthieu Moy <Matthieu.Moy@imag.fr> writes:\n> Signed-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\n> Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n\nSounds like you went all out with this patch.\n\nRémi\n"},{"id":"264667","messageId":"vpqsi9imb8d.fsf@anie.imag.fr","threadId":"39695","inReplyTo":"xmqq381idz59.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v7 0/5] git bisect old/new","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2015-06-23T20:16:34Z","receivedAt":"2015-06-23T20:16:34Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Matthieu Moy <Matthieu.Moy@imag.fr> writes:\n>\n>> I fixed a few minor issues in v6. Patch between my version and v6 is\n>> below. I also pushed my branch here:\n>>\n>>   https://github.com/moy/git/tree/bisect-terms\n>\n> It is somewhat confusing to see v3 yesterday and then this v7 next\n> day.  How did I miss v4 thru v6?\n\nOops, I pattern-matched the wrong part when reading [PATCH v3 6/6].\nIndeed, this should have been numberred v4, I should have s/v6/v3/ in my\nsentence above.\n\n> Regarding the second and third one, the messages they give when the\n> user marked one tip of a side branch as old and the other new gave\n> me a hiccup while reading them, though.\n>\n> \tif (!strcmp(name_bad, \"bad\")) {\n> \t\tfprintf(stderr, \"The merge base %s is bad.\\n\"\n> \t\t\t\"This means the bug has been fixed \"\n> \t\t\t\"between %s and [%s].\\n\",\n> \t\t\tbad_hex, bad_hex, good_hex);\n> \t} else {\n> \t\tfprintf(stderr, \"The merge base %s is %s.\\n\"\n> \t\t\t\"This means the first commit marked %s is \"\n> \t\t\t\"between %s and [%s].\\n\",\n> \t\t\tbad_hex, name_bad, name_bad, bad_hex, good_hex);\n>\n> The \"bad\" side is inherited from the original and not your fault,\n> but it was already very hard to understand. The other side is not\n> just unreadable, but I think is incorrect and confusing to say\n> \"first commit marked %(name_bad)s\"; you know there are history\n> segments whose oldest ends (i.e. merge base that is bad) are marked\n> as 'bad', and the other ends are marked as 'good', and you haven't\n> marked any of the commits in between yet.  So there is no \"first\n> commit marked\" either as bad or good there between these endpoints\n> (yet).\n\nThe situation is (the bisection started with bad=branch1 and\ngood=branch2):\n\n---- base (name_bad) ------ branch1 (name_bad)\n        \\\n         `----------------- branch2 (name_good)\n\nSo, the first commit having property name_good is between base and\nbranch2. So, the message seems wrong in two ways:\n\n* As you say, the wording \"marked as\" seem to imply that we did mark the\n  commit, while we actually did not explore base..branch2\n  I'd write \"the first '%s' commit\" (the important is to remove\n  \"marked\").\n\n* The message uses 'name_bad' where it should use 'name_good'. Indeed,\n  the original message talks about \"bug fixed\", i.e. the first _good_\n  commit is in base..branch2.\n\nIs this what you meant?\n\n(Sorry, I need drawings and bullet lists to think properly ;-) ).\n\nActually, I think it would make sense to include my drawing above in a\ncomment in the code.\n\n> Also I was somewhat puzzled and disappointed to still see\n> name_{bad,good} not name_{new,old} used as variable names even in\n> the endgame patch, though.  Is that intended?\n\nI still think that name_old/name_new would have been much better names\nif we were to write bisect from scratch, but I got convinced by\nChristian that name_bad/name_good made sense too. Even if we adopted\nold/new in these variables, we would still have e.g. a variable\n\"bad_seen\" in the code. So, moving the codebase to adopt the old/new\nconvention internally is more than just chosing the name of variables to\navoid hardcoded \"good\"/\"bad\" string litterals. Moving the brain of\ndeveloppers to adopt the old/new convention is even another debate.\n\nI don't know if this is the reason why Antoine did not change it, but\nthat's why I did not insist further and did not do the change myself.\n\n> Yeah, if I may rephrase to make sure we are on the same page, in\n> order for 5/5 to be done sanely, 1-4/5 must be giving a good\n> foundation to build on.  I agree with that, I agree that including a\n> polished 5/5 would be a good thing, and then I further agree that\n> 1-4/5 could be delivered before 5/5 is ready.\n\nYes.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"264670","messageId":"vpqy4jakw7p.fsf@anie.imag.fr","threadId":"39695","inReplyTo":"303519671.732577.1435087672353.JavaMail.zimbra@ensimag.grenoble-inp.fr","subject":"Re: [PATCH v7 4/5] bisect: add the terms old/new","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2015-06-23T20:26:18Z","receivedAt":"2015-06-23T20:26:18Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Remi Galan Alfonso <remi.galan-alfonso@ensimag.grenoble-inp.fr> writes:\n\n> Matthieu Moy <Matthieu.Moy@imag.fr> writes:\n>> Signed-off-by: Matthieu Moy <Matthieu.Moy@grenoble-inp.fr>\n>> Signed-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n>\n> Sounds like you went all out with this patch.\n\nAh, the first line was in the original patch, and the second is added by\nsend-email -s ... Both me and myself agree that one of them can be\nremoved indeed ;-).\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"264680","messageId":"xmqqioaecgfn.fsf@gitster.dls.corp.google.com","threadId":"39695","inReplyTo":"vpqsi9imb8d.fsf@anie.imag.fr","subject":"Re: [PATCH v7 0/5] git bisect old/new","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-06-23T20:34:20Z","receivedAt":"2015-06-23T20:34:20Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthieu Moy <Matthieu.Moy@Grenoble-INP.fr> writes:\n\n>> It is somewhat confusing to see v3 yesterday and then this v7 next\n>> day.  How did I miss v4 thru v6?\n>\n> Oops, I pattern-matched the wrong part when reading [PATCH v3 6/6].\n> Indeed, this should have been numberred v4, I should have s/v6/v3/ in my\n> sentence above.\n\nOK.\n\n> So, the first commit having property name_good is between base and\n> branch2. So, the message seems wrong in two ways:\n\nYeah, I agree with you on both points.\n\n> Actually, I think it would make sense to include my drawing above\n> in a comment in the code.\n\nSounds like a good idea.\n"},{"id":"264726","messageId":"1435159062-23468-1-git-send-email-Matthieu.Moy@imag.fr","threadId":"39695","inReplyTo":"1435064084-5554-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH v8 0/5] Bisect terms","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-24T15:17:37Z","receivedAt":"2015-06-24T15:17:37Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"This is a minor iteration over v7 to take into account Junio and\nEric's comments, AND fix an important typo that I introduced in the\nstrbuf code conversion (I used name_good instead of name_bad). This\nfixes the \"git bisect visualize\" bug I found earlier. I played a bit\nwith the result and didn't find any bug.\n\nExcept for the last patch, it seems at least close to mergeable.\n\ndiff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt\nindex ef0c03c..a37336e 100644\n--- a/Documentation/git-bisect.txt\n+++ b/Documentation/git-bisect.txt\n@@ -134,7 +134,7 @@ You must run `git bisect start` without commits as argument and run\n commits.\n \n Alternative terms: use your own terms\n-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n \n If the builtins terms bad/good and new/old do not satisfy you, you can\n set your own terms.\ndiff --git a/revision.c b/revision.c\nindex f22923f..24ce842 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -2083,27 +2083,21 @@ extern void read_bisect_terms(const char **bad, const char **good);\n \n static int for_each_bad_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data)\n {\n-\tstruct strbuf bisect_refs_buf = STRBUF_INIT;\n-\tconst char *bisect_refs_str;\n+\tstruct strbuf bisect_refs = STRBUF_INIT;\n \tint status;\n-\tstrbuf_addstr(&bisect_refs_buf, \"refs/bisect/\");\n-\tstrbuf_addstr(&bisect_refs_buf, name_bad);\n-\tbisect_refs_str = strbuf_detach(&bisect_refs_buf, NULL);\n-\tstatus = for_each_ref_in_submodule(submodule, bisect_refs_str, fn, cb_data);\n-\tfree((char *)bisect_refs_str);\n+\tstrbuf_addf(&bisect_refs, \"refs/bisect/%s\", name_bad);\n+\tstatus = for_each_ref_in_submodule(submodule, bisect_refs.buf, fn, cb_data);\n+\tstrbuf_release(&bisect_refs);\n \treturn status;\n }\n \n static int for_each_good_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data)\n {\n-\tstruct strbuf bisect_refs_buf = STRBUF_INIT;\n-\tconst char *bisect_refs_str;\n+\tstruct strbuf bisect_refs = STRBUF_INIT;\n \tint status;\n-\tstrbuf_addstr(&bisect_refs_buf, \"refs/bisect/\");\n-\tstrbuf_addstr(&bisect_refs_buf, name_bad);\n-\tbisect_refs_str = strbuf_detach(&bisect_refs_buf, NULL);\n-\tstatus = for_each_ref_in_submodule(submodule, bisect_refs_str, fn, cb_data);\n-\tfree((char *)bisect_refs_str);\n+\tstrbuf_addf(&bisect_refs, \"refs/bisect/%s\", name_good);\n+\tstatus = for_each_ref_in_submodule(submodule, bisect_refs.buf, fn, cb_data);\n+\tstrbuf_release(&bisect_refs);\n \treturn status;\n }\n \n\n\nAntoine Delaite (5):\n  bisect: correction of typo\n  bisect: replace hardcoded \"bad|good\" by variables\n  bisect: simplify the addition of new bisect terms\n  bisect: add the terms old/new\n  bisect: allow any terms set by user\n\n Documentation/git-bisect.txt |  67 +++++++++++++-\n bisect.c                     |  94 +++++++++++++++-----\n git-bisect.sh                | 207 +++++++++++++++++++++++++++++++++++--------\n revision.c                   |  20 ++++-\n t/t6030-bisect-porcelain.sh  |  83 ++++++++++++++++-\n 5 files changed, 407 insertions(+), 64 deletions(-)\n mode change 100755 => 100644 git-bisect.sh\n\n-- \n2.4.4.414.g59d82e6\n"},{"id":"264727","messageId":"1435159062-23468-2-git-send-email-Matthieu.Moy@imag.fr","threadId":"39695","inReplyTo":"1435159062-23468-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH v8 1/5] bisect: correction of typo","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-24T15:17:38Z","receivedAt":"2015-06-24T15:17:38Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"From: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\n\nSigned-off-by: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n bisect.c                    | 2 +-\n t/t6030-bisect-porcelain.sh | 2 +-\n 2 files changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/bisect.c b/bisect.c\nindex 03d5cd9..5b8357d 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -743,7 +743,7 @@ static void handle_bad_merge_base(void)\n \n \tfprintf(stderr, \"Some good revs are not ancestor of the bad rev.\\n\"\n \t\t\"git bisect cannot work properly in this case.\\n\"\n-\t\t\"Maybe you mistake good and bad revs?\\n\");\n+\t\t\"Maybe you mistook good and bad revs?\\n\");\n \texit(1);\n }\n \ndiff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh\nindex 06b4868..9e2c203 100755\n--- a/t/t6030-bisect-porcelain.sh\n+++ b/t/t6030-bisect-porcelain.sh\n@@ -362,7 +362,7 @@ test_expect_success 'bisect starting with a detached HEAD' '\n test_expect_success 'bisect errors out if bad and good are mistaken' '\n \tgit bisect reset &&\n \ttest_must_fail git bisect start $HASH2 $HASH4 2> rev_list_error &&\n-\tgrep \"mistake good and bad\" rev_list_error &&\n+\tgrep \"mistook good and bad\" rev_list_error &&\n \tgit bisect reset\n '\n \n-- \n2.4.4.414.g59d82e6\n"},{"id":"264729","messageId":"1435159062-23468-3-git-send-email-Matthieu.Moy@imag.fr","threadId":"39695","inReplyTo":"1435159062-23468-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH v8 2/5] bisect: replace hardcoded \"bad|good\" by variables","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-24T15:17:39Z","receivedAt":"2015-06-24T15:17:39Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"From: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\n\nTo add new tags like old/new and have keywords less confusing, the\nfirst step is to avoid hardcoding the keywords.\n\nThe default mode is still bad/good.\n\nSigned-off-by: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\nSigned-off-by: Louis Stuber <stuberl@ensimag.grenoble-inp.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n bisect.c      | 51 ++++++++++++++++++++++++++++++++++-----------------\n git-bisect.sh | 57 +++++++++++++++++++++++++++++++--------------------------\n 2 files changed, 65 insertions(+), 43 deletions(-)\n mode change 100755 => 100644 git-bisect.sh\n\ndiff --git a/bisect.c b/bisect.c\nindex 5b8357d..2d3dbdc 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -21,6 +21,9 @@ static const char *argv_checkout[] = {\"checkout\", \"-q\", NULL, \"--\", NULL};\n static const char *argv_show_branch[] = {\"show-branch\", NULL, NULL};\n static const char *argv_update_ref[] = {\"update-ref\", \"--no-deref\", \"BISECT_HEAD\", NULL, NULL};\n \n+static const char *name_bad;\n+static const char *name_good;\n+\n /* Remember to update object flag allocation in object.h */\n #define COUNTED\t\t(1u<<16)\n \n@@ -403,15 +406,21 @@ struct commit_list *find_bisection(struct commit_list *list,\n static int register_ref(const char *refname, const struct object_id *oid,\n \t\t\tint flags, void *cb_data)\n {\n-\tif (!strcmp(refname, \"bad\")) {\n+\tstruct strbuf good_prefix = STRBUF_INIT;\n+\tstrbuf_addstr(&good_prefix, name_good);\n+\tstrbuf_addstr(&good_prefix, \"-\");\n+\n+\tif (!strcmp(refname, name_bad)) {\n \t\tcurrent_bad_oid = xmalloc(sizeof(*current_bad_oid));\n \t\toidcpy(current_bad_oid, oid);\n-\t} else if (starts_with(refname, \"good-\")) {\n+\t} else if (starts_with(refname, good_prefix.buf)) {\n \t\tsha1_array_append(&good_revs, oid->hash);\n \t} else if (starts_with(refname, \"skip-\")) {\n \t\tsha1_array_append(&skipped_revs, oid->hash);\n \t}\n \n+\tstrbuf_release(&good_prefix);\n+\n \treturn 0;\n }\n \n@@ -634,7 +643,7 @@ static void exit_if_skipped_commits(struct commit_list *tried,\n \t\treturn;\n \n \tprintf(\"There are only 'skip'ped commits left to test.\\n\"\n-\t       \"The first bad commit could be any of:\\n\");\n+\t       \"The first %s commit could be any of:\\n\", name_bad);\n \tprint_commit_list(tried, \"%s\\n\", \"%s\\n\");\n \tif (bad)\n \t\tprintf(\"%s\\n\", oid_to_hex(bad));\n@@ -732,18 +741,21 @@ static void handle_bad_merge_base(void)\n \tif (is_expected_rev(current_bad_oid)) {\n \t\tchar *bad_hex = oid_to_hex(current_bad_oid);\n \t\tchar *good_hex = join_sha1_array_hex(&good_revs, ' ');\n-\n-\t\tfprintf(stderr, \"The merge base %s is bad.\\n\"\n-\t\t\t\"This means the bug has been fixed \"\n-\t\t\t\"between %s and [%s].\\n\",\n-\t\t\tbad_hex, bad_hex, good_hex);\n-\n+\t\tif (!strcmp(name_bad, \"bad\")) {\n+\t\t\tfprintf(stderr, \"The merge base %s is bad.\\n\"\n+\t\t\t\t\"This means the bug has been fixed \"\n+\t\t\t\t\"between %s and [%s].\\n\",\n+\t\t\t\tbad_hex, bad_hex, good_hex);\n+\t\t} else {\n+\t\t\tdie(\"BUG: terms %s/%s not managed\", name_bad, name_good);\n+\t\t}\n \t\texit(3);\n \t}\n \n-\tfprintf(stderr, \"Some good revs are not ancestor of the bad rev.\\n\"\n+\tfprintf(stderr, \"Some %s revs are not ancestor of the %s rev.\\n\"\n \t\t\"git bisect cannot work properly in this case.\\n\"\n-\t\t\"Maybe you mistook good and bad revs?\\n\");\n+\t\t\"Maybe you mistook %s and %s revs?\\n\",\n+\t\tname_good, name_bad, name_good, name_bad);\n \texit(1);\n }\n \n@@ -755,10 +767,10 @@ static void handle_skipped_merge_base(const unsigned char *mb)\n \n \twarning(\"the merge base between %s and [%s] \"\n \t\t\"must be skipped.\\n\"\n-\t\t\"So we cannot be sure the first bad commit is \"\n+\t\t\"So we cannot be sure the first %s commit is \"\n \t\t\"between %s and %s.\\n\"\n \t\t\"We continue anyway.\",\n-\t\tbad_hex, good_hex, mb_hex, bad_hex);\n+\t\tbad_hex, good_hex, name_bad, mb_hex, bad_hex);\n \tfree(good_hex);\n }\n \n@@ -839,7 +851,7 @@ static void check_good_are_ancestors_of_bad(const char *prefix, int no_checkout)\n \tint fd;\n \n \tif (!current_bad_oid)\n-\t\tdie(\"a bad revision is needed\");\n+\t\tdie(\"a %s revision is needed\", name_bad);\n \n \t/* Check if file BISECT_ANCESTORS_OK exists. */\n \tif (!stat(filename, &st) && S_ISREG(st.st_mode))\n@@ -905,6 +917,8 @@ int bisect_next_all(const char *prefix, int no_checkout)\n \tconst unsigned char *bisect_rev;\n \tchar bisect_rev_hex[GIT_SHA1_HEXSZ + 1];\n \n+\tname_bad = \"bad\";\n+\tname_good = \"good\";\n \tif (read_bisect_refs())\n \t\tdie(\"reading bisect refs failed\");\n \n@@ -926,8 +940,10 @@ int bisect_next_all(const char *prefix, int no_checkout)\n \t\t */\n \t\texit_if_skipped_commits(tried, NULL);\n \n-\t\tprintf(\"%s was both good and bad\\n\",\n-\t\t       oid_to_hex(current_bad_oid));\n+\t\tprintf(\"%s was both %s and %s\\n\",\n+\t\t       oid_to_hex(current_bad_oid),\n+\t\t       name_good,\n+\t\t       name_bad);\n \t\texit(1);\n \t}\n \n@@ -942,7 +958,8 @@ int bisect_next_all(const char *prefix, int no_checkout)\n \n \tif (!hashcmp(bisect_rev, current_bad_oid->hash)) {\n \t\texit_if_skipped_commits(tried, current_bad_oid);\n-\t\tprintf(\"%s is the first bad commit\\n\", bisect_rev_hex);\n+\t\tprintf(\"%s is the first %s commit\\n\", bisect_rev_hex,\n+\t\t\tname_bad);\n \t\tshow_diff_tree(prefix, revs.commits->item);\n \t\t/* This means the bisection process succeeded. */\n \t\texit(10);\ndiff --git a/git-bisect.sh b/git-bisect.sh\nold mode 100755\nnew mode 100644\nindex ae3fec2..ce6412f\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -32,6 +32,8 @@ OPTIONS_SPEC=\n \n _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'\n _x40=\"$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40\"\n+NAME_BAD=bad\n+NAME_GOOD=good\n \n bisect_head()\n {\n@@ -100,8 +102,8 @@ bisect_start() {\n \t\t\t\tbreak\n \t\t\t}\n \t\t\tcase $bad_seen in\n-\t\t\t0) state='bad' ; bad_seen=1 ;;\n-\t\t\t*) state='good' ;;\n+\t\t\t0) state=$NAME_BAD ; bad_seen=1 ;;\n+\t\t\t*) state=$NAME_GOOD ;;\n \t\t\tesac\n \t\t\teval=\"$eval bisect_write '$state' '$rev' 'nolog' &&\"\n \t\t\tshift\n@@ -184,9 +186,12 @@ bisect_write() {\n \trev=\"$2\"\n \tnolog=\"$3\"\n \tcase \"$state\" in\n-\t\tbad)\t\ttag=\"$state\" ;;\n-\t\tgood|skip)\ttag=\"$state\"-\"$rev\" ;;\n-\t\t*)\t\tdie \"$(eval_gettext \"Bad bisect_write argument: \\$state\")\" ;;\n+\t\t\"$NAME_BAD\")\n+\t\t\ttag=\"$state\" ;;\n+\t\t\"$NAME_GOOD\"|skip)\n+\t\t\ttag=\"$state\"-\"$rev\" ;;\n+\t\t*)\n+\t\t\tdie \"$(eval_gettext \"Bad bisect_write argument: \\$state\")\" ;;\n \tesac\n \tgit update-ref \"refs/bisect/$tag\" \"$rev\" || exit\n \techo \"# $state: $(git show-branch $rev)\" >>\"$GIT_DIR/BISECT_LOG\"\n@@ -230,12 +235,12 @@ bisect_state() {\n \tcase \"$#,$state\" in\n \t0,*)\n \t\tdie \"$(gettext \"Please call 'bisect_state' with at least one argument.\")\" ;;\n-\t1,bad|1,good|1,skip)\n+\t1,\"$NAME_BAD\"|1,\"$NAME_GOOD\"|1,skip)\n \t\trev=$(git rev-parse --verify $(bisect_head)) ||\n \t\t\tdie \"$(gettext \"Bad rev input: $(bisect_head)\")\"\n \t\tbisect_write \"$state\" \"$rev\"\n \t\tcheck_expected_revs \"$rev\" ;;\n-\t2,bad|*,good|*,skip)\n+\t2,\"$NAME_BAD\"|*,\"$NAME_GOOD\"|*,skip)\n \t\tshift\n \t\thash_list=''\n \t\tfor rev in \"$@\"\n@@ -249,8 +254,8 @@ bisect_state() {\n \t\t\tbisect_write \"$state\" \"$rev\"\n \t\tdone\n \t\tcheck_expected_revs $hash_list ;;\n-\t*,bad)\n-\t\tdie \"$(gettext \"'git bisect bad' can take only one argument.\")\" ;;\n+\t*,\"$NAME_BAD\")\n+\t\tdie \"$(eval_gettext \"'git bisect \\$NAME_BAD' can take only one argument.\")\" ;;\n \t*)\n \t\tusage ;;\n \tesac\n@@ -259,21 +264,21 @@ bisect_state() {\n \n bisect_next_check() {\n \tmissing_good= missing_bad=\n-\tgit show-ref -q --verify refs/bisect/bad || missing_bad=t\n-\ttest -n \"$(git for-each-ref \"refs/bisect/good-*\")\" || missing_good=t\n+\tgit show-ref -q --verify refs/bisect/$NAME_BAD || missing_bad=t\n+\ttest -n \"$(git for-each-ref \"refs/bisect/$NAME_GOOD-*\")\" || missing_good=t\n \n \tcase \"$missing_good,$missing_bad,$1\" in\n \t,,*)\n-\t\t: have both good and bad - ok\n+\t\t: have both $NAME_GOOD and $NAME_BAD - ok\n \t\t;;\n \t*,)\n \t\t# do not have both but not asked to fail - just report.\n \t\tfalse\n \t\t;;\n-\tt,,good)\n+\tt,,\"$NAME_GOOD\")\n \t\t# have bad but not good.  we could bisect although\n \t\t# this is less optimum.\n-\t\tgettextln \"Warning: bisecting only with a bad commit.\" >&2\n+\t\teval_gettextln \"Warning: bisecting only with a \\$NAME_BAD commit.\" >&2\n \t\tif test -t 0\n \t\tthen\n \t\t\t# TRANSLATORS: Make sure to include [Y] and [n] in your\n@@ -283,7 +288,7 @@ bisect_next_check() {\n \t\t\tread yesno\n \t\t\tcase \"$yesno\" in [Nn]*) exit 1 ;; esac\n \t\tfi\n-\t\t: bisect without good...\n+\t\t: bisect without $NAME_GOOD...\n \t\t;;\n \t*)\n \n@@ -307,7 +312,7 @@ bisect_auto_next() {\n bisect_next() {\n \tcase \"$#\" in 0) ;; *) usage ;; esac\n \tbisect_autostart\n-\tbisect_next_check good\n+\tbisect_next_check $NAME_GOOD\n \n \t# Perform all bisection computation, display and checkout\n \tgit bisect--helper --next-all $(test -f \"$GIT_DIR/BISECT_HEAD\" && echo --no-checkout)\n@@ -316,18 +321,18 @@ bisect_next() {\n \t# Check if we should exit because bisection is finished\n \tif test $res -eq 10\n \tthen\n-\t\tbad_rev=$(git show-ref --hash --verify refs/bisect/bad)\n+\t\tbad_rev=$(git show-ref --hash --verify refs/bisect/$NAME_BAD)\n \t\tbad_commit=$(git show-branch $bad_rev)\n-\t\techo \"# first bad commit: $bad_commit\" >>\"$GIT_DIR/BISECT_LOG\"\n+\t\techo \"# first $NAME_BAD commit: $bad_commit\" >>\"$GIT_DIR/BISECT_LOG\"\n \t\texit 0\n \telif test $res -eq 2\n \tthen\n \t\techo \"# only skipped commits left to test\" >>\"$GIT_DIR/BISECT_LOG\"\n-\t\tgood_revs=$(git for-each-ref --format=\"%(objectname)\" \"refs/bisect/good-*\")\n-\t\tfor skipped in $(git rev-list refs/bisect/bad --not $good_revs)\n+\t\tgood_revs=$(git for-each-ref --format=\"%(objectname)\" \"refs/bisect/$NAME_GOOD-*\")\n+\t\tfor skipped in $(git rev-list refs/bisect/$NAME_BAD --not $good_revs)\n \t\tdo\n \t\t\tskipped_commit=$(git show-branch $skipped)\n-\t\t\techo \"# possible first bad commit: $skipped_commit\" >>\"$GIT_DIR/BISECT_LOG\"\n+\t\t\techo \"# possible first $NAME_BAD commit: $skipped_commit\" >>\"$GIT_DIR/BISECT_LOG\"\n \t\tdone\n \t\texit $res\n \tfi\n@@ -421,7 +426,7 @@ bisect_replay () {\n \t\tstart)\n \t\t\tcmd=\"bisect_start $rev\"\n \t\t\teval \"$cmd\" ;;\n-\t\tgood|bad|skip)\n+\t\t$NAME_GOOD|$NAME_BAD|skip)\n \t\t\tbisect_write \"$command\" \"$rev\" ;;\n \t\t*)\n \t\t\tdie \"$(gettext \"?? what are you talking about?\")\" ;;\n@@ -455,9 +460,9 @@ exit code \\$res from '\\$command' is < 0 or >= 128\" >&2\n \t\t\tstate='skip'\n \t\telif [ $res -gt 0 ]\n \t\tthen\n-\t\t\tstate='bad'\n+\t\t\tstate=\"$NAME_BAD\"\n \t\telse\n-\t\t\tstate='good'\n+\t\t\tstate=\"$NAME_GOOD\"\n \t\tfi\n \n \t\t# We have to use a subshell because \"bisect_state\" can exit.\n@@ -466,7 +471,7 @@ exit code \\$res from '\\$command' is < 0 or >= 128\" >&2\n \n \t\tcat \"$GIT_DIR/BISECT_RUN\"\n \n-\t\tif sane_grep \"first bad commit could be any of\" \"$GIT_DIR/BISECT_RUN\" \\\n+\t\tif sane_grep \"first $NAME_BAD commit could be any of\" \"$GIT_DIR/BISECT_RUN\" \\\n \t\t\t>/dev/null\n \t\tthen\n \t\t\tgettextln \"bisect run cannot continue any more\" >&2\n@@ -480,7 +485,7 @@ exit code \\$res from '\\$command' is < 0 or >= 128\" >&2\n \t\t\texit $res\n \t\tfi\n \n-\t\tif sane_grep \"is the first bad commit\" \"$GIT_DIR/BISECT_RUN\" >/dev/null\n+\t\tif sane_grep \"is the first $NAME_BAD commit\" \"$GIT_DIR/BISECT_RUN\" >/dev/null\n \t\tthen\n \t\t\tgettextln \"bisect run success\"\n \t\t\texit 0;\n-- \n2.4.4.414.g59d82e6\n"},{"id":"264730","messageId":"1435159062-23468-4-git-send-email-Matthieu.Moy@imag.fr","threadId":"39695","inReplyTo":"1435159062-23468-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH v8 3/5] bisect: simplify the addition of new bisect terms","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-24T15:17:40Z","receivedAt":"2015-06-24T15:17:40Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"From: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\n\nWe create a file BISECT_TERMS in the repository .git to be read during a\nbisection. The fonctions to be changed if we add new terms are quite\nfew.\nIn git-bisect.sh:\n\tcheck_and_set_terms\n\tbisect_voc\n\nCo-authored-by: Louis Stuber <stuberl@ensimag.grenoble-inp.fr>\nTweaked-by: Matthieu Moy <Matthieu.Moy@imag.fr>\nSigned-off-by: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\nSigned-off-by: Louis Stuber <stuberl@ensimag.grenoble-inp.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n bisect.c      | 38 +++++++++++++++++++++++++++++---\n git-bisect.sh | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++------\n revision.c    | 20 +++++++++++++++--\n 3 files changed, 116 insertions(+), 12 deletions(-)\n\ndiff --git a/bisect.c b/bisect.c\nindex 2d3dbdc..08be634 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -747,7 +747,10 @@ static void handle_bad_merge_base(void)\n \t\t\t\t\"between %s and [%s].\\n\",\n \t\t\t\tbad_hex, bad_hex, good_hex);\n \t\t} else {\n-\t\t\tdie(\"BUG: terms %s/%s not managed\", name_bad, name_good);\n+\t\t\tfprintf(stderr, \"The merge base %s is %s.\\n\"\n+\t\t\t\t\"This means the first commit marked %s is \"\n+\t\t\t\t\"between %s and [%s].\\n\",\n+\t\t\t\tbad_hex, name_bad, name_bad, bad_hex, good_hex);\n \t\t}\n \t\texit(3);\n \t}\n@@ -902,6 +905,36 @@ static void show_diff_tree(const char *prefix, struct commit *commit)\n }\n \n /*\n+ * The terms used for this bisect session are stored in BISECT_TERMS.\n+ * We read them and store them to adapt the messages accordingly.\n+ * Default is bad/good.\n+ */\n+void read_bisect_terms(const char **read_bad, const char **read_good)\n+{\n+\tstruct strbuf str = STRBUF_INIT;\n+\tconst char *filename = git_path(\"BISECT_TERMS\");\n+\tFILE *fp = fopen(filename, \"r\");\n+\n+\tif (!fp) {\n+\t\tif (errno == ENOENT) {\n+\t\t\t*read_bad = \"bad\";\n+\t\t\t*read_good = \"good\";\n+\t\t\treturn;\n+\t\t} else {\n+\t\t\tdie(\"could not read file '%s': %s\", filename,\n+\t\t\t\tstrerror(errno));\n+\t\t}\n+\t} else {\n+\t\tstrbuf_getline(&str, fp, '\\n');\n+\t\t*read_bad = strbuf_detach(&str, NULL);\n+\t\tstrbuf_getline(&str, fp, '\\n');\n+\t\t*read_good = strbuf_detach(&str, NULL);\n+\t}\n+\tstrbuf_release(&str);\n+\tfclose(fp);\n+}\n+\n+/*\n  * We use the convention that exiting with an exit code 10 means that\n  * the bisection process finished successfully.\n  * In this case the calling shell script should exit 0.\n@@ -917,8 +950,7 @@ int bisect_next_all(const char *prefix, int no_checkout)\n \tconst unsigned char *bisect_rev;\n \tchar bisect_rev_hex[GIT_SHA1_HEXSZ + 1];\n \n-\tname_bad = \"bad\";\n-\tname_good = \"good\";\n+\tread_bisect_terms(&name_bad, &name_good);\n \tif (read_bisect_refs())\n \t\tdie(\"reading bisect refs failed\");\n \ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex ce6412f..7bb18db 100644\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -77,6 +77,9 @@ bisect_start() {\n \torig_args=$(git rev-parse --sq-quote \"$@\")\n \tbad_seen=0\n \teval=''\n+\t# revision_seen is true if a git bisect start\n+\t# has revision as arguments\n+\trevision_seen=0\n \tif test \"z$(git rev-parse --is-bare-repository)\" != zfalse\n \tthen\n \t\tmode=--no-checkout\n@@ -101,6 +104,9 @@ bisect_start() {\n \t\t\t\tdie \"$(eval_gettext \"'\\$arg' does not appear to be a valid revision\")\"\n \t\t\t\tbreak\n \t\t\t}\n+\n+\t\t\trevision_seen=1\n+\n \t\t\tcase $bad_seen in\n \t\t\t0) state=$NAME_BAD ; bad_seen=1 ;;\n \t\t\t*) state=$NAME_GOOD ;;\n@@ -172,6 +178,11 @@ bisect_start() {\n \t} &&\n \tgit rev-parse --sq-quote \"$@\" >\"$GIT_DIR/BISECT_NAMES\" &&\n \teval \"$eval true\" &&\n+\tif test $revision_seen -eq 1 && test ! -s \"$GIT_DIR/BISECT_TERMS\"\n+\tthen\n+\t\techo \"$NAME_BAD\" >\"$GIT_DIR/BISECT_TERMS\" &&\n+\t\techo \"$NAME_GOOD\" >>\"$GIT_DIR/BISECT_TERMS\"\n+\tfi &&\n \techo \"git bisect start$orig_args\" >>\"$GIT_DIR/BISECT_LOG\" || exit\n \t#\n \t# Check if we can proceed to the next bisect state.\n@@ -232,6 +243,7 @@ bisect_skip() {\n bisect_state() {\n \tbisect_autostart\n \tstate=$1\n+\tcheck_and_set_terms $state\n \tcase \"$#,$state\" in\n \t0,*)\n \t\tdie \"$(gettext \"Please call 'bisect_state' with at least one argument.\")\" ;;\n@@ -291,15 +303,17 @@ bisect_next_check() {\n \t\t: bisect without $NAME_GOOD...\n \t\t;;\n \t*)\n-\n+\t\tbad_syn=$(bisect_voc bad)\n+\t\tgood_syn=$(bisect_voc good)\n \t\tif test -s \"$GIT_DIR/BISECT_START\"\n \t\tthen\n-\t\t\tgettextln \"You need to give me at least one good and one bad revision.\n-(You can use \\\"git bisect bad\\\" and \\\"git bisect good\\\" for that.)\" >&2\n+\n+\t\t\teval_gettextln \"You need to give me at least one \\$bad_syn and one \\$good_syn revision.\n+(You can use \\\"git bisect \\$bad_syn\\\" and \\\"git bisect \\$good_syn\\\" for that.)\" >&2\n \t\telse\n-\t\t\tgettextln \"You need to start by \\\"git bisect start\\\".\n-You then need to give me at least one good and one bad revision.\n-(You can use \\\"git bisect bad\\\" and \\\"git bisect good\\\" for that.)\" >&2\n+\t\t\teval_gettextln \"You need to start by \\\"git bisect start\\\".\n+You then need to give me at least one \\$good_syn and one \\$bad_syn revision.\n+(You can use \\\"git bisect \\$bad_syn\\\" and \\\"git bisect \\$good_syn\\\" for that.)\" >&2\n \t\tfi\n \t\texit 1 ;;\n \tesac\n@@ -402,6 +416,7 @@ bisect_clean_state() {\n \trm -f \"$GIT_DIR/BISECT_LOG\" &&\n \trm -f \"$GIT_DIR/BISECT_NAMES\" &&\n \trm -f \"$GIT_DIR/BISECT_RUN\" &&\n+\trm -f \"$GIT_DIR/BISECT_TERMS\" &&\n \t# Cleanup head-name if it got left by an old version of git-bisect\n \trm -f \"$GIT_DIR/head-name\" &&\n \tgit update-ref -d --no-deref BISECT_HEAD &&\n@@ -422,11 +437,13 @@ bisect_replay () {\n \t\t\trev=\"$command\"\n \t\t\tcommand=\"$bisect\"\n \t\tfi\n+\t\tget_terms\n+\t\tcheck_and_set_terms \"$command\"\n \t\tcase \"$command\" in\n \t\tstart)\n \t\t\tcmd=\"bisect_start $rev\"\n \t\t\teval \"$cmd\" ;;\n-\t\t$NAME_GOOD|$NAME_BAD|skip)\n+\t\t\"$NAME_GOOD\"|\"$NAME_BAD\"|skip)\n \t\t\tbisect_write \"$command\" \"$rev\" ;;\n \t\t*)\n \t\t\tdie \"$(gettext \"?? what are you talking about?\")\" ;;\n@@ -499,11 +516,50 @@ bisect_log () {\n \tcat \"$GIT_DIR/BISECT_LOG\"\n }\n \n+get_terms () {\n+\tif test -s \"$GIT_DIR/BISECT_TERMS\"\n+\tthen\n+\t\t{\n+\t\tread NAME_BAD\n+\t\tread NAME_GOOD\n+\t\t} <\"$GIT_DIR/BISECT_TERMS\"\n+\tfi\n+}\n+\n+check_and_set_terms () {\n+\tcmd=\"$1\"\n+\tcase \"$cmd\" in\n+\tbad|good)\n+\t\tif test -s \"$GIT_DIR/BISECT_TERMS\" && test \"$cmd\" != \"$NAME_BAD\" && test \"$cmd\" != \"$NAME_GOOD\"\n+\t\tthen\n+\t\t\tdie \"$(eval_gettext \"Invalid command: you're currently in a \\$NAME_BAD/\\$NAME_GOOD bisect.\")\"\n+\t\tfi\n+\t\tcase \"$cmd\" in\n+\t\tbad|good)\n+\t\t\tif ! test -s \"$GIT_DIR/BISECT_TERMS\"\n+\t\t\tthen\n+\t\t\t\techo \"bad\" >\"$GIT_DIR/BISECT_TERMS\" &&\n+\t\t\t\techo \"good\" >>\"$GIT_DIR/BISECT_TERMS\"\n+\t\t\tfi\n+\t\t\tNAME_BAD=\"bad\"\n+\t\t\tNAME_GOOD=\"good\" ;;\n+\t\tesac ;;\n+\tesac\n+}\n+\n+bisect_voc () {\n+\tcase \"$1\" in\n+\tbad) echo \"bad\" ;;\n+\tgood) echo \"good\" ;;\n+\tesac\n+}\n+\n case \"$#\" in\n 0)\n \tusage ;;\n *)\n \tcmd=\"$1\"\n+\tget_terms\n \tshift\n \tcase \"$cmd\" in\n \thelp)\ndiff --git a/revision.c b/revision.c\nindex 3ff8723..24ce842 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -21,6 +21,9 @@\n \n volatile show_early_output_fn_t show_early_output;\n \n+static const char *name_bad;\n+static const char *name_good;\n+\n char *path_name(const struct name_path *path, const char *name)\n {\n \tconst struct name_path *p;\n@@ -2076,14 +2079,26 @@ void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx,\n \tctx->argc -= n;\n }\n \n+extern void read_bisect_terms(const char **bad, const char **good);\n+\n static int for_each_bad_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data)\n {\n-\treturn for_each_ref_in_submodule(submodule, \"refs/bisect/bad\", fn, cb_data);\n+\tstruct strbuf bisect_refs = STRBUF_INIT;\n+\tint status;\n+\tstrbuf_addf(&bisect_refs, \"refs/bisect/%s\", name_bad);\n+\tstatus = for_each_ref_in_submodule(submodule, bisect_refs.buf, fn, cb_data);\n+\tstrbuf_release(&bisect_refs);\n+\treturn status;\n }\n \n static int for_each_good_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data)\n {\n-\treturn for_each_ref_in_submodule(submodule, \"refs/bisect/good\", fn, cb_data);\n+\tstruct strbuf bisect_refs = STRBUF_INIT;\n+\tint status;\n+\tstrbuf_addf(&bisect_refs, \"refs/bisect/%s\", name_good);\n+\tstatus = for_each_ref_in_submodule(submodule, bisect_refs.buf, fn, cb_data);\n+\tstrbuf_release(&bisect_refs);\n+\treturn status;\n }\n \n static int handle_revision_pseudo_opt(const char *submodule,\n@@ -2112,6 +2127,7 @@ static int handle_revision_pseudo_opt(const char *submodule,\n \t\thandle_refs(submodule, revs, *flags, for_each_branch_ref_submodule);\n \t\tclear_ref_exclusion(&revs->ref_excludes);\n \t} else if (!strcmp(arg, \"--bisect\")) {\n+\t\tread_bisect_terms(&name_bad, &name_good);\n \t\thandle_refs(submodule, revs, *flags, for_each_bad_bisect_ref);\n \t\thandle_refs(submodule, revs, *flags ^ (UNINTERESTING | BOTTOM), for_each_good_bisect_ref);\n \t\trevs->bisect = 1;\n-- \n2.4.4.414.g59d82e6\n"},{"id":"264731","messageId":"1435159062-23468-5-git-send-email-Matthieu.Moy@imag.fr","threadId":"39695","inReplyTo":"1435159062-23468-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH v8 4/5] bisect: add the terms old/new","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-24T15:17:41Z","receivedAt":"2015-06-24T15:17:41Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"From: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\n\nWhen not looking for a regression during a bisect but for a fix or a\nchange in another given property, it can be confusing to use 'good'\nand 'bad'.\n\nThis patch introduce `git bisect new` and `git bisect old` as an\nalternative to 'bad' and good': the commits which have a certain\nproperty must be marked as `new` and the ones which do not as `old`.\n\nThe output will be the first commit after the change in the property.\nDuring a new/old bisect session you cannot use bad/good commands and\nvice-versa.\n\nSome commands are still not available for old/new:\n     * git rev-list --bisect does not treat the revs/bisect/new and\n       revs/bisect/old-SHA1 files.\n\nOld discussions:\n\t- http://thread.gmane.org/gmane.comp.version-control.git/86063\n\t\tintroduced bisect fix unfixed to find fix.\n\t- http://thread.gmane.org/gmane.comp.version-control.git/182398\n\t\tdiscussion around bisect yes/no or old/new.\n\t- http://thread.gmane.org/gmane.comp.version-control.git/199758\n\t\tlast discussion and reviews\nNew discussions:\n\t- http://thread.gmane.org/gmane.comp.version-control.git/271320\n\t\t( v2 1/7-4/7 )\n\t- http://comments.gmane.org/gmane.comp.version-control.git/271343\n\t\t( v2 5/7-7/7 )\n\nSigned-off-by: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\nSigned-off-by: Louis Stuber <stuberl@ensimag.grenoble-inp.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n Documentation/git-bisect.txt | 48 ++++++++++++++++++++++++++++++++++++++++++--\n bisect.c                     | 11 +++++++---\n git-bisect.sh                | 30 ++++++++++++++++++---------\n t/t6030-bisect-porcelain.sh  | 38 +++++++++++++++++++++++++++++++++++\n 4 files changed, 112 insertions(+), 15 deletions(-)\n\ndiff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt\nindex 4cb52a7..3c3021a 100644\n--- a/Documentation/git-bisect.txt\n+++ b/Documentation/git-bisect.txt\n@@ -18,8 +18,8 @@ on the subcommand:\n \n  git bisect help\n  git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<paths>...]\n- git bisect bad [<rev>]\n- git bisect good [<rev>...]\n+ git bisect (bad|new) [<rev>]\n+ git bisect (good|old) [<rev>...]\n  git bisect skip [(<rev>|<range>)...]\n  git bisect reset [<commit>]\n  git bisect visualize\n@@ -104,6 +104,35 @@ For example, `git bisect reset HEAD` will leave you on the current\n bisection commit and avoid switching commits at all, while `git bisect\n reset bisect/bad` will check out the first bad revision.\n \n+\n+Alternative terms: bisect new and bisect old\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+If you are not at ease with the terms \"bad\" and \"good\", perhaps\n+because you are looking for the commit that introduced a fix, you can\n+alternatively use \"new\" and \"old\" instead.\n+But note that you cannot mix \"bad\" and good\" with \"new\" and \"old\".\n+\n+------------------------------------------------\n+git bisect new [<rev>]\n+------------------------------------------------\n+\n+Marks the commit as new, e.g. \"the bug is no longer there\", if you are looking\n+for a commit that fixed a bug, or \"the feature that used to work is now broken\n+at this point\", if you are looking for a commit that introduced a bug.\n+It is the equivalent of \"git bisect bad [<rev>]\".\n+\n+------------------------------------------------\n+git bisect old [<rev>...]\n+------------------------------------------------\n+\n+Marks the commit as old, as the opposite of 'git bisect new'.\n+It is the equivalent of \"git bisect good [<rev>...]\".\n+\n+You must run `git bisect start` without commits as argument and run\n+`git bisect new <rev>`/`git bisect old <rev>...` after to add the\n+commits.\n+\n Bisect visualize\n ~~~~~~~~~~~~~~~~\n \n@@ -379,6 +408,21 @@ In this case, when 'git bisect run' finishes, bisect/bad will refer to a commit\n has at least one parent whose reachable graph is fully traversable in the sense\n required by 'git pack objects'.\n \n+* Look for a fix instead of a regression in the code\n++\n+------------\n+$ git bisect start\n+$ git bisect new HEAD    # current commit is marked as new\n+$ git bisect old HEAD~10 # the tenth commit from now is marked as old\n+------------\n++\n+Let's consider the last commit has a given property, and that we are looking\n+for the commit which introduced this property. For each commit the bisection\n+guide us to, we will test if the property is present. If it is we will mark\n+the commit as new with 'git bisect new', otherwise we will mark it as old.\n+At the end of the bisect session, the result will be the first new commit (e.g\n+the first one with the property).\n+\n \n SEE ALSO\n --------\ndiff --git a/bisect.c b/bisect.c\nindex 08be634..ab09650 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -746,6 +746,11 @@ static void handle_bad_merge_base(void)\n \t\t\t\t\"This means the bug has been fixed \"\n \t\t\t\t\"between %s and [%s].\\n\",\n \t\t\t\tbad_hex, bad_hex, good_hex);\n+\t\t} else if (!strcmp(name_bad, \"new\")) {\n+\t\t\tfprintf(stderr, \"The merge base %s is new.\\n\"\n+\t\t\t\t\"The property has changed \"\n+\t\t\t\t\"between %s and [%s].\\n\",\n+\t\t\t\tbad_hex, bad_hex, good_hex);\n \t\t} else {\n \t\t\tfprintf(stderr, \"The merge base %s is %s.\\n\"\n \t\t\t\t\"This means the first commit marked %s is \"\n@@ -778,11 +783,11 @@ static void handle_skipped_merge_base(const unsigned char *mb)\n }\n \n /*\n- * \"check_merge_bases\" checks that merge bases are not \"bad\".\n+ * \"check_merge_bases\" checks that merge bases are not \"bad\" (or \"new\").\n  *\n- * - If one is \"bad\", it means the user assumed something wrong\n+ * - If one is \"bad\" (or \"new\"), it means the user assumed something wrong\n  * and we must exit with a non 0 error code.\n- * - If one is \"good\", that's good, we have nothing to do.\n+ * - If one is \"good\" (or \"old\"), that's good, we have nothing to do.\n  * - If one is \"skipped\", we can't know but we should warn.\n  * - If we don't know, we should check it out and ask the user to test.\n  */\ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex 7bb18db..73763a2 100644\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -1,14 +1,16 @@\n #!/bin/sh\n \n-USAGE='[help|start|bad|good|skip|next|reset|visualize|replay|log|run]'\n+USAGE='[help|start|bad|good|new|old|skip|next|reset|visualize|replay|log|run]'\n LONG_USAGE='git bisect help\n \tprint this long help message.\n git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<pathspec>...]\n \treset bisect state and start bisection.\n-git bisect bad [<rev>]\n-\tmark <rev> a known-bad revision.\n-git bisect good [<rev>...]\n-\tmark <rev>... known-good revisions.\n+git bisect (bad|new) [<rev>]\n+\tmark <rev> a known-bad revision/\n+\t\ta revision after change in a given property.\n+git bisect (good|old) [<rev>...]\n+\tmark <rev>... known-good revisions/\n+\t\trevisions before change in a given property.\n git bisect skip [(<rev>|<range>)...]\n \tmark <rev>... untestable revisions.\n git bisect next\n@@ -288,7 +290,7 @@ bisect_next_check() {\n \t\tfalse\n \t\t;;\n \tt,,\"$NAME_GOOD\")\n-\t\t# have bad but not good.  we could bisect although\n+\t\t# have bad (or new) but not good (or old).  we could bisect although\n \t\t# this is less optimum.\n \t\teval_gettextln \"Warning: bisecting only with a \\$NAME_BAD commit.\" >&2\n \t\tif test -t 0\n@@ -529,7 +531,7 @@ get_terms () {\n check_and_set_terms () {\n \tcmd=\"$1\"\n \tcase \"$cmd\" in\n-\tbad|good)\n+\tbad|good|new|old)\n \t\tif test -s \"$GIT_DIR/BISECT_TERMS\" && test \"$cmd\" != \"$NAME_BAD\" && test \"$cmd\" != \"$NAME_GOOD\"\n \t\tthen\n \t\t\tdie \"$(eval_gettext \"Invalid command: you're currently in a \\$NAME_BAD/\\$NAME_GOOD bisect.\")\"\n@@ -543,14 +545,22 @@ check_and_set_terms () {\n \t\t\tfi\n \t\t\tNAME_BAD=\"bad\"\n \t\t\tNAME_GOOD=\"good\" ;;\n+\t\tnew|old)\n+\t\t\tif ! test -s \"$GIT_DIR/BISECT_TERMS\"\n+\t\t\tthen\n+\t\t\t\techo \"new\" >\"$GIT_DIR/BISECT_TERMS\" &&\n+\t\t\t\techo \"old\" >>\"$GIT_DIR/BISECT_TERMS\"\n+\t\t\tfi\n+\t\t\tNAME_BAD=\"new\"\n+\t\t\tNAME_GOOD=\"old\" ;;\n \t\tesac ;;\n \tesac\n }\n \n bisect_voc () {\n \tcase \"$1\" in\n-\tbad) echo \"bad\" ;;\n-\tgood) echo \"good\" ;;\n+\tbad) echo \"bad|old\" ;;\n+\tgood) echo \"good|new\" ;;\n \tesac\n }\n \n@@ -566,7 +576,7 @@ case \"$#\" in\n \t\tgit bisect -h ;;\n \tstart)\n \t\tbisect_start \"$@\" ;;\n-\tbad|good)\n+\tbad|good|new|old)\n \t\tbisect_state \"$cmd\" \"$@\" ;;\n \tskip)\n \t\tbisect_skip \"$@\" ;;\ndiff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh\nindex 9e2c203..983c503 100755\n--- a/t/t6030-bisect-porcelain.sh\n+++ b/t/t6030-bisect-porcelain.sh\n@@ -759,4 +759,42 @@ test_expect_success '\"git bisect bad HEAD\" behaves as \"git bisect bad\"' '\n \tgit bisect reset\n '\n \n+test_expect_success 'bisect starts with only one new' '\n+\tgit bisect reset &&\n+\tgit bisect start &&\n+\tgit bisect new $HASH4 &&\n+\tgit bisect next\n+'\n+\n+test_expect_success 'bisect does not start with only one old' '\n+\tgit bisect reset &&\n+\tgit bisect start &&\n+\tgit bisect old $HASH1 &&\n+\ttest_must_fail git bisect next\n+'\n+\n+test_expect_success 'bisect start with one new and old' '\n+\tgit bisect reset &&\n+\tgit bisect start &&\n+\tgit bisect old $HASH1 &&\n+\tgit bisect new $HASH4 &&\n+\tgit bisect new &&\n+\tgit bisect new >bisect_result &&\n+\tgrep \"$HASH2 is the first new commit\" bisect_result &&\n+\tgit bisect log >log_to_replay.txt &&\n+\tgit bisect reset\n+'\n+\n+test_expect_success 'bisect replay with old and new' '\n+\tgit bisect replay log_to_replay.txt >bisect_result &&\n+\tgrep \"$HASH2 is the first new commit\" bisect_result &&\n+\tgit bisect reset\n+'\n+\n+test_expect_success 'bisect cannot mix old/new and good/bad' '\n+\tgit bisect start &&\n+\tgit bisect bad $HASH4 &&\n+\ttest_must_fail git bisect old $HASH1\n+'\n+\n test_done\n-- \n2.4.4.414.g59d82e6\n"},{"id":"264728","messageId":"1435159062-23468-6-git-send-email-Matthieu.Moy@imag.fr","threadId":"39695","inReplyTo":"1435159062-23468-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH v8 5/5] bisect: allow any terms set by user","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-24T15:17:42Z","receivedAt":"2015-06-24T15:17:42Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"From: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\n\nIntroduction of the git bisect terms function.\nThe user can set its own terms.\nIt will work exactly like before. The terms must be set\nbefore the start.\n\nSigned-off-by: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\nSigned-off-by: Louis Stuber <stuberl@ensimag.grenoble-inp.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n Documentation/git-bisect.txt | 19 +++++++++++++\n git-bisect.sh                | 68 ++++++++++++++++++++++++++++++++++++++++----\n t/t6030-bisect-porcelain.sh  | 43 ++++++++++++++++++++++++++++\n 3 files changed, 125 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt\nindex 3c3021a..a37336e 100644\n--- a/Documentation/git-bisect.txt\n+++ b/Documentation/git-bisect.txt\n@@ -133,6 +133,25 @@ You must run `git bisect start` without commits as argument and run\n `git bisect new <rev>`/`git bisect old <rev>...` after to add the\n commits.\n \n+Alternative terms: use your own terms\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+If the builtins terms bad/good and new/old do not satisfy you, you can\n+set your own terms.\n+\n+------------------------------------------------\n+git bisect terms term1 term2\n+------------------------------------------------\n+\n+This command has to be used before a bisection has started.\n+The term1 must be associated with the latest revisions and term2 with the\n+ancestors of term1.\n+\n+Only the first bisection following the 'git bisect terms' will use the terms.\n+If you mistyped one of the terms you can do again 'git bisect terms term1\n+term2'.\n+\n+\n Bisect visualize\n ~~~~~~~~~~~~~~~~\n \ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex 73763a2..8ef2b94 100644\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -1,6 +1,6 @@\n #!/bin/sh\n \n-USAGE='[help|start|bad|good|new|old|skip|next|reset|visualize|replay|log|run]'\n+USAGE='[help|start|bad|good|new|old|terms|skip|next|reset|visualize|replay|log|run]'\n LONG_USAGE='git bisect help\n \tprint this long help message.\n git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<pathspec>...]\n@@ -11,6 +11,8 @@ git bisect (bad|new) [<rev>]\n git bisect (good|old) [<rev>...]\n \tmark <rev>... known-good revisions/\n \t\trevisions before change in a given property.\n+git bisect terms term1 term2\n+\tset up term1 and term2 as bisection terms.\n git bisect skip [(<rev>|<range>)...]\n \tmark <rev>... untestable revisions.\n git bisect next\n@@ -82,6 +84,14 @@ bisect_start() {\n \t# revision_seen is true if a git bisect start\n \t# has revision as arguments\n \trevision_seen=0\n+\t# terms_defined is used to detect if the user\n+\t# defined his own terms with git bisect terms\n+\tterms_defined=0\n+\tif test -s \"$GIT_DIR/TERMS_DEFINED\"\n+\tthen\n+\t\tterms_defined=1\n+\t\tget_terms\n+\tfi\n \tif test \"z$(git rev-parse --is-bare-repository)\" != zfalse\n \tthen\n \t\tmode=--no-checkout\n@@ -180,10 +190,14 @@ bisect_start() {\n \t} &&\n \tgit rev-parse --sq-quote \"$@\" >\"$GIT_DIR/BISECT_NAMES\" &&\n \teval \"$eval true\" &&\n-\tif test $revision_seen -eq 1 && test ! -s \"$GIT_DIR/BISECT_TERMS\"\n+\tif test $revision_seen -eq 1 && test ! -s \"$GIT_DIR/BISECT_TERMS\" || test $terms_defined -eq 1\n \tthen\n \t\techo \"$NAME_BAD\" >\"$GIT_DIR/BISECT_TERMS\" &&\n-\t\techo \"$NAME_GOOD\" >>\"$GIT_DIR/BISECT_TERMS\"\n+\t\techo \"$NAME_GOOD\" >>\"$GIT_DIR/BISECT_TERMS\" &&\n+\t\tif test $terms_defined -eq 1\n+\t\tthen\n+\t\t\techo \"git bisect terms $NAME_BAD $NAME_GOOD\" >>\"$GIT_DIR/BISECT_LOG\" || exit\n+\t\tfi\n \tfi &&\n \techo \"git bisect start$orig_args\" >>\"$GIT_DIR/BISECT_LOG\" || exit\n \t#\n@@ -419,6 +433,7 @@ bisect_clean_state() {\n \trm -f \"$GIT_DIR/BISECT_NAMES\" &&\n \trm -f \"$GIT_DIR/BISECT_RUN\" &&\n \trm -f \"$GIT_DIR/BISECT_TERMS\" &&\n+\trm -f \"$GIT_DIR/TERMS_DEFINED\" &&\n \t# Cleanup head-name if it got left by an old version of git-bisect\n \trm -f \"$GIT_DIR/head-name\" &&\n \tgit update-ref -d --no-deref BISECT_HEAD &&\n@@ -447,6 +462,8 @@ bisect_replay () {\n \t\t\teval \"$cmd\" ;;\n \t\t\"$NAME_GOOD\"|\"$NAME_BAD\"|skip)\n \t\t\tbisect_write \"$command\" \"$rev\" ;;\n+\t\tterms)\n+\t\t\tbisect_terms $rev ;;\n \t\t*)\n \t\t\tdie \"$(gettext \"?? what are you talking about?\")\" ;;\n \t\tesac\n@@ -531,7 +548,8 @@ get_terms () {\n check_and_set_terms () {\n \tcmd=\"$1\"\n \tcase \"$cmd\" in\n-\tbad|good|new|old)\n+\tskip|start|terms) ;;\n+\t*)\n \t\tif test -s \"$GIT_DIR/BISECT_TERMS\" && test \"$cmd\" != \"$NAME_BAD\" && test \"$cmd\" != \"$NAME_GOOD\"\n \t\tthen\n \t\t\tdie \"$(eval_gettext \"Invalid command: you're currently in a \\$NAME_BAD/\\$NAME_GOOD bisect.\")\"\n@@ -564,6 +582,44 @@ bisect_voc () {\n \tesac\n }\n \n+bisect_terms () {\n+\tcase \"$#\" in\n+\t0)\n+\t\tif test -s \"$GIT_DIR/BISECT_TERMS\"\n+\t\tthen\n+\t\t\t{\n+\t\t\tread term1\n+\t\t\tread term2\n+\t\t\t}<\"$GIT_DIR/BISECT_TERMS\"\n+\t\t\tgettextln \"Your current terms are $term1 and $term2.\"\n+\t\telse\n+\t\t\tdie \"$(gettext \"No terms defined.\")\"\n+\t\tfi ;;\n+\t2)\n+\t\tcheck_term_format refs/bisect/\"$1\"\n+\t\tcheck_term_format refs/bisect/\"$2\"\n+\t\tif ! test -s \"$GIT_DIR/BISECT_START\"\n+\t\tthen\n+\t\t\techo $1 >\"$GIT_DIR/BISECT_TERMS\" &&\n+\t\t\techo $2 >>\"$GIT_DIR/BISECT_TERMS\" &&\n+\t\t\techo \"1\" >\"$GIT_DIR/TERMS_DEFINED\"\n+\t\t\techo \"git bisect terms $NAME_BAD $NAME_GOOD\" >>\"$GIT_DIR/BISECT_LOG\" || exit\n+\t\telse\n+\t\t\tdie \"$(gettext \"A bisection has already started, and you can't change terms in the middle of it.\n+Use 'git bisect terms' to see the current terms.\n+Otherwise, to start a new bisection with new terms, please use 'git bisect reset' and set the terms before the start\")\"\n+\t\tfi ;;\n+\t*)\n+\t\tusage ;;\n+\tesac\n+}\n+\n+check_term_format () {\n+\targ=\"$1\"\n+\tgit check-ref-format $arg ||\n+\tdie \"$(eval_gettext \"'\\$arg' is not a valid term\")\"\n+}\n+\n case \"$#\" in\n 0)\n \tusage ;;\n@@ -576,7 +632,7 @@ case \"$#\" in\n \t\tgit bisect -h ;;\n \tstart)\n \t\tbisect_start \"$@\" ;;\n-\tbad|good|new|old)\n+\tbad|good|new|old|\"$NAME_BAD\"|\"$NAME_GOOD\")\n \t\tbisect_state \"$cmd\" \"$@\" ;;\n \tskip)\n \t\tbisect_skip \"$@\" ;;\n@@ -593,6 +649,8 @@ case \"$#\" in\n \t\tbisect_log ;;\n \trun)\n \t\tbisect_run \"$@\" ;;\n+\tterms)\n+\t\tbisect_terms \"$@\" ;;\n \t*)\n \t\tusage ;;\n \tesac\ndiff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh\nindex 983c503..289dbb0 100755\n--- a/t/t6030-bisect-porcelain.sh\n+++ b/t/t6030-bisect-porcelain.sh\n@@ -797,4 +797,47 @@ test_expect_success 'bisect cannot mix old/new and good/bad' '\n \ttest_must_fail git bisect old $HASH1\n '\n \n+test_expect_success 'bisect start with one term1 and term2' '\n+\tgit bisect reset &&\n+\tgit bisect terms term1 term2 &&\n+\tgit bisect start &&\n+\tgit bisect term2 $HASH1 &&\n+\tgit bisect term1 $HASH4 &&\n+\tgit bisect term1 &&\n+\tgit bisect term1 >bisect_result &&\n+\tgrep \"$HASH2 is the first term1 commit\" bisect_result &&\n+\tgit bisect log >log_to_replay.txt &&\n+\tgit bisect reset\n+'\n+\n+test_expect_success 'bisect replay with term1 and term2' '\n+\tgit bisect replay log_to_replay.txt >bisect_result &&\n+\tgrep \"$HASH2 is the first term1 commit\" bisect_result &&\n+\tgit bisect reset\n+'\n+\n+test_expect_success 'bisect start term1 term2' '\n+\tgit bisect reset &&\n+\tgit bisect terms term1 term2 &&\n+\tgit bisect start $HASH4 $HASH1 &&\n+\tgit bisect term1 &&\n+\tgit bisect term1 >bisect_result &&\n+\tgrep \"$HASH2 is the first term1 commit\" bisect_result &&\n+\tgit bisect log >log_to_replay.txt &&\n+\tgit bisect reset\n+'\n+\n+test_expect_success 'bisect cannot mix terms' '\n+\tgit bisect reset &&\n+\tgit bisect terms a b &&\n+\tgit bisect terms term1 term2 &&\n+\tgit bisect start $HASH4 $HASH1 &&\n+\ttest_must_fail git bisect a &&\n+\ttest_must_fail git bisect b &&\n+\ttest_must_fail git bisect bad &&\n+\ttest_must_fail git bisect good &&\n+\ttest_must_fail git bisect new &&\n+\ttest_must_fail git bisect old\n+'\n+\n test_done\n-- \n2.4.4.414.g59d82e6\n"},{"id":"264740","messageId":"xmqqioad9fvc.fsf@gitster.dls.corp.google.com","threadId":"39695","inReplyTo":"1435159062-23468-1-git-send-email-Matthieu.Moy@imag.fr","subject":"Re: [PATCH v8 0/5] Bisect terms","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-06-24T17:27:03Z","receivedAt":"2015-06-24T17:27:03Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthieu Moy <Matthieu.Moy@imag.fr> writes:\n\n> This is a minor iteration over v7 to take into account Junio and\n> Eric's comments, AND fix an important typo that I introduced in the\n> strbuf code conversion (I used name_good instead of name_bad). This\n> fixes the \"git bisect visualize\" bug I found earlier. I played a bit\n> with the result and didn't find any bug.\n\nIt seems that [3/5] essentially is the same from the previous round,\nthough.  I'll have more comments on it In-Reply-To that message.\n\nThanks.\n"},{"id":"264741","messageId":"xmqqegl19frm.fsf@gitster.dls.corp.google.com","threadId":"39695","inReplyTo":"1435159062-23468-4-git-send-email-Matthieu.Moy@imag.fr","subject":"Re: [PATCH v8 3/5] bisect: simplify the addition of new bisect terms","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-06-24T17:29:17Z","receivedAt":"2015-06-24T17:29:17Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthieu Moy <Matthieu.Moy@imag.fr> writes:\n\n> diff --git a/bisect.c b/bisect.c\n> index 2d3dbdc..08be634 100644\n> --- a/bisect.c\n> +++ b/bisect.c\n> @@ -747,7 +747,10 @@ static void handle_bad_merge_base(void)\n>  \t\t\t\t\"between %s and [%s].\\n\",\n>  \t\t\t\tbad_hex, bad_hex, good_hex);\n>  \t\t} else {\n> -\t\t\tdie(\"BUG: terms %s/%s not managed\", name_bad, name_good);\n> +\t\t\tfprintf(stderr, \"The merge base %s is %s.\\n\"\n> +\t\t\t\t\"This means the first commit marked %s is \"\n> +\t\t\t\t\"between %s and [%s].\\n\",\n> +\t\t\t\tbad_hex, name_bad, name_bad, bad_hex, good_hex);\n>  \t\t}\n>  \t\texit(3);\n>  \t}\n\nBefore the pre-context of this hunk is\n\n\t\tif (!strcmp(name_bad, \"bad\")) {\n\t\t\tfprintf(stderr, \"The merge base %s is bad.\\n\"\n\t\t\t\t\"This means the bug has been fixed \"\n\nSo, after 5/5, the user could do\n\n\tgit bisect terms bad worse\n\nand get utterly confused.  I think \n\n-\t\tif (!strcmp(name_bad, \"bad\")) {\n+\t\tif (!strcmp(name_bad, \"bad\") && !strcmp(name_good, \"good\") {\n\nneeds to be a part of this step.\n"},{"id":"264744","messageId":"xmqqa8vp9ezq.fsf@gitster.dls.corp.google.com","threadId":"39695","inReplyTo":"1435159062-23468-6-git-send-email-Matthieu.Moy@imag.fr","subject":"Re: [PATCH v8 5/5] bisect: allow any terms set by user","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-06-24T17:46:01Z","receivedAt":"2015-06-24T17:46:01Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthieu Moy <Matthieu.Moy@imag.fr> writes:\n\n> +Alternative terms: use your own terms\n> +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n> +\n> +If the builtins terms bad/good and new/old do not satisfy you, you can\n> +set your own terms.\n> +\n> +------------------------------------------------\n> +git bisect terms term1 term2\n> +------------------------------------------------\n> +\n> +This command has to be used before a bisection has started.\n> +The term1 must be associated with the latest revisions and term2 with the\n> +ancestors of term1.\n\nWhile this is not incorrect per-se, it would be more helpful to tell\nthe readers that they are hunting for a commit that changes the state\nthey would call \"term2\" into \"term1\" somewhere.  e.g.\n\n\t-ancestors of term1.\n\t+ancestors of term1.  For example, if something was buggy in\n        +the old part of the history, you know somewhere the bug was\n\t+fixed, and you want to find the exact commit that fixed it,\n        +you may want to say `git bisect terms fixed broken`; this\n        +way, you would mark a commit that still has the bug with\n        +`broken`, and a newer one after the fix with `fixed`.\n\nor something?\n\n> -USAGE='[help|start|bad|good|new|old|skip|next|reset|visualize|replay|log|run]'\n> +USAGE='[help|start|bad|good|new|old|terms|skip|next|reset|visualize|replay|log|run]'\n>  LONG_USAGE='git bisect help\n>  \tprint this long help message.\n>  git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<pathspec>...]\n> @@ -11,6 +11,8 @@ git bisect (bad|new) [<rev>]\n>  git bisect (good|old) [<rev>...]\n>  \tmark <rev>... known-good revisions/\n>  \t\trevisions before change in a given property.\n> +git bisect terms term1 term2\n> +\tset up term1 and term2 as bisection terms.\n\nThis will not help those who cannot remember which one between these\ntwo they want:\n\n\tgit bisect terms new old\n        git bisect terms old new\n\nI am wondering (together with the documentation patch) if it would\nbe better to be more explicit, instead of term[12], like this:\n\n\tgit bisect terms new old\n\nor even\n\n\tgit bisect terms bad good\n\nassuming that the only reason they use 'terms' is because they are\nsufficiently familiar with 'git bisect' and (intellectually) know\nthat 'bad' is more recent and 'good' is what it used to be, but have\ntrouble remembering which one is which during a hunt for a fix.\n\n> +bisect_terms () {\n> +\tcase \"$#\" in\n> +\t0)\n> +\t\tif test -s \"$GIT_DIR/BISECT_TERMS\"\n> +\t\tthen\n> +\t\t\t{\n> +\t\t\tread term1\n> +\t\t\tread term2\n> +\t\t\t}<\"$GIT_DIR/BISECT_TERMS\"\n> +\t\t\tgettextln \"Your current terms are $term1 and $term2.\"\n\nThe same comment on this part.  Instead of \"git bisect terms\" that\njust says \"You are using $term1 and $term2\", the users would benefit\nif it said \"You are using $term1 for newer state and $term2 for\nolder state\" [*1*].\n\nThanks.\n\n\n[Footnote]\n\n*1* It is funny that I had to rewrite this \"if it said...\" a few\ntimes to make sure I got newer and older right, even though I had\nthe relevant pieces (and only releavant pieces) of information for\nthe doc and help text in a single patch form while composing this\nresponse.  I suspect that an end user without such material would be\na lot more confused than I was.\n"},{"id":"264761","messageId":"xmqq616cao7j.fsf@gitster.dls.corp.google.com","threadId":"39695","inReplyTo":"1435159062-23468-1-git-send-email-Matthieu.Moy@imag.fr","subject":"Re: [PATCH v8 0/5] Bisect terms","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-06-24T19:41:36Z","receivedAt":"2015-06-24T19:41:36Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthieu Moy <Matthieu.Moy@imag.fr> writes:\n\n>  Documentation/git-bisect.txt |  67 +++++++++++++-\n>  bisect.c                     |  94 +++++++++++++++-----\n>  git-bisect.sh                | 207 +++++++++++++++++++++++++++++++++++--------\n>  revision.c                   |  20 ++++-\n>  t/t6030-bisect-porcelain.sh  |  83 ++++++++++++++++-\n>  5 files changed, 407 insertions(+), 64 deletions(-)\n>  mode change 100755 => 100644 git-bisect.sh\n\nHow come nobody noticed this last line so far, during the 7 rounds\nof reviews?\n\nI'll locally fix it up so no need to resend.\n\nThanks.\n"},{"id":"264779","messageId":"vpqioac3in2.fsf@anie.imag.fr","threadId":"39695","inReplyTo":"xmqqa8vp9ezq.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v8 5/5] bisect: allow any terms set by user","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2015-06-24T21:23:45Z","receivedAt":"2015-06-24T21:23:45Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> they would call \"term2\" into \"term1\" somewhere.  e.g.\n>\n> \t-ancestors of term1.\n> \t+ancestors of term1.  For example, if something was buggy in\n>         +the old part of the history, you know somewhere the bug was\n> \t+fixed, and you want to find the exact commit that fixed it,\n>         +you may want to say `git bisect terms fixed broken`; this\n>         +way, you would mark a commit that still has the bug with\n>         +`broken`, and a newer one after the fix with `fixed`.\n>\n> or something?\n\nYes.\n\n> I am wondering (together with the documentation patch) if it would\n> be better to be more explicit, instead of term[12], like this:\n>\n> \tgit bisect terms new old\n\nYes. I eliminated all instance of term1 and term2 in the doc of the\npatch, and replaced with <term-old> and <term-new>.\n\n>> +bisect_terms () {\n>> +\tcase \"$#\" in\n>> +\t0)\n>> +\t\tif test -s \"$GIT_DIR/BISECT_TERMS\"\n>> +\t\tthen\n>> +\t\t\t{\n>> +\t\t\tread term1\n>> +\t\t\tread term2\n>> +\t\t\t}<\"$GIT_DIR/BISECT_TERMS\"\n>> +\t\t\tgettextln \"Your current terms are $term1 and $term2.\"\n>\n> The same comment on this part.  Instead of \"git bisect terms\" that\n> just says \"You are using $term1 and $term2\", the users would benefit\n> if it said \"You are using $term1 for newer state and $term2 for\n> older state\" [*1*].\n\nDone. It's up to date on\n\nhttps://github.com/moy/git/tree/bisect-terms\n\nWill resend.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"264780","messageId":"vpqbng43iif.fsf@anie.imag.fr","threadId":"39695","inReplyTo":"xmqqegl19frm.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v8 3/5] bisect: simplify the addition of new bisect terms","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2015-06-24T21:26:32Z","receivedAt":"2015-06-24T21:26:32Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Matthieu Moy <Matthieu.Moy@imag.fr> writes:\n>\n>> diff --git a/bisect.c b/bisect.c\n>> index 2d3dbdc..08be634 100644\n>> --- a/bisect.c\n>> +++ b/bisect.c\n>> @@ -747,7 +747,10 @@ static void handle_bad_merge_base(void)\n>>  \t\t\t\t\"between %s and [%s].\\n\",\n>>  \t\t\t\tbad_hex, bad_hex, good_hex);\n>>  \t\t} else {\n>> -\t\t\tdie(\"BUG: terms %s/%s not managed\", name_bad, name_good);\n>> +\t\t\tfprintf(stderr, \"The merge base %s is %s.\\n\"\n>> +\t\t\t\t\"This means the first commit marked %s is \"\n>> +\t\t\t\t\"between %s and [%s].\\n\",\n>> +\t\t\t\tbad_hex, name_bad, name_bad, bad_hex, good_hex);\n\nIndeed, I forgot to apply the previous remark. Fixed.\n\n> -\t\tif (!strcmp(name_bad, \"bad\")) {\n> +\t\tif (!strcmp(name_bad, \"bad\") && !strcmp(name_good, \"good\") {\n\nIndeed. Applied.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"264879","messageId":"1435258257-29047-1-git-send-email-Matthieu.Moy@imag.fr","threadId":"39695","inReplyTo":"1435064084-5554-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH v9 0/5] bisect terms","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-25T18:50:52Z","receivedAt":"2015-06-25T18:50:52Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"This version takes into account Junio's remark on the previous series,\nand I did a much more thourough review of the whole, which led to a\nfew fixes (one forgotten strcmp(..., \"bad\") in addition to the other\nnoted by Junio), some style fixes, and some simplifications (the file\nTERMS_DEFINED of PATCH 5 is gone, it was redundant with BISECT_TERMS\nin all cases I could think of).\n\nHopefully, patches 1-4 are actually ready to be merged.\n\nI'm hesitant about patch 5: I actually ended up spending some time\nreviewing it and simplifying it, and I'm tempted to consider it as\nfinished. But it probably lacks more tests and review.\n\ndiff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt\nindex a37336e..e783f87 100644\n--- a/Documentation/git-bisect.txt\n+++ b/Documentation/git-bisect.txt\n@@ -140,16 +140,21 @@ If the builtins terms bad/good and new/old do not satisfy you, you can\n set your own terms.\n \n ------------------------------------------------\n-git bisect terms term1 term2\n+git bisect terms <term-new> <term-old>\n ------------------------------------------------\n \n-This command has to be used before a bisection has started.\n-The term1 must be associated with the latest revisions and term2 with the\n-ancestors of term1.\n-\n-Only the first bisection following the 'git bisect terms' will use the terms.\n-If you mistyped one of the terms you can do again 'git bisect terms term1\n-term2'.\n+This command has to be used before a bisection has started. <term-old>\n+must be associated with the latest revisions and <term-new> with the\n+ancestors of <term-old>. For example, if something was buggy in the\n+old part of the history, you know somewhere the bug was fixed, and you\n+want to find the exact commit that fixed it, you may want to say `git\n+bisect terms fixed broken`; this way, you would mark a commit that\n+still has the bug with `broken`, and a newer one after the fix with\n+`fixed`.\n+\n+Only the first bisection following the `git bisect terms` will use the\n+terms. If you mistyped one of the terms you can do again `git bisect\n+terms <term-old> <term-new>`.\n \n \n Bisect visualize\ndiff --git a/bisect.c b/bisect.c\nindex ab09650..d447b65 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -741,21 +741,21 @@ static void handle_bad_merge_base(void)\n \tif (is_expected_rev(current_bad_oid)) {\n \t\tchar *bad_hex = oid_to_hex(current_bad_oid);\n \t\tchar *good_hex = join_sha1_array_hex(&good_revs, ' ');\n-\t\tif (!strcmp(name_bad, \"bad\")) {\n+\t\tif (!strcmp(name_bad, \"bad\") && !strcmp(name_good, \"good\")) {\n \t\t\tfprintf(stderr, \"The merge base %s is bad.\\n\"\n \t\t\t\t\"This means the bug has been fixed \"\n \t\t\t\t\"between %s and [%s].\\n\",\n \t\t\t\tbad_hex, bad_hex, good_hex);\n-\t\t} else if (!strcmp(name_bad, \"new\")) {\n+\t\t} else if (!strcmp(name_bad, \"new\") && !strcmp(name_good, \"old\")) {\n \t\t\tfprintf(stderr, \"The merge base %s is new.\\n\"\n \t\t\t\t\"The property has changed \"\n \t\t\t\t\"between %s and [%s].\\n\",\n \t\t\t\tbad_hex, bad_hex, good_hex);\n \t\t} else {\n \t\t\tfprintf(stderr, \"The merge base %s is %s.\\n\"\n-\t\t\t\t\"This means the first commit marked %s is \"\n+\t\t\t\t\"This means the first '%s' commit is \"\n \t\t\t\t\"between %s and [%s].\\n\",\n-\t\t\t\tbad_hex, name_bad, name_bad, bad_hex, good_hex);\n+\t\t\t\tbad_hex, name_bad, name_good, bad_hex, good_hex);\n \t\t}\n \t\texit(3);\n \t}\ndiff --git a/git-bisect.sh b/git-bisect.sh\nold mode 100644\nnew mode 100755\nindex 8ef2b94..8fee712\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -11,8 +11,8 @@ git bisect (bad|new) [<rev>]\n git bisect (good|old) [<rev>...]\n \tmark <rev>... known-good revisions/\n \t\trevisions before change in a given property.\n-git bisect terms term1 term2\n-\tset up term1 and term2 as bisection terms.\n+git bisect terms <term-new> <term-old>\n+\tset up <term-new> and <term-old> as terms (default: bad, good)\n git bisect skip [(<rev>|<range>)...]\n \tmark <rev>... untestable revisions.\n git bisect next\n@@ -81,15 +81,15 @@ bisect_start() {\n \torig_args=$(git rev-parse --sq-quote \"$@\")\n \tbad_seen=0\n \teval=''\n-\t# revision_seen is true if a git bisect start\n-\t# has revision as arguments\n-\trevision_seen=0\n-\t# terms_defined is used to detect if the user\n-\t# defined his own terms with git bisect terms\n-\tterms_defined=0\n-\tif test -s \"$GIT_DIR/TERMS_DEFINED\"\n+\tmust_write_terms=0\n+\tmust_log_terms=0\n+\tif test -s \"$GIT_DIR/BISECT_TERMS\"\n \tthen\n-\t\tterms_defined=1\n+\t\t# We're going to restart from a clean state and the\n+\t\t# file will be deleted. Record the old state in\n+\t\t# variables and restore it below.\n+\t\tmust_write_terms=1\n+\t\tmust_log_terms=1\n \t\tget_terms\n \tfi\n \tif test \"z$(git rev-parse --is-bare-repository)\" != zfalse\n@@ -117,7 +117,12 @@ bisect_start() {\n \t\t\t\tbreak\n \t\t\t}\n \n-\t\t\trevision_seen=1\n+\t\t\t# The user ran \"git bisect start <sha1>\n+\t\t\t# <sha1>\", hence did not explicitly specify\n+\t\t\t# the terms, but we are already starting to\n+\t\t\t# set references named with the default terms,\n+\t\t\t# and won't be able to change afterwards.\n+\t\t\tmust_write_terms=1\n \n \t\t\tcase $bad_seen in\n \t\t\t0) state=$NAME_BAD ; bad_seen=1 ;;\n@@ -190,13 +195,13 @@ bisect_start() {\n \t} &&\n \tgit rev-parse --sq-quote \"$@\" >\"$GIT_DIR/BISECT_NAMES\" &&\n \teval \"$eval true\" &&\n-\tif test $revision_seen -eq 1 && test ! -s \"$GIT_DIR/BISECT_TERMS\" || test $terms_defined -eq 1\n+\tif test $must_write_terms -eq 1\n \tthen\n-\t\techo \"$NAME_BAD\" >\"$GIT_DIR/BISECT_TERMS\" &&\n-\t\techo \"$NAME_GOOD\" >>\"$GIT_DIR/BISECT_TERMS\" &&\n-\t\tif test $terms_defined -eq 1\n+\t\twrite_terms \"$NAME_BAD\" \"$NAME_GOOD\" &&\n+\t\tif test $must_log_terms -eq 1\n \t\tthen\n-\t\t\techo \"git bisect terms $NAME_BAD $NAME_GOOD\" >>\"$GIT_DIR/BISECT_LOG\" || exit\n+\t\t\techo \"git bisect terms $NAME_BAD $NAME_GOOD\" \\\n+\t\t\t    >>\"$GIT_DIR/BISECT_LOG\"\n \t\tfi\n \tfi &&\n \techo \"git bisect start$orig_args\" >>\"$GIT_DIR/BISECT_LOG\" || exit\n@@ -433,7 +438,6 @@ bisect_clean_state() {\n \trm -f \"$GIT_DIR/BISECT_NAMES\" &&\n \trm -f \"$GIT_DIR/BISECT_RUN\" &&\n \trm -f \"$GIT_DIR/BISECT_TERMS\" &&\n-\trm -f \"$GIT_DIR/TERMS_DEFINED\" &&\n \t# Cleanup head-name if it got left by an old version of git-bisect\n \trm -f \"$GIT_DIR/head-name\" &&\n \tgit update-ref -d --no-deref BISECT_HEAD &&\n@@ -558,16 +562,14 @@ check_and_set_terms () {\n \t\tbad|good)\n \t\t\tif ! test -s \"$GIT_DIR/BISECT_TERMS\"\n \t\t\tthen\n-\t\t\t\techo \"bad\" >\"$GIT_DIR/BISECT_TERMS\" &&\n-\t\t\t\techo \"good\" >>\"$GIT_DIR/BISECT_TERMS\"\n+\t\t\t\twrite_terms bad good\n \t\t\tfi\n \t\t\tNAME_BAD=\"bad\"\n \t\t\tNAME_GOOD=\"good\" ;;\n \t\tnew|old)\n \t\t\tif ! test -s \"$GIT_DIR/BISECT_TERMS\"\n \t\t\tthen\n-\t\t\t\techo \"new\" >\"$GIT_DIR/BISECT_TERMS\" &&\n-\t\t\t\techo \"old\" >>\"$GIT_DIR/BISECT_TERMS\"\n+\t\t\t\twrite_terms new old\n \t\t\tfi\n \t\t\tNAME_BAD=\"new\"\n \t\t\tNAME_GOOD=\"old\" ;;\n@@ -587,37 +589,40 @@ bisect_terms () {\n \t0)\n \t\tif test -s \"$GIT_DIR/BISECT_TERMS\"\n \t\tthen\n-\t\t\t{\n-\t\t\tread term1\n-\t\t\tread term2\n-\t\t\t}<\"$GIT_DIR/BISECT_TERMS\"\n-\t\t\tgettextln \"Your current terms are $term1 and $term2.\"\n+\t\t\tget_terms\n+\t\t\tgettextln \"Your current terms are $NAME_GOOD for the old state\n+and $NAME_BAD for the new state.\"\n \t\telse\n \t\t\tdie \"$(gettext \"No terms defined.\")\"\n \t\tfi ;;\n \t2)\n-\t\tcheck_term_format refs/bisect/\"$1\"\n-\t\tcheck_term_format refs/bisect/\"$2\"\n \t\tif ! test -s \"$GIT_DIR/BISECT_START\"\n \t\tthen\n-\t\t\techo $1 >\"$GIT_DIR/BISECT_TERMS\" &&\n-\t\t\techo $2 >>\"$GIT_DIR/BISECT_TERMS\" &&\n-\t\t\techo \"1\" >\"$GIT_DIR/TERMS_DEFINED\"\n+\t\t\twrite_terms \"$1\" \"$2\"\n \t\t\techo \"git bisect terms $NAME_BAD $NAME_GOOD\" >>\"$GIT_DIR/BISECT_LOG\" || exit\n \t\telse\n \t\t\tdie \"$(gettext \"A bisection has already started, and you can't change terms in the middle of it.\n Use 'git bisect terms' to see the current terms.\n-Otherwise, to start a new bisection with new terms, please use 'git bisect reset' and set the terms before the start\")\"\n+Otherwise, to start a new bisection with new terms, please use\n+'git bisect reset' and set the terms before the start\")\"\n \t\tfi ;;\n \t*)\n \t\tusage ;;\n \tesac\n }\n \n+write_terms () {\n+\tNAME_BAD=$1\n+\tNAME_GOOD=$2\n+\tcheck_term_format \"$NAME_BAD\"\n+\tcheck_term_format \"$NAME_GOOD\"\n+\tprintf '%s\\n%s\\n' \"$NAME_BAD\" \"$NAME_GOOD\" >\"$GIT_DIR/BISECT_TERMS\"\n+}\n+\n check_term_format () {\n-\targ=\"$1\"\n-\tgit check-ref-format $arg ||\n-\tdie \"$(eval_gettext \"'\\$arg' is not a valid term\")\"\n+\tterm=$1\n+\tgit check-ref-format refs/bisect/\"$term\" ||\n+\tdie \"$(eval_gettext \"'\\$term' is not a valid term\")\"\n }\n \n case \"$#\" in\n\nAntoine Delaite (5):\n  bisect: correction of typo\n  bisect: replace hardcoded \"bad|good\" by variables\n  bisect: simplify the addition of new bisect terms\n  bisect: add the terms old/new\n  bisect: allow any terms set by user\n\n Documentation/git-bisect.txt |  72 ++++++++++++++-\n bisect.c                     |  94 +++++++++++++++----\n git-bisect.sh                | 212 +++++++++++++++++++++++++++++++++++--------\n revision.c                   |  20 +++-\n t/t6030-bisect-porcelain.sh  |  83 ++++++++++++++++-\n 5 files changed, 417 insertions(+), 64 deletions(-)\n\n-- \n2.4.4.414.g318df7a.dirty\n"},{"id":"264883","messageId":"1435258257-29047-2-git-send-email-Matthieu.Moy@imag.fr","threadId":"39695","inReplyTo":"1435258257-29047-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH v9 1/5] bisect: correction of typo","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-25T18:50:53Z","receivedAt":"2015-06-25T18:50:53Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"From: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\n\nSigned-off-by: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n bisect.c                    | 2 +-\n t/t6030-bisect-porcelain.sh | 2 +-\n 2 files changed, 2 insertions(+), 2 deletions(-)\n\ndiff --git a/bisect.c b/bisect.c\nindex 03d5cd9..5b8357d 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -743,7 +743,7 @@ static void handle_bad_merge_base(void)\n \n \tfprintf(stderr, \"Some good revs are not ancestor of the bad rev.\\n\"\n \t\t\"git bisect cannot work properly in this case.\\n\"\n-\t\t\"Maybe you mistake good and bad revs?\\n\");\n+\t\t\"Maybe you mistook good and bad revs?\\n\");\n \texit(1);\n }\n \ndiff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh\nindex 06b4868..9e2c203 100755\n--- a/t/t6030-bisect-porcelain.sh\n+++ b/t/t6030-bisect-porcelain.sh\n@@ -362,7 +362,7 @@ test_expect_success 'bisect starting with a detached HEAD' '\n test_expect_success 'bisect errors out if bad and good are mistaken' '\n \tgit bisect reset &&\n \ttest_must_fail git bisect start $HASH2 $HASH4 2> rev_list_error &&\n-\tgrep \"mistake good and bad\" rev_list_error &&\n+\tgrep \"mistook good and bad\" rev_list_error &&\n \tgit bisect reset\n '\n \n-- \n2.4.4.414.g318df7a.dirty\n"},{"id":"264881","messageId":"1435258257-29047-3-git-send-email-Matthieu.Moy@imag.fr","threadId":"39695","inReplyTo":"1435258257-29047-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH v9 2/5] bisect: replace hardcoded \"bad|good\" by variables","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-25T18:50:54Z","receivedAt":"2015-06-25T18:50:54Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"From: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\n\nTo add new tags like old/new and have keywords less confusing, the\nfirst step is to avoid hardcoding the keywords.\n\nThe default mode is still bad/good.\n\nSigned-off-by: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\nSigned-off-by: Louis Stuber <stuberl@ensimag.grenoble-inp.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n bisect.c      | 54 +++++++++++++++++++++++++++++++++++++-----------------\n git-bisect.sh | 57 +++++++++++++++++++++++++++++++--------------------------\n 2 files changed, 68 insertions(+), 43 deletions(-)\n\ndiff --git a/bisect.c b/bisect.c\nindex 5b8357d..9368f6c 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -21,6 +21,9 @@ static const char *argv_checkout[] = {\"checkout\", \"-q\", NULL, \"--\", NULL};\n static const char *argv_show_branch[] = {\"show-branch\", NULL, NULL};\n static const char *argv_update_ref[] = {\"update-ref\", \"--no-deref\", \"BISECT_HEAD\", NULL, NULL};\n \n+static const char *name_bad;\n+static const char *name_good;\n+\n /* Remember to update object flag allocation in object.h */\n #define COUNTED\t\t(1u<<16)\n \n@@ -403,15 +406,21 @@ struct commit_list *find_bisection(struct commit_list *list,\n static int register_ref(const char *refname, const struct object_id *oid,\n \t\t\tint flags, void *cb_data)\n {\n-\tif (!strcmp(refname, \"bad\")) {\n+\tstruct strbuf good_prefix = STRBUF_INIT;\n+\tstrbuf_addstr(&good_prefix, name_good);\n+\tstrbuf_addstr(&good_prefix, \"-\");\n+\n+\tif (!strcmp(refname, name_bad)) {\n \t\tcurrent_bad_oid = xmalloc(sizeof(*current_bad_oid));\n \t\toidcpy(current_bad_oid, oid);\n-\t} else if (starts_with(refname, \"good-\")) {\n+\t} else if (starts_with(refname, good_prefix.buf)) {\n \t\tsha1_array_append(&good_revs, oid->hash);\n \t} else if (starts_with(refname, \"skip-\")) {\n \t\tsha1_array_append(&skipped_revs, oid->hash);\n \t}\n \n+\tstrbuf_release(&good_prefix);\n+\n \treturn 0;\n }\n \n@@ -634,7 +643,7 @@ static void exit_if_skipped_commits(struct commit_list *tried,\n \t\treturn;\n \n \tprintf(\"There are only 'skip'ped commits left to test.\\n\"\n-\t       \"The first bad commit could be any of:\\n\");\n+\t       \"The first %s commit could be any of:\\n\", name_bad);\n \tprint_commit_list(tried, \"%s\\n\", \"%s\\n\");\n \tif (bad)\n \t\tprintf(\"%s\\n\", oid_to_hex(bad));\n@@ -732,18 +741,24 @@ static void handle_bad_merge_base(void)\n \tif (is_expected_rev(current_bad_oid)) {\n \t\tchar *bad_hex = oid_to_hex(current_bad_oid);\n \t\tchar *good_hex = join_sha1_array_hex(&good_revs, ' ');\n-\n-\t\tfprintf(stderr, \"The merge base %s is bad.\\n\"\n-\t\t\t\"This means the bug has been fixed \"\n-\t\t\t\"between %s and [%s].\\n\",\n-\t\t\tbad_hex, bad_hex, good_hex);\n-\n+\t\tif (!strcmp(name_bad, \"bad\") && !strcmp(name_good, \"good\")) {\n+\t\t\tfprintf(stderr, \"The merge base %s is bad.\\n\"\n+\t\t\t\t\"This means the bug has been fixed \"\n+\t\t\t\t\"between %s and [%s].\\n\",\n+\t\t\t\tbad_hex, bad_hex, good_hex);\n+\t\t} else {\n+\t\t\tfprintf(stderr, \"The merge base %s is %s.\\n\"\n+\t\t\t\t\"This means the first '%s' commit is \"\n+\t\t\t\t\"between %s and [%s].\\n\",\n+\t\t\t\tbad_hex, name_bad, name_good, bad_hex, good_hex);\n+\t\t}\n \t\texit(3);\n \t}\n \n-\tfprintf(stderr, \"Some good revs are not ancestor of the bad rev.\\n\"\n+\tfprintf(stderr, \"Some %s revs are not ancestor of the %s rev.\\n\"\n \t\t\"git bisect cannot work properly in this case.\\n\"\n-\t\t\"Maybe you mistook good and bad revs?\\n\");\n+\t\t\"Maybe you mistook %s and %s revs?\\n\",\n+\t\tname_good, name_bad, name_good, name_bad);\n \texit(1);\n }\n \n@@ -755,10 +770,10 @@ static void handle_skipped_merge_base(const unsigned char *mb)\n \n \twarning(\"the merge base between %s and [%s] \"\n \t\t\"must be skipped.\\n\"\n-\t\t\"So we cannot be sure the first bad commit is \"\n+\t\t\"So we cannot be sure the first %s commit is \"\n \t\t\"between %s and %s.\\n\"\n \t\t\"We continue anyway.\",\n-\t\tbad_hex, good_hex, mb_hex, bad_hex);\n+\t\tbad_hex, good_hex, name_bad, mb_hex, bad_hex);\n \tfree(good_hex);\n }\n \n@@ -839,7 +854,7 @@ static void check_good_are_ancestors_of_bad(const char *prefix, int no_checkout)\n \tint fd;\n \n \tif (!current_bad_oid)\n-\t\tdie(\"a bad revision is needed\");\n+\t\tdie(\"a %s revision is needed\", name_bad);\n \n \t/* Check if file BISECT_ANCESTORS_OK exists. */\n \tif (!stat(filename, &st) && S_ISREG(st.st_mode))\n@@ -905,6 +920,8 @@ int bisect_next_all(const char *prefix, int no_checkout)\n \tconst unsigned char *bisect_rev;\n \tchar bisect_rev_hex[GIT_SHA1_HEXSZ + 1];\n \n+\tname_bad = \"bad\";\n+\tname_good = \"good\";\n \tif (read_bisect_refs())\n \t\tdie(\"reading bisect refs failed\");\n \n@@ -926,8 +943,10 @@ int bisect_next_all(const char *prefix, int no_checkout)\n \t\t */\n \t\texit_if_skipped_commits(tried, NULL);\n \n-\t\tprintf(\"%s was both good and bad\\n\",\n-\t\t       oid_to_hex(current_bad_oid));\n+\t\tprintf(\"%s was both %s and %s\\n\",\n+\t\t       oid_to_hex(current_bad_oid),\n+\t\t       name_good,\n+\t\t       name_bad);\n \t\texit(1);\n \t}\n \n@@ -942,7 +961,8 @@ int bisect_next_all(const char *prefix, int no_checkout)\n \n \tif (!hashcmp(bisect_rev, current_bad_oid->hash)) {\n \t\texit_if_skipped_commits(tried, current_bad_oid);\n-\t\tprintf(\"%s is the first bad commit\\n\", bisect_rev_hex);\n+\t\tprintf(\"%s is the first %s commit\\n\", bisect_rev_hex,\n+\t\t\tname_bad);\n \t\tshow_diff_tree(prefix, revs.commits->item);\n \t\t/* This means the bisection process succeeded. */\n \t\texit(10);\ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex ae3fec2..ce6412f 100755\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -32,6 +32,8 @@ OPTIONS_SPEC=\n \n _x40='[0-9a-f][0-9a-f][0-9a-f][0-9a-f][0-9a-f]'\n _x40=\"$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40\"\n+NAME_BAD=bad\n+NAME_GOOD=good\n \n bisect_head()\n {\n@@ -100,8 +102,8 @@ bisect_start() {\n \t\t\t\tbreak\n \t\t\t}\n \t\t\tcase $bad_seen in\n-\t\t\t0) state='bad' ; bad_seen=1 ;;\n-\t\t\t*) state='good' ;;\n+\t\t\t0) state=$NAME_BAD ; bad_seen=1 ;;\n+\t\t\t*) state=$NAME_GOOD ;;\n \t\t\tesac\n \t\t\teval=\"$eval bisect_write '$state' '$rev' 'nolog' &&\"\n \t\t\tshift\n@@ -184,9 +186,12 @@ bisect_write() {\n \trev=\"$2\"\n \tnolog=\"$3\"\n \tcase \"$state\" in\n-\t\tbad)\t\ttag=\"$state\" ;;\n-\t\tgood|skip)\ttag=\"$state\"-\"$rev\" ;;\n-\t\t*)\t\tdie \"$(eval_gettext \"Bad bisect_write argument: \\$state\")\" ;;\n+\t\t\"$NAME_BAD\")\n+\t\t\ttag=\"$state\" ;;\n+\t\t\"$NAME_GOOD\"|skip)\n+\t\t\ttag=\"$state\"-\"$rev\" ;;\n+\t\t*)\n+\t\t\tdie \"$(eval_gettext \"Bad bisect_write argument: \\$state\")\" ;;\n \tesac\n \tgit update-ref \"refs/bisect/$tag\" \"$rev\" || exit\n \techo \"# $state: $(git show-branch $rev)\" >>\"$GIT_DIR/BISECT_LOG\"\n@@ -230,12 +235,12 @@ bisect_state() {\n \tcase \"$#,$state\" in\n \t0,*)\n \t\tdie \"$(gettext \"Please call 'bisect_state' with at least one argument.\")\" ;;\n-\t1,bad|1,good|1,skip)\n+\t1,\"$NAME_BAD\"|1,\"$NAME_GOOD\"|1,skip)\n \t\trev=$(git rev-parse --verify $(bisect_head)) ||\n \t\t\tdie \"$(gettext \"Bad rev input: $(bisect_head)\")\"\n \t\tbisect_write \"$state\" \"$rev\"\n \t\tcheck_expected_revs \"$rev\" ;;\n-\t2,bad|*,good|*,skip)\n+\t2,\"$NAME_BAD\"|*,\"$NAME_GOOD\"|*,skip)\n \t\tshift\n \t\thash_list=''\n \t\tfor rev in \"$@\"\n@@ -249,8 +254,8 @@ bisect_state() {\n \t\t\tbisect_write \"$state\" \"$rev\"\n \t\tdone\n \t\tcheck_expected_revs $hash_list ;;\n-\t*,bad)\n-\t\tdie \"$(gettext \"'git bisect bad' can take only one argument.\")\" ;;\n+\t*,\"$NAME_BAD\")\n+\t\tdie \"$(eval_gettext \"'git bisect \\$NAME_BAD' can take only one argument.\")\" ;;\n \t*)\n \t\tusage ;;\n \tesac\n@@ -259,21 +264,21 @@ bisect_state() {\n \n bisect_next_check() {\n \tmissing_good= missing_bad=\n-\tgit show-ref -q --verify refs/bisect/bad || missing_bad=t\n-\ttest -n \"$(git for-each-ref \"refs/bisect/good-*\")\" || missing_good=t\n+\tgit show-ref -q --verify refs/bisect/$NAME_BAD || missing_bad=t\n+\ttest -n \"$(git for-each-ref \"refs/bisect/$NAME_GOOD-*\")\" || missing_good=t\n \n \tcase \"$missing_good,$missing_bad,$1\" in\n \t,,*)\n-\t\t: have both good and bad - ok\n+\t\t: have both $NAME_GOOD and $NAME_BAD - ok\n \t\t;;\n \t*,)\n \t\t# do not have both but not asked to fail - just report.\n \t\tfalse\n \t\t;;\n-\tt,,good)\n+\tt,,\"$NAME_GOOD\")\n \t\t# have bad but not good.  we could bisect although\n \t\t# this is less optimum.\n-\t\tgettextln \"Warning: bisecting only with a bad commit.\" >&2\n+\t\teval_gettextln \"Warning: bisecting only with a \\$NAME_BAD commit.\" >&2\n \t\tif test -t 0\n \t\tthen\n \t\t\t# TRANSLATORS: Make sure to include [Y] and [n] in your\n@@ -283,7 +288,7 @@ bisect_next_check() {\n \t\t\tread yesno\n \t\t\tcase \"$yesno\" in [Nn]*) exit 1 ;; esac\n \t\tfi\n-\t\t: bisect without good...\n+\t\t: bisect without $NAME_GOOD...\n \t\t;;\n \t*)\n \n@@ -307,7 +312,7 @@ bisect_auto_next() {\n bisect_next() {\n \tcase \"$#\" in 0) ;; *) usage ;; esac\n \tbisect_autostart\n-\tbisect_next_check good\n+\tbisect_next_check $NAME_GOOD\n \n \t# Perform all bisection computation, display and checkout\n \tgit bisect--helper --next-all $(test -f \"$GIT_DIR/BISECT_HEAD\" && echo --no-checkout)\n@@ -316,18 +321,18 @@ bisect_next() {\n \t# Check if we should exit because bisection is finished\n \tif test $res -eq 10\n \tthen\n-\t\tbad_rev=$(git show-ref --hash --verify refs/bisect/bad)\n+\t\tbad_rev=$(git show-ref --hash --verify refs/bisect/$NAME_BAD)\n \t\tbad_commit=$(git show-branch $bad_rev)\n-\t\techo \"# first bad commit: $bad_commit\" >>\"$GIT_DIR/BISECT_LOG\"\n+\t\techo \"# first $NAME_BAD commit: $bad_commit\" >>\"$GIT_DIR/BISECT_LOG\"\n \t\texit 0\n \telif test $res -eq 2\n \tthen\n \t\techo \"# only skipped commits left to test\" >>\"$GIT_DIR/BISECT_LOG\"\n-\t\tgood_revs=$(git for-each-ref --format=\"%(objectname)\" \"refs/bisect/good-*\")\n-\t\tfor skipped in $(git rev-list refs/bisect/bad --not $good_revs)\n+\t\tgood_revs=$(git for-each-ref --format=\"%(objectname)\" \"refs/bisect/$NAME_GOOD-*\")\n+\t\tfor skipped in $(git rev-list refs/bisect/$NAME_BAD --not $good_revs)\n \t\tdo\n \t\t\tskipped_commit=$(git show-branch $skipped)\n-\t\t\techo \"# possible first bad commit: $skipped_commit\" >>\"$GIT_DIR/BISECT_LOG\"\n+\t\t\techo \"# possible first $NAME_BAD commit: $skipped_commit\" >>\"$GIT_DIR/BISECT_LOG\"\n \t\tdone\n \t\texit $res\n \tfi\n@@ -421,7 +426,7 @@ bisect_replay () {\n \t\tstart)\n \t\t\tcmd=\"bisect_start $rev\"\n \t\t\teval \"$cmd\" ;;\n-\t\tgood|bad|skip)\n+\t\t$NAME_GOOD|$NAME_BAD|skip)\n \t\t\tbisect_write \"$command\" \"$rev\" ;;\n \t\t*)\n \t\t\tdie \"$(gettext \"?? what are you talking about?\")\" ;;\n@@ -455,9 +460,9 @@ exit code \\$res from '\\$command' is < 0 or >= 128\" >&2\n \t\t\tstate='skip'\n \t\telif [ $res -gt 0 ]\n \t\tthen\n-\t\t\tstate='bad'\n+\t\t\tstate=\"$NAME_BAD\"\n \t\telse\n-\t\t\tstate='good'\n+\t\t\tstate=\"$NAME_GOOD\"\n \t\tfi\n \n \t\t# We have to use a subshell because \"bisect_state\" can exit.\n@@ -466,7 +471,7 @@ exit code \\$res from '\\$command' is < 0 or >= 128\" >&2\n \n \t\tcat \"$GIT_DIR/BISECT_RUN\"\n \n-\t\tif sane_grep \"first bad commit could be any of\" \"$GIT_DIR/BISECT_RUN\" \\\n+\t\tif sane_grep \"first $NAME_BAD commit could be any of\" \"$GIT_DIR/BISECT_RUN\" \\\n \t\t\t>/dev/null\n \t\tthen\n \t\t\tgettextln \"bisect run cannot continue any more\" >&2\n@@ -480,7 +485,7 @@ exit code \\$res from '\\$command' is < 0 or >= 128\" >&2\n \t\t\texit $res\n \t\tfi\n \n-\t\tif sane_grep \"is the first bad commit\" \"$GIT_DIR/BISECT_RUN\" >/dev/null\n+\t\tif sane_grep \"is the first $NAME_BAD commit\" \"$GIT_DIR/BISECT_RUN\" >/dev/null\n \t\tthen\n \t\t\tgettextln \"bisect run success\"\n \t\t\texit 0;\n-- \n2.4.4.414.g318df7a.dirty\n"},{"id":"264880","messageId":"1435258257-29047-4-git-send-email-Matthieu.Moy@imag.fr","threadId":"39695","inReplyTo":"1435258257-29047-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH v9 3/5] bisect: simplify the addition of new bisect terms","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-25T18:50:55Z","receivedAt":"2015-06-25T18:50:55Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"From: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\n\nWe create a file BISECT_TERMS in the repository .git to be read during a\nbisection. The fonctions to be changed if we add new terms are quite\nfew.\nIn git-bisect.sh :\n\tcheck_and_set_terms\n\tbisect_voc\n\nCo-authored-by: Louis Stuber <stuberl@ensimag.grenoble-inp.fr>\nTweaked-by: Matthieu Moy <Matthieu.Moy@imag.fr>\nSigned-off-by: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\nSigned-off-by: Louis Stuber <stuberl@ensimag.grenoble-inp.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n bisect.c      | 33 ++++++++++++++++++++++++++--\n git-bisect.sh | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++------\n revision.c    | 20 +++++++++++++++--\n 3 files changed, 112 insertions(+), 11 deletions(-)\n\ndiff --git a/bisect.c b/bisect.c\nindex 9368f6c..c5f96eb 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -905,6 +905,36 @@ static void show_diff_tree(const char *prefix, struct commit *commit)\n }\n \n /*\n+ * The terms used for this bisect session are stored in BISECT_TERMS.\n+ * We read them and store them to adapt the messages accordingly.\n+ * Default is bad/good.\n+ */\n+void read_bisect_terms(const char **read_bad, const char **read_good)\n+{\n+\tstruct strbuf str = STRBUF_INIT;\n+\tconst char *filename = git_path(\"BISECT_TERMS\");\n+\tFILE *fp = fopen(filename, \"r\");\n+\n+\tif (!fp) {\n+\t\tif (errno == ENOENT) {\n+\t\t\t*read_bad = \"bad\";\n+\t\t\t*read_good = \"good\";\n+\t\t\treturn;\n+\t\t} else {\n+\t\t\tdie(\"could not read file '%s': %s\", filename,\n+\t\t\t\tstrerror(errno));\n+\t\t}\n+\t} else {\n+\t\tstrbuf_getline(&str, fp, '\\n');\n+\t\t*read_bad = strbuf_detach(&str, NULL);\n+\t\tstrbuf_getline(&str, fp, '\\n');\n+\t\t*read_good = strbuf_detach(&str, NULL);\n+\t}\n+\tstrbuf_release(&str);\n+\tfclose(fp);\n+}\n+\n+/*\n  * We use the convention that exiting with an exit code 10 means that\n  * the bisection process finished successfully.\n  * In this case the calling shell script should exit 0.\n@@ -920,8 +950,7 @@ int bisect_next_all(const char *prefix, int no_checkout)\n \tconst unsigned char *bisect_rev;\n \tchar bisect_rev_hex[GIT_SHA1_HEXSZ + 1];\n \n-\tname_bad = \"bad\";\n-\tname_good = \"good\";\n+\tread_bisect_terms(&name_bad, &name_good);\n \tif (read_bisect_refs())\n \t\tdie(\"reading bisect refs failed\");\n \ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex ce6412f..7bb18db 100755\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -77,6 +77,9 @@ bisect_start() {\n \torig_args=$(git rev-parse --sq-quote \"$@\")\n \tbad_seen=0\n \teval=''\n+\t# revision_seen is true if a git bisect start\n+\t# has revision as arguments\n+\trevision_seen=0\n \tif test \"z$(git rev-parse --is-bare-repository)\" != zfalse\n \tthen\n \t\tmode=--no-checkout\n@@ -101,6 +104,9 @@ bisect_start() {\n \t\t\t\tdie \"$(eval_gettext \"'\\$arg' does not appear to be a valid revision\")\"\n \t\t\t\tbreak\n \t\t\t}\n+\n+\t\t\trevision_seen=1\n+\n \t\t\tcase $bad_seen in\n \t\t\t0) state=$NAME_BAD ; bad_seen=1 ;;\n \t\t\t*) state=$NAME_GOOD ;;\n@@ -172,6 +178,11 @@ bisect_start() {\n \t} &&\n \tgit rev-parse --sq-quote \"$@\" >\"$GIT_DIR/BISECT_NAMES\" &&\n \teval \"$eval true\" &&\n+\tif test $revision_seen -eq 1 && test ! -s \"$GIT_DIR/BISECT_TERMS\"\n+\tthen\n+\t\techo \"$NAME_BAD\" >\"$GIT_DIR/BISECT_TERMS\" &&\n+\t\techo \"$NAME_GOOD\" >>\"$GIT_DIR/BISECT_TERMS\"\n+\tfi &&\n \techo \"git bisect start$orig_args\" >>\"$GIT_DIR/BISECT_LOG\" || exit\n \t#\n \t# Check if we can proceed to the next bisect state.\n@@ -232,6 +243,7 @@ bisect_skip() {\n bisect_state() {\n \tbisect_autostart\n \tstate=$1\n+\tcheck_and_set_terms $state\n \tcase \"$#,$state\" in\n \t0,*)\n \t\tdie \"$(gettext \"Please call 'bisect_state' with at least one argument.\")\" ;;\n@@ -291,15 +303,17 @@ bisect_next_check() {\n \t\t: bisect without $NAME_GOOD...\n \t\t;;\n \t*)\n-\n+\t\tbad_syn=$(bisect_voc bad)\n+\t\tgood_syn=$(bisect_voc good)\n \t\tif test -s \"$GIT_DIR/BISECT_START\"\n \t\tthen\n-\t\t\tgettextln \"You need to give me at least one good and one bad revision.\n-(You can use \\\"git bisect bad\\\" and \\\"git bisect good\\\" for that.)\" >&2\n+\n+\t\t\teval_gettextln \"You need to give me at least one \\$bad_syn and one \\$good_syn revision.\n+(You can use \\\"git bisect \\$bad_syn\\\" and \\\"git bisect \\$good_syn\\\" for that.)\" >&2\n \t\telse\n-\t\t\tgettextln \"You need to start by \\\"git bisect start\\\".\n-You then need to give me at least one good and one bad revision.\n-(You can use \\\"git bisect bad\\\" and \\\"git bisect good\\\" for that.)\" >&2\n+\t\t\teval_gettextln \"You need to start by \\\"git bisect start\\\".\n+You then need to give me at least one \\$good_syn and one \\$bad_syn revision.\n+(You can use \\\"git bisect \\$bad_syn\\\" and \\\"git bisect \\$good_syn\\\" for that.)\" >&2\n \t\tfi\n \t\texit 1 ;;\n \tesac\n@@ -402,6 +416,7 @@ bisect_clean_state() {\n \trm -f \"$GIT_DIR/BISECT_LOG\" &&\n \trm -f \"$GIT_DIR/BISECT_NAMES\" &&\n \trm -f \"$GIT_DIR/BISECT_RUN\" &&\n+\trm -f \"$GIT_DIR/BISECT_TERMS\" &&\n \t# Cleanup head-name if it got left by an old version of git-bisect\n \trm -f \"$GIT_DIR/head-name\" &&\n \tgit update-ref -d --no-deref BISECT_HEAD &&\n@@ -422,11 +437,13 @@ bisect_replay () {\n \t\t\trev=\"$command\"\n \t\t\tcommand=\"$bisect\"\n \t\tfi\n+\t\tget_terms\n+\t\tcheck_and_set_terms \"$command\"\n \t\tcase \"$command\" in\n \t\tstart)\n \t\t\tcmd=\"bisect_start $rev\"\n \t\t\teval \"$cmd\" ;;\n-\t\t$NAME_GOOD|$NAME_BAD|skip)\n+\t\t\"$NAME_GOOD\"|\"$NAME_BAD\"|skip)\n \t\t\tbisect_write \"$command\" \"$rev\" ;;\n \t\t*)\n \t\t\tdie \"$(gettext \"?? what are you talking about?\")\" ;;\n@@ -499,11 +516,50 @@ bisect_log () {\n \tcat \"$GIT_DIR/BISECT_LOG\"\n }\n \n+get_terms () {\n+\tif test -s \"$GIT_DIR/BISECT_TERMS\"\n+\tthen\n+\t\t{\n+\t\tread NAME_BAD\n+\t\tread NAME_GOOD\n+\t\t} <\"$GIT_DIR/BISECT_TERMS\"\n+\tfi\n+}\n+\n+check_and_set_terms () {\n+\tcmd=\"$1\"\n+\tcase \"$cmd\" in\n+\tbad|good)\n+\t\tif test -s \"$GIT_DIR/BISECT_TERMS\" && test \"$cmd\" != \"$NAME_BAD\" && test \"$cmd\" != \"$NAME_GOOD\"\n+\t\tthen\n+\t\t\tdie \"$(eval_gettext \"Invalid command: you're currently in a \\$NAME_BAD/\\$NAME_GOOD bisect.\")\"\n+\t\tfi\n+\t\tcase \"$cmd\" in\n+\t\tbad|good)\n+\t\t\tif ! test -s \"$GIT_DIR/BISECT_TERMS\"\n+\t\t\tthen\n+\t\t\t\techo \"bad\" >\"$GIT_DIR/BISECT_TERMS\" &&\n+\t\t\t\techo \"good\" >>\"$GIT_DIR/BISECT_TERMS\"\n+\t\t\tfi\n+\t\t\tNAME_BAD=\"bad\"\n+\t\t\tNAME_GOOD=\"good\" ;;\n+\t\tesac ;;\n+\tesac\n+}\n+\n+bisect_voc () {\n+\tcase \"$1\" in\n+\tbad) echo \"bad\" ;;\n+\tgood) echo \"good\" ;;\n+\tesac\n+}\n+\n case \"$#\" in\n 0)\n \tusage ;;\n *)\n \tcmd=\"$1\"\n+\tget_terms\n \tshift\n \tcase \"$cmd\" in\n \thelp)\ndiff --git a/revision.c b/revision.c\nindex 3ff8723..24ce842 100644\n--- a/revision.c\n+++ b/revision.c\n@@ -21,6 +21,9 @@\n \n volatile show_early_output_fn_t show_early_output;\n \n+static const char *name_bad;\n+static const char *name_good;\n+\n char *path_name(const struct name_path *path, const char *name)\n {\n \tconst struct name_path *p;\n@@ -2076,14 +2079,26 @@ void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx,\n \tctx->argc -= n;\n }\n \n+extern void read_bisect_terms(const char **bad, const char **good);\n+\n static int for_each_bad_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data)\n {\n-\treturn for_each_ref_in_submodule(submodule, \"refs/bisect/bad\", fn, cb_data);\n+\tstruct strbuf bisect_refs = STRBUF_INIT;\n+\tint status;\n+\tstrbuf_addf(&bisect_refs, \"refs/bisect/%s\", name_bad);\n+\tstatus = for_each_ref_in_submodule(submodule, bisect_refs.buf, fn, cb_data);\n+\tstrbuf_release(&bisect_refs);\n+\treturn status;\n }\n \n static int for_each_good_bisect_ref(const char *submodule, each_ref_fn fn, void *cb_data)\n {\n-\treturn for_each_ref_in_submodule(submodule, \"refs/bisect/good\", fn, cb_data);\n+\tstruct strbuf bisect_refs = STRBUF_INIT;\n+\tint status;\n+\tstrbuf_addf(&bisect_refs, \"refs/bisect/%s\", name_good);\n+\tstatus = for_each_ref_in_submodule(submodule, bisect_refs.buf, fn, cb_data);\n+\tstrbuf_release(&bisect_refs);\n+\treturn status;\n }\n \n static int handle_revision_pseudo_opt(const char *submodule,\n@@ -2112,6 +2127,7 @@ static int handle_revision_pseudo_opt(const char *submodule,\n \t\thandle_refs(submodule, revs, *flags, for_each_branch_ref_submodule);\n \t\tclear_ref_exclusion(&revs->ref_excludes);\n \t} else if (!strcmp(arg, \"--bisect\")) {\n+\t\tread_bisect_terms(&name_bad, &name_good);\n \t\thandle_refs(submodule, revs, *flags, for_each_bad_bisect_ref);\n \t\thandle_refs(submodule, revs, *flags ^ (UNINTERESTING | BOTTOM), for_each_good_bisect_ref);\n \t\trevs->bisect = 1;\n-- \n2.4.4.414.g318df7a.dirty\n"},{"id":"264884","messageId":"1435258257-29047-5-git-send-email-Matthieu.Moy@imag.fr","threadId":"39695","inReplyTo":"1435258257-29047-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH v9 4/5] bisect: add the terms old/new","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-25T18:50:56Z","receivedAt":"2015-06-25T18:50:56Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"From: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\n\nWhen not looking for a regression during a bisect but for a fix or a\nchange in another given property, it can be confusing to use 'good'\nand 'bad'.\n\nThis patch introduce `git bisect new` and `git bisect old` as an\nalternative to 'bad' and good': the commits which have a certain\nproperty must be marked as `new` and the ones which do not as `old`.\n\nThe output will be the first commit after the change in the property.\nDuring a new/old bisect session you cannot use bad/good commands and\nvice-versa.\n\nSome commands are still not available for old/new:\n     * git rev-list --bisect does not treat the revs/bisect/new and\n       revs/bisect/old-SHA1 files.\n\nOld discussions:\n\t- http://thread.gmane.org/gmane.comp.version-control.git/86063\n\t\tintroduced bisect fix unfixed to find fix.\n\t- http://thread.gmane.org/gmane.comp.version-control.git/182398\n\t\tdiscussion around bisect yes/no or old/new.\n\t- http://thread.gmane.org/gmane.comp.version-control.git/199758\n\t\tlast discussion and reviews\nNew discussions:\n\t- http://thread.gmane.org/gmane.comp.version-control.git/271320\n\t\t( v2 1/7-4/7 )\n\t- http://comments.gmane.org/gmane.comp.version-control.git/271343\n\t\t( v2 5/7-7/7 )\n\nSigned-off-by: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\nSigned-off-by: Louis Stuber <stuberl@ensimag.grenoble-inp.fr>\nSigned-off-by: Valentin Duperray <Valentin.Duperray@ensimag.imag.fr>\nSigned-off-by: Franck Jonas <Franck.Jonas@ensimag.imag.fr>\nSigned-off-by: Lucien Kong <Lucien.Kong@ensimag.imag.fr>\nSigned-off-by: Thomas Nguy <Thomas.Nguy@ensimag.imag.fr>\nSigned-off-by: Huynh Khoi Nguyen Nguyen <Huynh-Khoi-Nguyen.Nguyen@ensimag.imag.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n Documentation/git-bisect.txt | 48 ++++++++++++++++++++++++++++++++++++++++++--\n bisect.c                     | 11 +++++++---\n git-bisect.sh                | 43 +++++++++++++++++++++++++--------------\n t/t6030-bisect-porcelain.sh  | 38 +++++++++++++++++++++++++++++++++++\n 4 files changed, 120 insertions(+), 20 deletions(-)\n\ndiff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt\nindex 4cb52a7..3c3021a 100644\n--- a/Documentation/git-bisect.txt\n+++ b/Documentation/git-bisect.txt\n@@ -18,8 +18,8 @@ on the subcommand:\n \n  git bisect help\n  git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<paths>...]\n- git bisect bad [<rev>]\n- git bisect good [<rev>...]\n+ git bisect (bad|new) [<rev>]\n+ git bisect (good|old) [<rev>...]\n  git bisect skip [(<rev>|<range>)...]\n  git bisect reset [<commit>]\n  git bisect visualize\n@@ -104,6 +104,35 @@ For example, `git bisect reset HEAD` will leave you on the current\n bisection commit and avoid switching commits at all, while `git bisect\n reset bisect/bad` will check out the first bad revision.\n \n+\n+Alternative terms: bisect new and bisect old\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+If you are not at ease with the terms \"bad\" and \"good\", perhaps\n+because you are looking for the commit that introduced a fix, you can\n+alternatively use \"new\" and \"old\" instead.\n+But note that you cannot mix \"bad\" and good\" with \"new\" and \"old\".\n+\n+------------------------------------------------\n+git bisect new [<rev>]\n+------------------------------------------------\n+\n+Marks the commit as new, e.g. \"the bug is no longer there\", if you are looking\n+for a commit that fixed a bug, or \"the feature that used to work is now broken\n+at this point\", if you are looking for a commit that introduced a bug.\n+It is the equivalent of \"git bisect bad [<rev>]\".\n+\n+------------------------------------------------\n+git bisect old [<rev>...]\n+------------------------------------------------\n+\n+Marks the commit as old, as the opposite of 'git bisect new'.\n+It is the equivalent of \"git bisect good [<rev>...]\".\n+\n+You must run `git bisect start` without commits as argument and run\n+`git bisect new <rev>`/`git bisect old <rev>...` after to add the\n+commits.\n+\n Bisect visualize\n ~~~~~~~~~~~~~~~~\n \n@@ -379,6 +408,21 @@ In this case, when 'git bisect run' finishes, bisect/bad will refer to a commit\n has at least one parent whose reachable graph is fully traversable in the sense\n required by 'git pack objects'.\n \n+* Look for a fix instead of a regression in the code\n++\n+------------\n+$ git bisect start\n+$ git bisect new HEAD    # current commit is marked as new\n+$ git bisect old HEAD~10 # the tenth commit from now is marked as old\n+------------\n++\n+Let's consider the last commit has a given property, and that we are looking\n+for the commit which introduced this property. For each commit the bisection\n+guide us to, we will test if the property is present. If it is we will mark\n+the commit as new with 'git bisect new', otherwise we will mark it as old.\n+At the end of the bisect session, the result will be the first new commit (e.g\n+the first one with the property).\n+\n \n SEE ALSO\n --------\ndiff --git a/bisect.c b/bisect.c\nindex c5f96eb..d447b65 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -746,6 +746,11 @@ static void handle_bad_merge_base(void)\n \t\t\t\t\"This means the bug has been fixed \"\n \t\t\t\t\"between %s and [%s].\\n\",\n \t\t\t\tbad_hex, bad_hex, good_hex);\n+\t\t} else if (!strcmp(name_bad, \"new\") && !strcmp(name_good, \"old\")) {\n+\t\t\tfprintf(stderr, \"The merge base %s is new.\\n\"\n+\t\t\t\t\"The property has changed \"\n+\t\t\t\t\"between %s and [%s].\\n\",\n+\t\t\t\tbad_hex, bad_hex, good_hex);\n \t\t} else {\n \t\t\tfprintf(stderr, \"The merge base %s is %s.\\n\"\n \t\t\t\t\"This means the first '%s' commit is \"\n@@ -778,11 +783,11 @@ static void handle_skipped_merge_base(const unsigned char *mb)\n }\n \n /*\n- * \"check_merge_bases\" checks that merge bases are not \"bad\".\n+ * \"check_merge_bases\" checks that merge bases are not \"bad\" (or \"new\").\n  *\n- * - If one is \"bad\", it means the user assumed something wrong\n+ * - If one is \"bad\" (or \"new\"), it means the user assumed something wrong\n  * and we must exit with a non 0 error code.\n- * - If one is \"good\", that's good, we have nothing to do.\n+ * - If one is \"good\" (or \"old\"), that's good, we have nothing to do.\n  * - If one is \"skipped\", we can't know but we should warn.\n  * - If we don't know, we should check it out and ask the user to test.\n  */\ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex 7bb18db..569898b 100755\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -1,14 +1,16 @@\n #!/bin/sh\n \n-USAGE='[help|start|bad|good|skip|next|reset|visualize|replay|log|run]'\n+USAGE='[help|start|bad|good|new|old|skip|next|reset|visualize|replay|log|run]'\n LONG_USAGE='git bisect help\n \tprint this long help message.\n git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<pathspec>...]\n \treset bisect state and start bisection.\n-git bisect bad [<rev>]\n-\tmark <rev> a known-bad revision.\n-git bisect good [<rev>...]\n-\tmark <rev>... known-good revisions.\n+git bisect (bad|new) [<rev>]\n+\tmark <rev> a known-bad revision/\n+\t\ta revision after change in a given property.\n+git bisect (good|old) [<rev>...]\n+\tmark <rev>... known-good revisions/\n+\t\trevisions before change in a given property.\n git bisect skip [(<rev>|<range>)...]\n \tmark <rev>... untestable revisions.\n git bisect next\n@@ -77,9 +79,7 @@ bisect_start() {\n \torig_args=$(git rev-parse --sq-quote \"$@\")\n \tbad_seen=0\n \teval=''\n-\t# revision_seen is true if a git bisect start\n-\t# has revision as arguments\n-\trevision_seen=0\n+\tmust_write_terms=0\n \tif test \"z$(git rev-parse --is-bare-repository)\" != zfalse\n \tthen\n \t\tmode=--no-checkout\n@@ -105,7 +105,12 @@ bisect_start() {\n \t\t\t\tbreak\n \t\t\t}\n \n-\t\t\trevision_seen=1\n+\t\t\t# The user ran \"git bisect start <sha1>\n+\t\t\t# <sha1>\", hence did not explicitly specify\n+\t\t\t# the terms, but we are already starting to\n+\t\t\t# set references named with the default terms,\n+\t\t\t# and won't be able to change afterwards.\n+\t\t\tmust_write_terms=1\n \n \t\t\tcase $bad_seen in\n \t\t\t0) state=$NAME_BAD ; bad_seen=1 ;;\n@@ -178,7 +183,7 @@ bisect_start() {\n \t} &&\n \tgit rev-parse --sq-quote \"$@\" >\"$GIT_DIR/BISECT_NAMES\" &&\n \teval \"$eval true\" &&\n-\tif test $revision_seen -eq 1 && test ! -s \"$GIT_DIR/BISECT_TERMS\"\n+\tif test $must_write_terms -eq 1 && test ! -s \"$GIT_DIR/BISECT_TERMS\"\n \tthen\n \t\techo \"$NAME_BAD\" >\"$GIT_DIR/BISECT_TERMS\" &&\n \t\techo \"$NAME_GOOD\" >>\"$GIT_DIR/BISECT_TERMS\"\n@@ -288,7 +293,7 @@ bisect_next_check() {\n \t\tfalse\n \t\t;;\n \tt,,\"$NAME_GOOD\")\n-\t\t# have bad but not good.  we could bisect although\n+\t\t# have bad (or new) but not good (or old).  we could bisect although\n \t\t# this is less optimum.\n \t\teval_gettextln \"Warning: bisecting only with a \\$NAME_BAD commit.\" >&2\n \t\tif test -t 0\n@@ -529,7 +534,7 @@ get_terms () {\n check_and_set_terms () {\n \tcmd=\"$1\"\n \tcase \"$cmd\" in\n-\tbad|good)\n+\tbad|good|new|old)\n \t\tif test -s \"$GIT_DIR/BISECT_TERMS\" && test \"$cmd\" != \"$NAME_BAD\" && test \"$cmd\" != \"$NAME_GOOD\"\n \t\tthen\n \t\t\tdie \"$(eval_gettext \"Invalid command: you're currently in a \\$NAME_BAD/\\$NAME_GOOD bisect.\")\"\n@@ -543,14 +548,22 @@ check_and_set_terms () {\n \t\t\tfi\n \t\t\tNAME_BAD=\"bad\"\n \t\t\tNAME_GOOD=\"good\" ;;\n+\t\tnew|old)\n+\t\t\tif ! test -s \"$GIT_DIR/BISECT_TERMS\"\n+\t\t\tthen\n+\t\t\t\techo \"new\" >\"$GIT_DIR/BISECT_TERMS\" &&\n+\t\t\t\techo \"old\" >>\"$GIT_DIR/BISECT_TERMS\"\n+\t\t\tfi\n+\t\t\tNAME_BAD=\"new\"\n+\t\t\tNAME_GOOD=\"old\" ;;\n \t\tesac ;;\n \tesac\n }\n \n bisect_voc () {\n \tcase \"$1\" in\n-\tbad) echo \"bad\" ;;\n-\tgood) echo \"good\" ;;\n+\tbad) echo \"bad|old\" ;;\n+\tgood) echo \"good|new\" ;;\n \tesac\n }\n \n@@ -566,7 +579,7 @@ case \"$#\" in\n \t\tgit bisect -h ;;\n \tstart)\n \t\tbisect_start \"$@\" ;;\n-\tbad|good)\n+\tbad|good|new|old)\n \t\tbisect_state \"$cmd\" \"$@\" ;;\n \tskip)\n \t\tbisect_skip \"$@\" ;;\ndiff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh\nindex 9e2c203..983c503 100755\n--- a/t/t6030-bisect-porcelain.sh\n+++ b/t/t6030-bisect-porcelain.sh\n@@ -759,4 +759,42 @@ test_expect_success '\"git bisect bad HEAD\" behaves as \"git bisect bad\"' '\n \tgit bisect reset\n '\n \n+test_expect_success 'bisect starts with only one new' '\n+\tgit bisect reset &&\n+\tgit bisect start &&\n+\tgit bisect new $HASH4 &&\n+\tgit bisect next\n+'\n+\n+test_expect_success 'bisect does not start with only one old' '\n+\tgit bisect reset &&\n+\tgit bisect start &&\n+\tgit bisect old $HASH1 &&\n+\ttest_must_fail git bisect next\n+'\n+\n+test_expect_success 'bisect start with one new and old' '\n+\tgit bisect reset &&\n+\tgit bisect start &&\n+\tgit bisect old $HASH1 &&\n+\tgit bisect new $HASH4 &&\n+\tgit bisect new &&\n+\tgit bisect new >bisect_result &&\n+\tgrep \"$HASH2 is the first new commit\" bisect_result &&\n+\tgit bisect log >log_to_replay.txt &&\n+\tgit bisect reset\n+'\n+\n+test_expect_success 'bisect replay with old and new' '\n+\tgit bisect replay log_to_replay.txt >bisect_result &&\n+\tgrep \"$HASH2 is the first new commit\" bisect_result &&\n+\tgit bisect reset\n+'\n+\n+test_expect_success 'bisect cannot mix old/new and good/bad' '\n+\tgit bisect start &&\n+\tgit bisect bad $HASH4 &&\n+\ttest_must_fail git bisect old $HASH1\n+'\n+\n test_done\n-- \n2.4.4.414.g318df7a.dirty\n"},{"id":"264882","messageId":"1435258257-29047-6-git-send-email-Matthieu.Moy@imag.fr","threadId":"39695","inReplyTo":"1435258257-29047-1-git-send-email-Matthieu.Moy@imag.fr","subject":"[PATCH v9 5/5] bisect: allow any terms set by user","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@imag.fr","sentAt":"2015-06-25T18:50:57Z","receivedAt":"2015-06-25T18:50:57Z","isPatch":true,"sender":{"key":"git@matthieu-moy.fr","avatar":"https://avatars.githubusercontent.com/u/14709?v=4"},"body":"From: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\n\nIntroduction of the git bisect terms command. The user can set his own\nterms. It will work exactly like before. The terms must be set before the\nstart.\n\nSigned-off-by: Antoine Delaite <antoine.delaite@ensimag.grenoble-inp.fr>\nSigned-off-by: Louis Stuber <stuberl@ensimag.grenoble-inp.fr>\nSigned-off-by: Matthieu Moy <Matthieu.Moy@imag.fr>\n---\n Documentation/git-bisect.txt | 24 +++++++++++++\n git-bisect.sh                | 80 ++++++++++++++++++++++++++++++++++++++------\n t/t6030-bisect-porcelain.sh  | 43 ++++++++++++++++++++++++\n 3 files changed, 137 insertions(+), 10 deletions(-)\n\ndiff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt\nindex 3c3021a..e783f87 100644\n--- a/Documentation/git-bisect.txt\n+++ b/Documentation/git-bisect.txt\n@@ -133,6 +133,30 @@ You must run `git bisect start` without commits as argument and run\n `git bisect new <rev>`/`git bisect old <rev>...` after to add the\n commits.\n \n+Alternative terms: use your own terms\n+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n+\n+If the builtins terms bad/good and new/old do not satisfy you, you can\n+set your own terms.\n+\n+------------------------------------------------\n+git bisect terms <term-new> <term-old>\n+------------------------------------------------\n+\n+This command has to be used before a bisection has started. <term-old>\n+must be associated with the latest revisions and <term-new> with the\n+ancestors of <term-old>. For example, if something was buggy in the\n+old part of the history, you know somewhere the bug was fixed, and you\n+want to find the exact commit that fixed it, you may want to say `git\n+bisect terms fixed broken`; this way, you would mark a commit that\n+still has the bug with `broken`, and a newer one after the fix with\n+`fixed`.\n+\n+Only the first bisection following the `git bisect terms` will use the\n+terms. If you mistyped one of the terms you can do again `git bisect\n+terms <term-old> <term-new>`.\n+\n+\n Bisect visualize\n ~~~~~~~~~~~~~~~~\n \ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex 569898b..8fee712 100755\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -1,6 +1,6 @@\n #!/bin/sh\n \n-USAGE='[help|start|bad|good|new|old|skip|next|reset|visualize|replay|log|run]'\n+USAGE='[help|start|bad|good|new|old|terms|skip|next|reset|visualize|replay|log|run]'\n LONG_USAGE='git bisect help\n \tprint this long help message.\n git bisect start [--no-checkout] [<bad> [<good>...]] [--] [<pathspec>...]\n@@ -11,6 +11,8 @@ git bisect (bad|new) [<rev>]\n git bisect (good|old) [<rev>...]\n \tmark <rev>... known-good revisions/\n \t\trevisions before change in a given property.\n+git bisect terms <term-new> <term-old>\n+\tset up <term-new> and <term-old> as terms (default: bad, good)\n git bisect skip [(<rev>|<range>)...]\n \tmark <rev>... untestable revisions.\n git bisect next\n@@ -80,6 +82,16 @@ bisect_start() {\n \tbad_seen=0\n \teval=''\n \tmust_write_terms=0\n+\tmust_log_terms=0\n+\tif test -s \"$GIT_DIR/BISECT_TERMS\"\n+\tthen\n+\t\t# We're going to restart from a clean state and the\n+\t\t# file will be deleted. Record the old state in\n+\t\t# variables and restore it below.\n+\t\tmust_write_terms=1\n+\t\tmust_log_terms=1\n+\t\tget_terms\n+\tfi\n \tif test \"z$(git rev-parse --is-bare-repository)\" != zfalse\n \tthen\n \t\tmode=--no-checkout\n@@ -183,10 +195,14 @@ bisect_start() {\n \t} &&\n \tgit rev-parse --sq-quote \"$@\" >\"$GIT_DIR/BISECT_NAMES\" &&\n \teval \"$eval true\" &&\n-\tif test $must_write_terms -eq 1 && test ! -s \"$GIT_DIR/BISECT_TERMS\"\n+\tif test $must_write_terms -eq 1\n \tthen\n-\t\techo \"$NAME_BAD\" >\"$GIT_DIR/BISECT_TERMS\" &&\n-\t\techo \"$NAME_GOOD\" >>\"$GIT_DIR/BISECT_TERMS\"\n+\t\twrite_terms \"$NAME_BAD\" \"$NAME_GOOD\" &&\n+\t\tif test $must_log_terms -eq 1\n+\t\tthen\n+\t\t\techo \"git bisect terms $NAME_BAD $NAME_GOOD\" \\\n+\t\t\t    >>\"$GIT_DIR/BISECT_LOG\"\n+\t\tfi\n \tfi &&\n \techo \"git bisect start$orig_args\" >>\"$GIT_DIR/BISECT_LOG\" || exit\n \t#\n@@ -450,6 +466,8 @@ bisect_replay () {\n \t\t\teval \"$cmd\" ;;\n \t\t\"$NAME_GOOD\"|\"$NAME_BAD\"|skip)\n \t\t\tbisect_write \"$command\" \"$rev\" ;;\n+\t\tterms)\n+\t\t\tbisect_terms $rev ;;\n \t\t*)\n \t\t\tdie \"$(gettext \"?? what are you talking about?\")\" ;;\n \t\tesac\n@@ -534,7 +552,8 @@ get_terms () {\n check_and_set_terms () {\n \tcmd=\"$1\"\n \tcase \"$cmd\" in\n-\tbad|good|new|old)\n+\tskip|start|terms) ;;\n+\t*)\n \t\tif test -s \"$GIT_DIR/BISECT_TERMS\" && test \"$cmd\" != \"$NAME_BAD\" && test \"$cmd\" != \"$NAME_GOOD\"\n \t\tthen\n \t\t\tdie \"$(eval_gettext \"Invalid command: you're currently in a \\$NAME_BAD/\\$NAME_GOOD bisect.\")\"\n@@ -543,16 +562,14 @@ check_and_set_terms () {\n \t\tbad|good)\n \t\t\tif ! test -s \"$GIT_DIR/BISECT_TERMS\"\n \t\t\tthen\n-\t\t\t\techo \"bad\" >\"$GIT_DIR/BISECT_TERMS\" &&\n-\t\t\t\techo \"good\" >>\"$GIT_DIR/BISECT_TERMS\"\n+\t\t\t\twrite_terms bad good\n \t\t\tfi\n \t\t\tNAME_BAD=\"bad\"\n \t\t\tNAME_GOOD=\"good\" ;;\n \t\tnew|old)\n \t\t\tif ! test -s \"$GIT_DIR/BISECT_TERMS\"\n \t\t\tthen\n-\t\t\t\techo \"new\" >\"$GIT_DIR/BISECT_TERMS\" &&\n-\t\t\t\techo \"old\" >>\"$GIT_DIR/BISECT_TERMS\"\n+\t\t\t\twrite_terms new old\n \t\t\tfi\n \t\t\tNAME_BAD=\"new\"\n \t\t\tNAME_GOOD=\"old\" ;;\n@@ -567,6 +584,47 @@ bisect_voc () {\n \tesac\n }\n \n+bisect_terms () {\n+\tcase \"$#\" in\n+\t0)\n+\t\tif test -s \"$GIT_DIR/BISECT_TERMS\"\n+\t\tthen\n+\t\t\tget_terms\n+\t\t\tgettextln \"Your current terms are $NAME_GOOD for the old state\n+and $NAME_BAD for the new state.\"\n+\t\telse\n+\t\t\tdie \"$(gettext \"No terms defined.\")\"\n+\t\tfi ;;\n+\t2)\n+\t\tif ! test -s \"$GIT_DIR/BISECT_START\"\n+\t\tthen\n+\t\t\twrite_terms \"$1\" \"$2\"\n+\t\t\techo \"git bisect terms $NAME_BAD $NAME_GOOD\" >>\"$GIT_DIR/BISECT_LOG\" || exit\n+\t\telse\n+\t\t\tdie \"$(gettext \"A bisection has already started, and you can't change terms in the middle of it.\n+Use 'git bisect terms' to see the current terms.\n+Otherwise, to start a new bisection with new terms, please use\n+'git bisect reset' and set the terms before the start\")\"\n+\t\tfi ;;\n+\t*)\n+\t\tusage ;;\n+\tesac\n+}\n+\n+write_terms () {\n+\tNAME_BAD=$1\n+\tNAME_GOOD=$2\n+\tcheck_term_format \"$NAME_BAD\"\n+\tcheck_term_format \"$NAME_GOOD\"\n+\tprintf '%s\\n%s\\n' \"$NAME_BAD\" \"$NAME_GOOD\" >\"$GIT_DIR/BISECT_TERMS\"\n+}\n+\n+check_term_format () {\n+\tterm=$1\n+\tgit check-ref-format refs/bisect/\"$term\" ||\n+\tdie \"$(eval_gettext \"'\\$term' is not a valid term\")\"\n+}\n+\n case \"$#\" in\n 0)\n \tusage ;;\n@@ -579,7 +637,7 @@ case \"$#\" in\n \t\tgit bisect -h ;;\n \tstart)\n \t\tbisect_start \"$@\" ;;\n-\tbad|good|new|old)\n+\tbad|good|new|old|\"$NAME_BAD\"|\"$NAME_GOOD\")\n \t\tbisect_state \"$cmd\" \"$@\" ;;\n \tskip)\n \t\tbisect_skip \"$@\" ;;\n@@ -596,6 +654,8 @@ case \"$#\" in\n \t\tbisect_log ;;\n \trun)\n \t\tbisect_run \"$@\" ;;\n+\tterms)\n+\t\tbisect_terms \"$@\" ;;\n \t*)\n \t\tusage ;;\n \tesac\ndiff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh\nindex 983c503..289dbb0 100755\n--- a/t/t6030-bisect-porcelain.sh\n+++ b/t/t6030-bisect-porcelain.sh\n@@ -797,4 +797,47 @@ test_expect_success 'bisect cannot mix old/new and good/bad' '\n \ttest_must_fail git bisect old $HASH1\n '\n \n+test_expect_success 'bisect start with one term1 and term2' '\n+\tgit bisect reset &&\n+\tgit bisect terms term1 term2 &&\n+\tgit bisect start &&\n+\tgit bisect term2 $HASH1 &&\n+\tgit bisect term1 $HASH4 &&\n+\tgit bisect term1 &&\n+\tgit bisect term1 >bisect_result &&\n+\tgrep \"$HASH2 is the first term1 commit\" bisect_result &&\n+\tgit bisect log >log_to_replay.txt &&\n+\tgit bisect reset\n+'\n+\n+test_expect_success 'bisect replay with term1 and term2' '\n+\tgit bisect replay log_to_replay.txt >bisect_result &&\n+\tgrep \"$HASH2 is the first term1 commit\" bisect_result &&\n+\tgit bisect reset\n+'\n+\n+test_expect_success 'bisect start term1 term2' '\n+\tgit bisect reset &&\n+\tgit bisect terms term1 term2 &&\n+\tgit bisect start $HASH4 $HASH1 &&\n+\tgit bisect term1 &&\n+\tgit bisect term1 >bisect_result &&\n+\tgrep \"$HASH2 is the first term1 commit\" bisect_result &&\n+\tgit bisect log >log_to_replay.txt &&\n+\tgit bisect reset\n+'\n+\n+test_expect_success 'bisect cannot mix terms' '\n+\tgit bisect reset &&\n+\tgit bisect terms a b &&\n+\tgit bisect terms term1 term2 &&\n+\tgit bisect start $HASH4 $HASH1 &&\n+\ttest_must_fail git bisect a &&\n+\ttest_must_fail git bisect b &&\n+\ttest_must_fail git bisect bad &&\n+\ttest_must_fail git bisect good &&\n+\ttest_must_fail git bisect new &&\n+\ttest_must_fail git bisect old\n+'\n+\n test_done\n-- \n2.4.4.414.g318df7a.dirty\n"},{"id":"264910","messageId":"xmqqk2urwjmq.fsf@gitster.dls.corp.google.com","threadId":"39695","inReplyTo":"1435258257-29047-6-git-send-email-Matthieu.Moy@imag.fr","subject":"Re: [PATCH v9 5/5] bisect: allow any terms set by user","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-06-25T21:41:49Z","receivedAt":"2015-06-25T21:41:49Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthieu Moy <Matthieu.Moy@imag.fr> writes:\n\n> +------------------------------------------------\n> +git bisect terms <term-new> <term-old>\n> +------------------------------------------------\n\nThe mnemonic for \"git bisect start bad good\" is Bad comes before\nGood (B = 0x42, G = 0x47) and this is same for \"new/old\", New comes\nbefore Old (N = 0x4e, O = 0x4f).  \"git bisect terms new old\" follows\nthe same pattern, which is good.  Easy to remember.\n\n> +This command has to be used before a bisection has started. <term-old>\n> +must be associated with the latest revisions and <term-new> with the\n> +ancestors of <term-old>.\n\nWhoa?  This gets new and old mixed up, doesn't it?\n\n> For example, if something was buggy in the\n> +old part of the history, you know somewhere the bug was fixed, and you\n> +want to find the exact commit that fixed it, you may want to say `git\n> +bisect terms fixed broken`; this way, you would mark a commit that\n> +still has the bug with `broken`, and a newer one after the fix with\n> +`fixed`.\n\nSo, it used to be broken, it got fixed recently, so broken is old,\nfixed is new, \"bad/new and then good/old\" mnemonic says you give\n\"fixed broken\" to \"bisect terms\".  OK.\n\n> +Only the first bisection following the `git bisect terms` will use the\n> +terms. If you mistyped one of the terms you can do again `git bisect\n> +terms <term-old> <term-new>`.\n\nThis is also the other way around, no?\n\n> +git bisect terms <term-new> <term-old>\n> +\tset up <term-new> and <term-old> as terms (default: bad, good)\n\nGood.\n"},{"id":"264913","messageId":"xmqqfv5fwib3.fsf@gitster.dls.corp.google.com","threadId":"39695","inReplyTo":"xmqqk2urwjmq.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v9 5/5] bisect: allow any terms set by user","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-06-25T22:10:24Z","receivedAt":"2015-06-25T22:10:24Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n>> +Only the first bisection following the `git bisect terms` will use the\n>> +terms. If you mistyped one of the terms you can do again `git bisect\n>> +terms <term-old> <term-new>`.\n\nThis paragraph may need further polishing.\n\nThe first sentence makes it sound as if this is a valid sequence,\nbut I do not think that is what you meant:\n\n    $ git bisect start master maint\n    $ git bisect bad\n    $ git bisect terms new old\n    $ git bisect old\n    $ git bisect bad\n\nI think what you wanted to say was that \"git bisect terms\" is in\neffect during the single bisect session, and after you are done with\n\"git bisect reset\", the next bisect session, unless you use \"git\nbisect terms\", will use \"bad\" and \"good\", as that is the default\npair of terms.\n\nThe second sentence may want to be something like\n\n\tIf you mistyped one of the terms, you can do another \"git\n\tbisect terms <term-new> <term-old>\" to correct them, but\n\tthat is possible only before you start the bisection.\n\nOtherwise, you invite this\n\n    $ git bisect start master maint\n    $ git bisect terms new olf\n    $ git bisect olf\n    $ git bisect new\n    $ git bisect old\n    ... error message that says you can give either \"new\" and \"olf\"\n    $ git bisect terms new old\n    $ git bisect old\n\nwhich may not work well.\n"},{"id":"264931","messageId":"CAP8UFD1EWYzg7-O4BDgUTQPJOoo6TEAF49amakgfR8K6CX886A@mail.gmail.com","threadId":"39695","inReplyTo":"1435258257-29047-5-git-send-email-Matthieu.Moy@imag.fr","subject":"Re: [PATCH v9 4/5] bisect: add the terms old/new","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2015-06-26T04:11:57Z","receivedAt":"2015-06-26T04:11:57Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Thu, Jun 25, 2015 at 8:50 PM, Matthieu Moy <Matthieu.Moy@imag.fr> wrote:\n\n[...]\n\n> @@ -178,7 +183,7 @@ bisect_start() {\n>         } &&\n>         git rev-parse --sq-quote \"$@\" >\"$GIT_DIR/BISECT_NAMES\" &&\n>         eval \"$eval true\" &&\n> -       if test $revision_seen -eq 1 && test ! -s \"$GIT_DIR/BISECT_TERMS\"\n> +       if test $must_write_terms -eq 1 && test ! -s \"$GIT_DIR/BISECT_TERMS\"\n>         then\n>                 echo \"$NAME_BAD\" >\"$GIT_DIR/BISECT_TERMS\" &&\n>                 echo \"$NAME_GOOD\" >>\"$GIT_DIR/BISECT_TERMS\"\n\nYou are writing BISECT_TERMS here...\n\n> @@ -543,14 +548,22 @@ check_and_set_terms () {\n>                         fi\n>                         NAME_BAD=\"bad\"\n>                         NAME_GOOD=\"good\" ;;\n> +               new|old)\n> +                       if ! test -s \"$GIT_DIR/BISECT_TERMS\"\n> +                       then\n> +                               echo \"new\" >\"$GIT_DIR/BISECT_TERMS\" &&\n> +                               echo \"old\" >>\"$GIT_DIR/BISECT_TERMS\"\n> +                       fi\n> +                       NAME_BAD=\"new\"\n> +                       NAME_GOOD=\"old\" ;;\n\n...and here nearly in the same way.\n\nSo perhaps you could use a function like:\n\nwrite_bisect_terms() {\n      if test ! -s \"$GIT_DIR/BISECT_TERMS\"\n      then\n            echo \"$NAME_BAD\" >\"$GIT_DIR/BISECT_TERMS\" &&\n            echo \"$NAME_GOOD\" >>\"$GIT_DIR/BISECT_TERMS\"\n      fi\n}\n"},{"id":"264934","messageId":"vpqy4j7x8eg.fsf@anie.imag.fr","threadId":"39695","inReplyTo":"xmqqk2urwjmq.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v9 5/5] bisect: allow any terms set by user","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2015-06-26T06:59:03Z","receivedAt":"2015-06-26T06:59:03Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Matthieu Moy <Matthieu.Moy@imag.fr> writes:\n>\n>> +------------------------------------------------\n>> +git bisect terms <term-new> <term-old>\n>> +------------------------------------------------\n>\n> The mnemonic for \"git bisect start bad good\" is Bad comes before\n> Good (B = 0x42, G = 0x47) and this is same for \"new/old\", New comes\n> before Old (N = 0x4e, O = 0x4f).  \"git bisect terms new old\" follows\n> the same pattern, which is good.  Easy to remember.\n>\n>> +This command has to be used before a bisection has started. <term-old>\n>> +must be associated with the latest revisions and <term-new> with the\n>> +ancestors of <term-old>.\n>\n> Whoa?  This gets new and old mixed up, doesn't it?\n\nRight. I think it was already the case before, but using term1/term2 in\nthe text made it hard to spot. The new wording is clearer, and makes it\neasier to find bugs in the explanations ;-).\n\n>> +Only the first bisection following the `git bisect terms` will use the\n>> +terms. If you mistyped one of the terms you can do again `git bisect\n>> +terms <term-old> <term-new>`.\n>\n> This is also the other way around, no?\n\nIndeed.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"264935","messageId":"vpqoak3x8bc.fsf@anie.imag.fr","threadId":"39695","inReplyTo":"CAP8UFD1EWYzg7-O4BDgUTQPJOoo6TEAF49amakgfR8K6CX886A@mail.gmail.com","subject":"Re: [PATCH v9 4/5] bisect: add the terms old/new","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2015-06-26T07:00:55Z","receivedAt":"2015-06-26T07:00:55Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Christian Couder <christian.couder@gmail.com> writes:\n\n> So perhaps you could use a function like:\n>\n> write_bisect_terms() {\n>       if test ! -s \"$GIT_DIR/BISECT_TERMS\"\n>       then\n>             echo \"$NAME_BAD\" >\"$GIT_DIR/BISECT_TERMS\" &&\n>             echo \"$NAME_GOOD\" >>\"$GIT_DIR/BISECT_TERMS\"\n>       fi\n> }\n\nI already had it in the last patch, but reworked the code to introduce\nit earlier, and never >\"$GIT_DIR/BISECT_TERMS\" outside this function.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"264939","messageId":"vpqegkyyj7z.fsf@anie.imag.fr","threadId":"39695","inReplyTo":"xmqqfv5fwib3.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v9 5/5] bisect: allow any terms set by user","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2015-06-26T08:20:00Z","receivedAt":"2015-06-26T08:20:00Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> The second sentence may want to be something like\n>\n> \tIf you mistyped one of the terms, you can do another \"git\n> \tbisect terms <term-new> <term-old>\" to correct them, but\n> \tthat is possible only before you start the bisection.\n\nApplied, thanks.\n\nI currently have this in addition to v9 in my branch. I'll resend later\n(https://github.com/moy/git/tree/bisect-terms is up to date).\n\ndiff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt\nindex e783f87..7609cd6 100644\n--- a/Documentation/git-bisect.txt\n+++ b/Documentation/git-bisect.txt\n@@ -143,19 +143,19 @@ set your own terms.\n git bisect terms <term-new> <term-old>\n ------------------------------------------------\n \n-This command has to be used before a bisection has started. <term-old>\n-must be associated with the latest revisions and <term-new> with the\n-ancestors of <term-old>. For example, if something was buggy in the\n+This command has to be used before a bisection has started. <term-new>\n+must be associated with the latest revisions and <term-old> with some\n+ancestors of <term-new>. For example, if something was buggy in the\n old part of the history, you know somewhere the bug was fixed, and you\n want to find the exact commit that fixed it, you may want to say `git\n-bisect terms fixed broken`; this way, you would mark a commit that\n+bisect terms broken fixed`; this way, you would mark a commit that\n still has the bug with `broken`, and a newer one after the fix with\n `fixed`.\n \n-Only the first bisection following the `git bisect terms` will use the\n+Only the bisection following the `git bisect terms` will use the\n terms. If you mistyped one of the terms you can do again `git bisect\n-terms <term-old> <term-new>`.\n-\n+terms <term-new> <term-old>`, but that is possible only before you\n+start the bisection.\n \n Bisect visualize\n ~~~~~~~~~~~~~~~~\ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex 8fee712..07c64d9 100755\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -549,6 +549,20 @@ get_terms () {\n        fi\n }\n \n+write_terms () {\n+       NAME_BAD=$1\n+       NAME_GOOD=$2\n+       check_term_format \"$NAME_BAD\"\n+       check_term_format \"$NAME_GOOD\"\n+       printf '%s\\n%s\\n' \"$NAME_BAD\" \"$NAME_GOOD\" >\"$GIT_DIR/BISECT_TERMS\"\n+}\n+\n+check_term_format () {\n+       term=$1\n+       git check-ref-format refs/bisect/\"$term\" ||\n+       die \"$(eval_gettext \"'\\$term' is not a valid term\")\"\n+}\n+\n check_and_set_terms () {\n        cmd=\"$1\"\n        case \"$cmd\" in\n@@ -579,8 +593,8 @@ check_and_set_terms () {\n \n bisect_voc () {\n        case \"$1\" in\n-       bad) echo \"bad|old\" ;;\n-       good) echo \"good|new\" ;;\n+       bad) echo \"bad|new\" ;;\n+       good) echo \"good|old\" ;;\n        esac\n }\n \n@@ -611,20 +625,6 @@ Otherwise, to start a new bisection with new terms, please use\n        esac\n }\n \n-write_terms () {\n-       NAME_BAD=$1\n-       NAME_GOOD=$2\n-       check_term_format \"$NAME_BAD\"\n-       check_term_format \"$NAME_GOOD\"\n-       printf '%s\\n%s\\n' \"$NAME_BAD\" \"$NAME_GOOD\" >\"$GIT_DIR/BISECT_TERMS\"\n-}\n-\n-check_term_format () {\n-       term=$1\n-       git check-ref-format refs/bisect/\"$term\" ||\n-       die \"$(eval_gettext \"'\\$term' is not a valid term\")\"\n-}\n-\n case \"$#\" in\n 0)\n        usage ;;\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"264962","messageId":"xmqqtwtuv2jr.fsf@gitster.dls.corp.google.com","threadId":"39695","inReplyTo":"vpqegkyyj7z.fsf@anie.imag.fr","subject":"Re: [PATCH v9 5/5] bisect: allow any terms set by user","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-06-26T16:48:24Z","receivedAt":"2015-06-26T16:48:24Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:\n\n> Junio C Hamano <gitster@pobox.com> writes:\n>\n>> The second sentence may want to be something like\n>>\n>> \tIf you mistyped one of the terms, you can do another \"git\n>> \tbisect terms <term-new> <term-old>\" to correct them, but\n>> \tthat is possible only before you start the bisection.\n>\n> Applied, thanks.\n\nI didn't say it out loud while writing the above, but this (and we\nhave other places that use the same phrase in the doc) mentions that\nyou have some point in time where you \"start\" the bisection, without\nhaving a clear definition of where that bisection starts, and that\nbothers me.  \"You can do X until you do Y\", when it is not clear\nwhat Y exactly happens, is not very helpful.\n\nWe who know how bisection works internally know that the point of no\nreturn is when we commit to the two terms and write one of the good\nor bad bisect refs.  At that point, technically we haven't done a\nbisection yet (\"git bisect good maint\" would bisect_autostart, but\nwithout the other end, does not have a graph to bisect yet to find a\nmidpoint).\n\nAnd worse yet, majority of users may read \"git bisect start\" is\nwhere \"you start bisection\", but \"bisect start\" (either called\ndirectly, or via bisect_autostart by the first \"git bisect good\")\nis where you set up the machinery, so doing \"bisect terms\" before\ndoing \"bisect start\" does not make much sense.\n\n\n\n> I currently have this in addition to v9 in my branch. I'll resend later\n> (https://github.com/moy/git/tree/bisect-terms is up to date).\n>\n> diff --git a/Documentation/git-bisect.txt b/Documentation/git-bisect.txt\n> index e783f87..7609cd6 100644\n> --- a/Documentation/git-bisect.txt\n> +++ b/Documentation/git-bisect.txt\n> @@ -143,19 +143,19 @@ set your own terms.\n>  git bisect terms <term-new> <term-old>\n>  ------------------------------------------------\n>  \n> -This command has to be used before a bisection has started. <term-old>\n> -must be associated with the latest revisions and <term-new> with the\n> -ancestors of <term-old>. For example, if something was buggy in the\n> +This command has to be used before a bisection has started. <term-new>\n> +must be associated with the latest revisions and <term-old> with some\n> +ancestors of <term-new>. For example, if something was buggy in the\n>  old part of the history, you know somewhere the bug was fixed, and you\n>  want to find the exact commit that fixed it, you may want to say `git\n> -bisect terms fixed broken`; this way, you would mark a commit that\n> +bisect terms broken fixed`; this way, you would mark a commit that\n\nThe example talks about a bug we used to have that was corrected, so\n\"broken\" is old and \"fixed\" is new.  The earlier parts of this hunk\nare correct but the last line should not be changed, no?\n\nThere unfortunately are two reasons why we cannot flip the order to\n\"git bisect terms old new\":\n\n * \"git bisect start $bad $good\" established the\n   convention to list bad before good (and 'B'ad comes before\n   'G'ood, so does 'N'ew before 'O'ld).\n\n * \"git bisect start $good $bad\", even if we could use a time\n   machine, would not be a good syntax, as you give zero or more\n   good ones and one and only one bad one.\n"},{"id":"264971","messageId":"vpq8ub6s8hc.fsf@anie.imag.fr","threadId":"39695","inReplyTo":"xmqqtwtuv2jr.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v9 5/5] bisect: allow any terms set by user","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2015-06-26T17:08:31Z","receivedAt":"2015-06-26T17:08:31Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> And worse yet, majority of users may read \"git bisect start\" is\n> where \"you start bisection\", but \"bisect start\" (either called\n> directly, or via bisect_autostart by the first \"git bisect good\")\n> is where you set up the machinery, so doing \"bisect terms\" before\n> doing \"bisect start\" does not make much sense.\n\nThis is currently how it's implemented. You need to say\n\n$ git bisect terms foo bar\n$ git bisect start\n\nAnd indeed \"git bisect terms foo bar\" errors out. I think the reason it\nis this way is to allow\n\n$ git bisect terms foo bar\n$ git bisect start <sha1> <sha1>\n\nBut actually, we can allow \"git bisect terms\" until BISECT_TERMS is\ncreated, which is your intuition and makes more sense IMHO. I'll try to\ndo that.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"},{"id":"264980","messageId":"xmqq1tgyuyuy.fsf@gitster.dls.corp.google.com","threadId":"39695","inReplyTo":"vpq8ub6s8hc.fsf@anie.imag.fr","subject":"Re: [PATCH v9 5/5] bisect: allow any terms set by user","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2015-06-26T18:08:05Z","receivedAt":"2015-06-26T18:08:05Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:\n\n> This is currently how it's implemented. You need to say\n>\n> $ git bisect terms foo bar\n> $ git bisect start\n\nAhh, it means everything including the description (i.e. \"you start\nbisection\") is consistent and perfectly fine.\n\nI misread the patch, it seems.  Sorry for the noise.\n\nThanks.\n\n> And indeed \"git bisect terms foo bar\" errors out. I think the reason it\n> is this way is to allow\n>\n> $ git bisect terms foo bar\n> $ git bisect start <sha1> <sha1>\n>\n> But actually, we can allow \"git bisect terms\" until BISECT_TERMS is\n> created, which is your intuition and makes more sense IMHO. I'll try to\n> do that.\n\nI am not sure if it is a good idea, though.  Matching the intuition\nof those who (think they) know how it is implemented is much less\nimportant than providing a behaviour that is simple to explain to\ncasual users.\n"},{"id":"264990","messageId":"vpqvbeaql4c.fsf@anie.imag.fr","threadId":"39695","inReplyTo":"xmqq1tgyuyuy.fsf@gitster.dls.corp.google.com","subject":"Re: [PATCH v9 5/5] bisect: allow any terms set by user","fromName":"Matthieu Moy","fromEmail":"matthieu.moy@grenoble-inp.fr","sentAt":"2015-06-26T20:18:27Z","receivedAt":"2015-06-26T20:18:27Z","isPatch":true,"sender":{"key":"matthieu.moy@grenoble-inp.fr","avatar":"https://gravatar.com/avatar/72c8a2705971a25dfaff23cece15130d405685845d911aedd5667ace277f3fc5?d=mp&s=160"},"body":"Junio C Hamano <gitster@pobox.com> writes:\n\n> Matthieu Moy <Matthieu.Moy@grenoble-inp.fr> writes:\n>\n>> And indeed \"git bisect terms foo bar\" errors out. I think the reason it\n>> is this way is to allow\n>>\n>> $ git bisect terms foo bar\n>> $ git bisect start <sha1> <sha1>\n>>\n>> But actually, we can allow \"git bisect terms\" until BISECT_TERMS is\n>> created, which is your intuition and makes more sense IMHO. I'll try to\n>> do that.\n>\n> I am not sure if it is a good idea, though.  Matching the intuition\n> of those who (think they) know how it is implemented is much less\n> important than providing a behaviour that is simple to explain to\n> casual users.\n\nI thought about it a bit more. Essentially, we have two options simple\nto implement:\n\n1) Allow `git bisect terms` when BISECT_TERMS does not exists. This\n   prevents running `git bisect terms` twice in a row, but would match\n   your first guess: we could still run it until the terms are commited.\n \n   Pro: it feels more natural to me to write\n \n   git bisect start\n   git bisect terms foo bar\n   ...\n   git bisect reset\n \n   => everything happens between start and reset.\n\n2) Allow `git bisect terms` when BISECT_START does not exist (the current\n   implementation).\n\nI'm keeping option 2) for now, but if anyone think option 1) is better,\nit shouldn't be hard to change.\n\n-- \nMatthieu Moy\nhttp://www-verimag.imag.fr/~moy/\n"}]}