{"thread":{"id":"65634","subject":"[PATCH v4 0/3] Avoid hardcoded \"good\"/\"bad\" bisect terms","startedAt":"2026-05-14T09:22:16Z","lastAt":"2026-05-15T08:07:04Z","messageCount":6,"participants":["Jonas Rebmann","Junio C Hamano"],"isPatch":true,"patchVersion":4,"patchTotal":3},"messages":[{"id":"543289","messageId":"20260514-bisect-terms-v4-0-b3e3cf1b06ce@schlaraffenlan.de","threadId":"65634","inReplyTo":null,"subject":"[PATCH v4 0/3] Avoid hardcoded \"good\"/\"bad\" bisect terms","fromName":"Jonas Rebmann","fromEmail":"kernel@schlaraffenlan.de","sentAt":"2026-05-14T09:07:03Z","receivedAt":"2026-05-14T09:22:16Z","isPatch":true,"body":"While checking whether all output messages of git bisect were covered by\n[PATCH 1/3] bisect: use selected alternate terms in status output I\nfound hardcoded good/bad refs leading to incompatibility of git\nrev-parse --bisect with alternate bisect run terms. This is addressed by\n[PATCH 3/3] rev-parse: use selected alternate terms to look up refs\n\nSigned-off-by: Jonas Rebmann <kernel@schlaraffenlan.de>\n---\nChanges in v4:\n- Always print bisect terms in single quote (Thanks, Junio)\n- Split out quoting of bisect terms into separate commit\n- Link to v3: https://patch.msgid.link/20260417-bisect-terms-v3-0-d659fa547261@schlaraffenlan.de\n\nChanges in v3:\n- when referencing newly introduced terms, reference them in single\n  quotes (Thanks, Phillip)\n- Prefer test_grep over grep in updated Tests (Thanks, Phillip)\n- Improve commit messages (Thanks, Phillip)\n- Don't leak memory after read_bisect_terms() (Thanks, Phillip)\n- Don't leak memory after xstrfmt() (Thanks, Junio)\n- Add test case to patch 2/2\n- Link to v2: https://patch.msgid.link/20260323-bisect-terms-v2-0-8d6bdb2c9c7e@schlaraffenlan.de\n\nChanges in v2:\n- Improve commit message\n- Add tests\n- Include second patch for hardcoded good/bad in rev-parse\n- Link to v1: https://lore.kernel.org/r/20260320-bisect-terms-v1-1-c30c9540542a@schlaraffenlan.de\n\n---\nJonas Rebmann (3):\n      bisect: use selected alternate terms in status output\n      bisect: print bisect terms in single quotes\n      rev-parse: use selected alternate terms to look up refs\n\n bisect.c                    |  16 +++---\n builtin/bisect.c            |  31 ++++++-----\n builtin/rev-parse.c         |  15 +++++-\n t/t1500-rev-parse.sh        |  25 +++++++++\n t/t6030-bisect-porcelain.sh | 124 ++++++++++++++++++++++++--------------------\n 5 files changed, 131 insertions(+), 80 deletions(-)\n---\nbase-commit: 59ff4886a579f4bc91e976fe18590b9ae02c7a08\nchange-id: 20260320-bisect-terms-76036676769c\n\nBest regards,\n--  \nJonas Rebmann <kernel@schlaraffenlan.de>\n\n"},{"id":"543290","messageId":"20260514-bisect-terms-v4-1-b3e3cf1b06ce@schlaraffenlan.de","threadId":"65634","inReplyTo":"20260514-bisect-terms-v4-0-b3e3cf1b06ce@schlaraffenlan.de","subject":"[PATCH v4 1/3] bisect: use selected alternate terms in status output","fromName":"Jonas Rebmann","fromEmail":"kernel@schlaraffenlan.de","sentAt":"2026-05-14T09:07:04Z","receivedAt":"2026-05-14T09:26:25Z","isPatch":true,"body":"Alternate bisect terms are helpful when the terms \"good\" and \"bad\" are\nconfusing such as when bisecting for the resolution of an issue (the\nfirst good commit) rather than the introduction of a regression.\n\nThese terms must be used when marking a commit (e.g. `git bisect new`),\nthey will be used in reference names (e.g. refs/bisect/new) and they are\nused in parts of git's log output such as \"<sha> was both old and new\"\nin git bisect skip's output.\n\nHowever, hardcoded \"good\"/\"bad\" terms are still used in a few status\nmessages and can cause confusion about the status of the bisect such as:\n\n  $ git bisect old\n  [sha] is the first new commit\n\nor about the required action such as:\n\n  status: waiting for bad commit, 1 good commit known\n  $ git bisect bad\n  error: Invalid command: you're currently in a new/old bisect\n  fatal: unknown command: 'bad'\n\nThis commit updates all remaining output messages which use hardcoded\n\"good\" and \"bad\" terms to use the selected terms consistently across the\nbisect output and adds tests.\n\nSigned-off-by: Jonas Rebmann <kernel@schlaraffenlan.de>\n---\n builtin/bisect.c            | 23 +++++++++++++----------\n t/t6030-bisect-porcelain.sh | 16 ++++++++++++++--\n 2 files changed, 27 insertions(+), 12 deletions(-)\n\ndiff --git a/builtin/bisect.c b/builtin/bisect.c\nindex 4520e585d0..ee6a2c83b8 100644\n--- a/builtin/bisect.c\n+++ b/builtin/bisect.c\n@@ -465,13 +465,16 @@ static void bisect_print_status(const struct bisect_terms *terms)\n \t\treturn;\n \n \tif (!state.nr_good && !state.nr_bad)\n-\t\tbisect_log_printf(_(\"status: waiting for both good and bad commits\\n\"));\n+\t\tbisect_log_printf(_(\"status: waiting for both %s and %s commits\\n\"),\n+\t\t\t\t  terms->term_good, terms->term_bad);\n \telse if (state.nr_good)\n-\t\tbisect_log_printf(Q_(\"status: waiting for bad commit, %d good commit known\\n\",\n-\t\t\t\t     \"status: waiting for bad commit, %d good commits known\\n\",\n-\t\t\t\t     state.nr_good), state.nr_good);\n+\t\tbisect_log_printf(Q_(\"status: waiting for %s commit, %d %s commit known\\n\",\n+\t\t\t\t     \"status: waiting for %s commit, %d %s commits known\\n\",\n+\t\t\t\t     state.nr_good),\n+\t\t\t\t  terms->term_bad, state.nr_good, terms->term_good);\n \telse\n-\t\tbisect_log_printf(_(\"status: waiting for good commit(s), bad commit known\\n\"));\n+\t\tbisect_log_printf(_(\"status: waiting for %s commit(s), %s commit known\\n\"),\n+\t\t\t\t  terms->term_good, terms->term_bad);\n }\n \n static int bisect_next_check(const struct bisect_terms *terms,\n@@ -1262,14 +1265,14 @@ static int bisect_run(struct bisect_terms *terms, int argc, const char **argv)\n \t\t\tint rc = verify_good(terms, command.buf);\n \t\t\tis_first_run = 0;\n \t\t\tif (rc < 0 || 128 <= rc) {\n-\t\t\t\terror(_(\"unable to verify %s on good\"\n-\t\t\t\t\t\" revision\"), command.buf);\n+\t\t\t\terror(_(\"unable to verify %s on %s\"\n+\t\t\t\t\t\" revision\"), command.buf, terms->term_good);\n \t\t\t\tres = BISECT_FAILED;\n \t\t\t\tbreak;\n \t\t\t}\n \t\t\tif (rc == res) {\n-\t\t\t\terror(_(\"bogus exit code %d for good revision\"),\n-\t\t\t\t      rc);\n+\t\t\t\terror(_(\"bogus exit code %d for %s revision\"),\n+\t\t\t\t      rc, terms->term_good);\n \t\t\t\tres = BISECT_FAILED;\n \t\t\t\tbreak;\n \t\t\t}\n@@ -1314,7 +1317,7 @@ static int bisect_run(struct bisect_terms *terms, int argc, const char **argv)\n \t\t\tputs(_(\"bisect run success\"));\n \t\t\tres = BISECT_OK;\n \t\t} else if (res == BISECT_INTERNAL_SUCCESS_1ST_BAD_FOUND) {\n-\t\t\tputs(_(\"bisect found first bad commit\"));\n+\t\t\tprintf(_(\"bisect found first %s commit\\n\"), terms->term_bad);\n \t\t\tres = BISECT_OK;\n \t\t} else if (res) {\n \t\t\terror(_(\"bisect run failed: 'git bisect %s'\"\ndiff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh\nindex 1ba9ca219e..9d28d1eedb 100755\n--- a/t/t6030-bisect-porcelain.sh\n+++ b/t/t6030-bisect-porcelain.sh\n@@ -1077,8 +1077,10 @@ test_expect_success 'bisect terms shows good/bad after start' '\n \n test_expect_success 'bisect start with one term1 and term2' '\n \tgit bisect reset &&\n-\tgit bisect start --term-old term2 --term-new term1 &&\n-\tgit bisect term2 $HASH1 &&\n+\tgit bisect start --term-old term2 --term-new term1 >bisect_result &&\n+\tgrep \"status: waiting for both term2 and term1 commits\" bisect_result &&\n+\tgit bisect term2 $HASH1 >bisect_result &&\n+\tgrep \"status: waiting for term1 commit, 1 term2 commit known\" bisect_result &&\n \tgit bisect term1 $HASH4 &&\n \tgit bisect term1 &&\n \tgit bisect term1 >bisect_result &&\n@@ -1103,6 +1105,16 @@ test_expect_success 'bisect replay with term1 and term2' '\n \tgit bisect reset\n '\n \n+test_expect_success 'bisect run term1 term2' '\n+\tgit bisect reset &&\n+\tgit bisect start --term-new term1 --term-old term2 $HASH4 $HASH1 &&\n+\tgit bisect term1 &&\n+\tgit bisect run false >bisect_result &&\n+\tgrep \"bisect found first term1 commit\" bisect_result &&\n+\tgit bisect log >log_to_replay.txt &&\n+\tgit bisect reset\n+'\n+\n test_expect_success 'bisect start term1 term2' '\n \tgit bisect reset &&\n \tgit bisect start --term-new term1 --term-old term2 $HASH4 $HASH1 &&\n\n-- \n2.54.0\n\n"},{"id":"543291","messageId":"20260514-bisect-terms-v4-2-b3e3cf1b06ce@schlaraffenlan.de","threadId":"65634","inReplyTo":"20260514-bisect-terms-v4-0-b3e3cf1b06ce@schlaraffenlan.de","subject":"[PATCH v4 2/3] bisect: print bisect terms in single quotes","fromName":"Jonas Rebmann","fromEmail":"kernel@schlaraffenlan.de","sentAt":"2026-05-14T09:07:05Z","receivedAt":"2026-05-14T09:46:28Z","isPatch":true,"body":"As bisect terms can be arbitrarily chosen, they have been quoted in some\nstatus messages, and in even more by translators.\n\nTo make the role of bisect terms more clear, including in translations,\nand for consistency, 'enquote' all occurrences of bisect terms in status\nmessages.\n\nSigned-off-by: Jonas Rebmann <kernel@schlaraffenlan.de>\n---\n bisect.c                    |  16 +++----\n builtin/bisect.c            |  24 +++++-----\n t/t6030-bisect-porcelain.sh | 114 ++++++++++++++++++++++----------------------\n 3 files changed, 77 insertions(+), 77 deletions(-)\n\ndiff --git a/bisect.c b/bisect.c\nindex ef17a442e5..905a9afb05 100644\n--- a/bisect.c\n+++ b/bisect.c\n@@ -711,7 +711,7 @@ static enum bisect_error error_if_skipped_commits(struct commit_list *tried,\n \t\treturn BISECT_OK;\n \n \tprintf(\"There are only 'skip'ped commits left to test.\\n\"\n-\t       \"The first %s commit could be any of:\\n\", term_bad);\n+\t       \"The first '%s' commit could be any of:\\n\", term_bad);\n \n \tfor ( ; tried; tried = tried->next)\n \t\tprintf(\"%s\\n\", oid_to_hex(&tried->item->object.oid));\n@@ -810,7 +810,7 @@ static enum bisect_error 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\tfprintf(stderr, _(\"The merge base %s is %s.\\n\"\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, term_bad, term_good, bad_hex, good_hex);\n@@ -820,9 +820,9 @@ static enum bisect_error handle_bad_merge_base(void)\n \t\treturn BISECT_MERGE_BASE_CHECK;\n \t}\n \n-\tfprintf(stderr, _(\"Some %s revs are not ancestors of the %s rev.\\n\"\n+\tfprintf(stderr, _(\"Some '%s' revs are not ancestors of the '%s' rev.\\n\"\n \t\t\"git bisect cannot work properly in this case.\\n\"\n-\t\t\"Maybe you mistook %s and %s revs?\\n\"),\n+\t\t\"Maybe you mistook '%s' and '%s' revs?\\n\"),\n \t\tterm_good, term_bad, term_good, term_bad);\n \treturn BISECT_FAILED;\n }\n@@ -835,7 +835,7 @@ static void handle_skipped_merge_base(const struct object_id *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 %s 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, term_bad, mb_hex, bad_hex);\n@@ -928,7 +928,7 @@ static enum bisect_error check_good_are_ancestors_of_bad(struct repository *r,\n \tstruct commit **rev;\n \n \tif (!current_bad_oid)\n-\t\treturn error(_(\"a %s revision is needed\"), term_bad);\n+\t\treturn error(_(\"a '%s' revision is needed\"), term_bad);\n \n \tfilename = repo_git_path(the_repository, \"BISECT_ANCESTORS_OK\");\n \n@@ -1090,7 +1090,7 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix)\n \t\tres = error_if_skipped_commits(tried, NULL);\n \t\tif (res < 0)\n \t\t\tgoto cleanup;\n-\t\tprintf(_(\"%s was both %s and %s\\n\"),\n+\t\tprintf(_(\"%s was both '%s' and '%s'\\n\"),\n \t\t       oid_to_hex(current_bad_oid),\n \t\t       term_good,\n \t\t       term_bad);\n@@ -1113,7 +1113,7 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix)\n \t\tres = error_if_skipped_commits(tried, current_bad_oid);\n \t\tif (res)\n \t\t\tgoto cleanup;\n-\t\tprintf(\"%s is the first %s commit\\n\", oid_to_hex(bisect_rev),\n+\t\tprintf(\"%s is the first '%s' commit\\n\", oid_to_hex(bisect_rev),\n \t\t\tterm_bad);\n \n \t\tshow_commit(revs.commits->item);\ndiff --git a/builtin/bisect.c b/builtin/bisect.c\nindex ee6a2c83b8..606698b21e 100644\n--- a/builtin/bisect.c\n+++ b/builtin/bisect.c\n@@ -465,15 +465,15 @@ static void bisect_print_status(const struct bisect_terms *terms)\n \t\treturn;\n \n \tif (!state.nr_good && !state.nr_bad)\n-\t\tbisect_log_printf(_(\"status: waiting for both %s and %s commits\\n\"),\n+\t\tbisect_log_printf(_(\"status: waiting for both '%s' and '%s' commits\\n\"),\n \t\t\t\t  terms->term_good, terms->term_bad);\n \telse if (state.nr_good)\n-\t\tbisect_log_printf(Q_(\"status: waiting for %s commit, %d %s commit known\\n\",\n-\t\t\t\t     \"status: waiting for %s commit, %d %s commits known\\n\",\n+\t\tbisect_log_printf(Q_(\"status: waiting for '%s' commit, %d '%s' commit known\\n\",\n+\t\t\t\t     \"status: waiting for '%s' commit, %d '%s' commits known\\n\",\n \t\t\t\t     state.nr_good),\n \t\t\t\t  terms->term_bad, state.nr_good, terms->term_good);\n \telse\n-\t\tbisect_log_printf(_(\"status: waiting for %s commit(s), %s commit known\\n\"),\n+\t\tbisect_log_printf(_(\"status: waiting for '%s' commit(s), '%s' commit known\\n\"),\n \t\t\t\t  terms->term_good, terms->term_bad);\n }\n \n@@ -516,8 +516,8 @@ static int bisect_terms(struct bisect_terms *terms, const char *option)\n \t\treturn error(_(\"no terms defined\"));\n \n \tif (!option) {\n-\t\tprintf(_(\"Your current terms are %s for the old state\\n\"\n-\t\t\t \"and %s for the new state.\\n\"),\n+\t\tprintf(_(\"Your current terms are '%s' for the old state\\n\"\n+\t\t\t \"and '%s' for the new state.\\n\"),\n \t\t       terms->term_good, terms->term_bad);\n \t\treturn 0;\n \t}\n@@ -635,7 +635,7 @@ static int bisect_skipped_commits(struct bisect_terms *terms)\n \t\tstrbuf_reset(&commit_name);\n \t\trepo_format_commit_message(the_repository, commit, \"%s\",\n \t\t\t\t\t   &commit_name, &pp);\n-\t\tfprintf(fp, \"# possible first %s commit: [%s] %s\\n\",\n+\t\tfprintf(fp, \"# possible first '%s' commit: [%s] %s\\n\",\n \t\t\tterms->term_bad, oid_to_hex(&commit->object.oid),\n \t\t\tcommit_name.buf);\n \t}\n@@ -666,7 +666,7 @@ static int bisect_successful(struct bisect_terms *terms)\n \trepo_format_commit_message(the_repository, commit, \"%s\", &commit_name,\n \t\t\t\t   &pp);\n \n-\tres = append_to_file(git_path_bisect_log(), \"# first %s commit: [%s] %s\\n\",\n+\tres = append_to_file(git_path_bisect_log(), \"# first '%s' commit: [%s] %s\\n\",\n \t\t\t    terms->term_bad, oid_to_hex(&commit->object.oid),\n \t\t\t    commit_name.buf);\n \n@@ -1265,13 +1265,13 @@ static int bisect_run(struct bisect_terms *terms, int argc, const char **argv)\n \t\t\tint rc = verify_good(terms, command.buf);\n \t\t\tis_first_run = 0;\n \t\t\tif (rc < 0 || 128 <= rc) {\n-\t\t\t\terror(_(\"unable to verify %s on %s\"\n-\t\t\t\t\t\" revision\"), command.buf, terms->term_good);\n+\t\t\t\terror(_(\"unable to verify %s on '%s' revision\"),\n+\t\t\t\t      command.buf, terms->term_good);\n \t\t\t\tres = BISECT_FAILED;\n \t\t\t\tbreak;\n \t\t\t}\n \t\t\tif (rc == res) {\n-\t\t\t\terror(_(\"bogus exit code %d for %s revision\"),\n+\t\t\t\terror(_(\"bogus exit code %d for '%s' revision\"),\n \t\t\t\t      rc, terms->term_good);\n \t\t\t\tres = BISECT_FAILED;\n \t\t\t\tbreak;\n@@ -1317,7 +1317,7 @@ static int bisect_run(struct bisect_terms *terms, int argc, const char **argv)\n \t\t\tputs(_(\"bisect run success\"));\n \t\t\tres = BISECT_OK;\n \t\t} else if (res == BISECT_INTERNAL_SUCCESS_1ST_BAD_FOUND) {\n-\t\t\tprintf(_(\"bisect found first %s commit\\n\"), terms->term_bad);\n+\t\t\tprintf(_(\"bisect found first '%s' commit\\n\"), terms->term_bad);\n \t\t\tres = BISECT_OK;\n \t\t} else if (res) {\n \t\t\terror(_(\"bisect run failed: 'git bisect %s'\"\ndiff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh\nindex 9d28d1eedb..081116220a 100755\n--- a/t/t6030-bisect-porcelain.sh\n+++ b/t/t6030-bisect-porcelain.sh\n@@ -258,7 +258,7 @@ test_expect_success 'bisect skip: successful result' '\n \tgit bisect start $HASH4 $HASH1 &&\n \tgit bisect skip &&\n \tgit bisect bad > my_bisect_log.txt &&\n-\tgrep \"$HASH2 is the first bad commit\" my_bisect_log.txt\n+\tgrep \"$HASH2 is the first '\\''bad'\\'' commit\" my_bisect_log.txt\n '\n \n # $HASH1 is good, $HASH4 is bad, we skip $HASH3 and $HASH2\n@@ -269,7 +269,7 @@ test_expect_success 'bisect skip: cannot tell between 3 commits' '\n \tgit bisect start $HASH4 $HASH1 &&\n \tgit bisect skip &&\n \ttest_expect_code 2 git bisect skip >my_bisect_log.txt &&\n-\tgrep \"first bad commit could be any of\" my_bisect_log.txt &&\n+\tgrep \"first '\\''bad'\\'' commit could be any of\" my_bisect_log.txt &&\n \t! grep $HASH1 my_bisect_log.txt &&\n \tgrep $HASH2 my_bisect_log.txt &&\n \tgrep $HASH3 my_bisect_log.txt &&\n@@ -285,7 +285,7 @@ test_expect_success 'bisect skip: cannot tell between 2 commits' '\n \tgit bisect start $HASH4 $HASH1 &&\n \tgit bisect skip &&\n \ttest_expect_code 2 git bisect good >my_bisect_log.txt &&\n-\tgrep \"first bad commit could be any of\" my_bisect_log.txt &&\n+\tgrep \"first '\\''bad'\\'' commit could be any of\" my_bisect_log.txt &&\n \t! grep $HASH1 my_bisect_log.txt &&\n \t! grep $HASH2 my_bisect_log.txt &&\n \tgrep $HASH3 my_bisect_log.txt &&\n@@ -304,7 +304,7 @@ test_expect_success 'bisect skip: with commit both bad and skipped' '\n \tgit bisect good $HASH1 &&\n \tgit bisect skip &&\n \ttest_expect_code 2 git bisect good >my_bisect_log.txt &&\n-\tgrep \"first bad commit could be any of\" my_bisect_log.txt &&\n+\tgrep \"first '\\''bad'\\'' commit could be any of\" my_bisect_log.txt &&\n \t! grep $HASH1 my_bisect_log.txt &&\n \t! grep $HASH2 my_bisect_log.txt &&\n \tgrep $HASH3 my_bisect_log.txt &&\n@@ -348,8 +348,8 @@ test_expect_success 'git bisect run: args, stdout and stderr with no arguments'\n \ttest_bisect_run_args <<-'EOF_ARGS' 6<<-EOF_OUT 7<<-'EOF_ERR'\n \tEOF_ARGS\n \trunning './run.sh'\n-\t$HASH4 is the first bad commit\n-\tbisect found first bad commit\n+\t$HASH4 is the first 'bad' commit\n+\tbisect found first 'bad' commit\n \tEOF_OUT\n \tEOF_ERR\n \"\n@@ -359,8 +359,8 @@ test_expect_success 'git bisect run: args, stdout and stderr: \"--\" argument' \"\n \t<-->\n \tEOF_ARGS\n \trunning './run.sh' '--'\n-\t$HASH4 is the first bad commit\n-\tbisect found first bad commit\n+\t$HASH4 is the first 'bad' commit\n+\tbisect found first 'bad' commit\n \tEOF_OUT\n \tEOF_ERR\n \"\n@@ -373,8 +373,8 @@ test_expect_success 'git bisect run: args, stdout and stderr: \"--log foo --no-lo\n \t<bar>\n \tEOF_ARGS\n \trunning './run.sh' '--log' 'foo' '--no-log' 'bar'\n-\t$HASH4 is the first bad commit\n-\tbisect found first bad commit\n+\t$HASH4 is the first 'bad' commit\n+\tbisect found first 'bad' commit\n \tEOF_OUT\n \tEOF_ERR\n \"\n@@ -384,8 +384,8 @@ test_expect_success 'git bisect run: args, stdout and stderr: \"--bisect-start\" a\n \t<--bisect-start>\n \tEOF_ARGS\n \trunning './run.sh' '--bisect-start'\n-\t$HASH4 is the first bad commit\n-\tbisect found first bad commit\n+\t$HASH4 is the first 'bad' commit\n+\tbisect found first 'bad' commit\n \tEOF_OUT\n \tEOF_ERR\n \"\n@@ -418,7 +418,7 @@ test_expect_success 'git bisect run: unable to verify on good' \"\n \tfi\n \tEOF\n \tcat <<-'EOF' >expect &&\n-\tunable to verify './fail.sh' on good revision\n+\tunable to verify './fail.sh' on 'good' revision\n \tEOF\n \ttest_when_finished 'git bisect reset' &&\n \tgit bisect start &&\n@@ -439,7 +439,7 @@ test_expect_success '\"git bisect run\" simple case' '\n \tgit bisect good $HASH1 &&\n \tgit bisect bad $HASH4 &&\n \tgit bisect run ./test_script.sh >my_bisect_log.txt &&\n-\tgrep \"$HASH3 is the first bad commit\" my_bisect_log.txt &&\n+\tgrep \"$HASH3 is the first '\\''bad'\\'' commit\" my_bisect_log.txt &&\n \tgit bisect reset\n '\n \n@@ -461,7 +461,7 @@ test_expect_success '\"git bisect run\" with more complex \"git bisect start\"' '\n \tEOF\n \tgit bisect start $HASH4 $HASH1 &&\n \tgit bisect run ./test_script.sh >my_bisect_log.txt &&\n-\tgrep \"$HASH4 is the first bad commit\" my_bisect_log.txt &&\n+\tgrep \"$HASH4 is the first '\\''bad'\\'' commit\" my_bisect_log.txt &&\n \tgit bisect reset\n '\n \n@@ -474,7 +474,7 @@ test_expect_success 'bisect run accepts exit code 126 as bad' '\n \tgit bisect good $HASH1 &&\n \tgit bisect bad $HASH4 &&\n \tgit bisect run ./test_script.sh >my_bisect_log.txt &&\n-\tgrep \"$HASH3 is the first bad commit\" my_bisect_log.txt\n+\tgrep \"$HASH3 is the first '\\''bad'\\'' commit\" my_bisect_log.txt\n '\n \n test_expect_success POSIXPERM 'bisect run fails with non-executable test script' '\n@@ -485,7 +485,7 @@ test_expect_success POSIXPERM 'bisect run fails with non-executable test script'\n \tgit bisect good $HASH1 &&\n \tgit bisect bad $HASH4 &&\n \ttest_must_fail git bisect run ./not-executable.sh >my_bisect_log.txt &&\n-\t! grep \"is the first bad commit\" my_bisect_log.txt\n+\t! grep \"is the first '\\''bad'\\'' commit\" my_bisect_log.txt\n '\n \n test_expect_success 'bisect run accepts exit code 127 as bad' '\n@@ -497,7 +497,7 @@ test_expect_success 'bisect run accepts exit code 127 as bad' '\n \tgit bisect good $HASH1 &&\n \tgit bisect bad $HASH4 &&\n \tgit bisect run ./test_script.sh >my_bisect_log.txt &&\n-\tgrep \"$HASH3 is the first bad commit\" my_bisect_log.txt\n+\tgrep \"$HASH3 is the first '\\''bad'\\'' commit\" my_bisect_log.txt\n '\n \n test_expect_success 'bisect run fails with missing test script' '\n@@ -507,7 +507,7 @@ test_expect_success 'bisect run fails with missing test script' '\n \tgit bisect good $HASH1 &&\n \tgit bisect bad $HASH4 &&\n \ttest_must_fail git bisect run ./does-not-exist.sh >my_bisect_log.txt &&\n-\t! grep \"is the first bad commit\" my_bisect_log.txt\n+\t! grep \"is the first '\\''bad'\\'' commit\" my_bisect_log.txt\n '\n \n # $HASH1 is good, $HASH5 is bad, we skip $HASH3\n@@ -520,14 +520,14 @@ test_expect_success 'bisect skip: add line and then a new test' '\n \tgit bisect start $HASH5 $HASH1 &&\n \tgit bisect skip &&\n \tgit bisect good > my_bisect_log.txt &&\n-\tgrep \"$HASH5 is the first bad commit\" my_bisect_log.txt &&\n+\tgrep \"$HASH5 is the first '\\''bad'\\'' commit\" my_bisect_log.txt &&\n \tgit bisect log > log_to_replay.txt &&\n \tgit bisect reset\n '\n \n test_expect_success 'bisect skip and bisect replay' '\n \tgit bisect replay log_to_replay.txt > my_bisect_log.txt &&\n-\tgrep \"$HASH5 is the first bad commit\" my_bisect_log.txt &&\n+\tgrep \"$HASH5 is the first '\\''bad'\\'' commit\" my_bisect_log.txt &&\n \tgit bisect reset\n '\n \n@@ -541,7 +541,7 @@ test_expect_success 'bisect run & skip: cannot tell between 2' '\n \tEOF\n \tgit bisect start $HASH6 $HASH1 &&\n \ttest_expect_code 2 git bisect run ./test_script.sh >my_bisect_log.txt &&\n-\tgrep \"first bad commit could be any of\" my_bisect_log.txt &&\n+\tgrep \"first '\\''bad'\\'' commit could be any of\" my_bisect_log.txt &&\n \t! grep $HASH3 my_bisect_log.txt &&\n \t! grep $HASH6 my_bisect_log.txt &&\n \tgrep $HASH4 my_bisect_log.txt &&\n@@ -560,7 +560,7 @@ test_expect_success 'bisect run & skip: find first bad' '\n \tEOF\n \tgit bisect start $HASH7 $HASH1 &&\n \tgit bisect run ./test_script.sh >my_bisect_log.txt &&\n-\tgrep \"$HASH6 is the first bad commit\" my_bisect_log.txt\n+\tgrep \"$HASH6 is the first '\\''bad'\\'' commit\" my_bisect_log.txt\n '\n \n test_expect_success 'bisect skip only one range' '\n@@ -569,7 +569,7 @@ test_expect_success 'bisect skip only one range' '\n \tgit bisect skip $HASH1..$HASH5 &&\n \ttest \"$HASH6\" = \"$(git rev-parse --verify HEAD)\" &&\n \ttest_must_fail git bisect bad > my_bisect_log.txt &&\n-\tgrep \"first bad commit could be any of\" my_bisect_log.txt\n+\tgrep \"first '\\''bad'\\'' commit could be any of\" my_bisect_log.txt\n '\n \n test_expect_success 'bisect skip many ranges' '\n@@ -578,7 +578,7 @@ test_expect_success 'bisect skip many ranges' '\n \tgit bisect skip $HASH2 $HASH2.. ..$HASH5 &&\n \ttest \"$HASH6\" = \"$(git rev-parse --verify HEAD)\" &&\n \ttest_must_fail git bisect bad > my_bisect_log.txt &&\n-\tgrep \"first bad commit could be any of\" my_bisect_log.txt\n+\tgrep \"first '\\''bad'\\'' commit could be any of\" my_bisect_log.txt\n '\n \n test_expect_success 'bisect starting with a detached HEAD' '\n@@ -594,7 +594,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-\ttest_grep \"mistook good and bad\" rev_list_error &&\n+\ttest_grep \"mistook '\\''good'\\'' and '\\''bad'\\''\" rev_list_error &&\n \tgit bisect reset\n '\n \n@@ -610,7 +610,7 @@ test_expect_success 'bisect does not create a \"bisect\" branch' '\n \trev_hash6=$(git rev-parse --verify HEAD) &&\n \ttest \"$rev_hash6\" = \"$HASH6\" &&\n \tgit bisect good > my_bisect_log.txt &&\n-\tgrep \"$HASH7 is the first bad commit\" my_bisect_log.txt &&\n+\tgrep \"$HASH7 is the first '\\''bad'\\'' commit\" my_bisect_log.txt &&\n \tgit bisect reset &&\n \trev_hash6=$(git rev-parse --verify bisect) &&\n \ttest \"$rev_hash6\" = \"$HASH6\" &&\n@@ -703,7 +703,7 @@ test_expect_success '\"git bisect run --first-parent\" simple case' '\n \tgit bisect good $HASH4 &&\n \tgit bisect bad $B_HASH &&\n \tgit bisect run ./test_script.sh >my_bisect_log.txt &&\n-\tgrep \"$B_HASH is the first bad commit\" my_bisect_log.txt &&\n+\tgrep \"$B_HASH is the first '\\''bad'\\'' commit\" my_bisect_log.txt &&\n \tgit bisect reset &&\n \ttest_path_is_missing .git/BISECT_FIRST_PARENT\n '\n@@ -777,7 +777,7 @@ test_expect_success 'restricting bisection on one dir' '\n \tpara1=$(git rev-parse --verify HEAD) &&\n \ttest \"$para1\" = \"$PARA_HASH1\" &&\n \tgit bisect bad > my_bisect_log.txt &&\n-\tgrep \"$PARA_HASH1 is the first bad commit\" my_bisect_log.txt\n+\tgrep \"$PARA_HASH1 is the first '\\''bad'\\'' commit\" my_bisect_log.txt\n '\n \n test_expect_success 'restricting bisection on one dir and a file' '\n@@ -795,7 +795,7 @@ test_expect_success 'restricting bisection on one dir and a file' '\n \tpara1=$(git rev-parse --verify HEAD) &&\n \ttest \"$para1\" = \"$PARA_HASH1\" &&\n \tgit bisect good > my_bisect_log.txt &&\n-\tgrep \"$PARA_HASH4 is the first bad commit\" my_bisect_log.txt\n+\tgrep \"$PARA_HASH4 is the first '\\''bad'\\'' commit\" my_bisect_log.txt\n '\n \n test_expect_success 'skipping away from skipped commit' '\n@@ -826,7 +826,7 @@ test_expect_success 'test bisection on bare repo - --no-checkout specified' '\n \t\t\t\"test \\$(git rev-list BISECT_HEAD ^$HASH2 --max-count=1 | wc -l) = 0\" \\\n \t\t\t>../nocheckout.log\n \t) &&\n-\tgrep \"$HASH3 is the first bad commit\" nocheckout.log\n+\tgrep \"$HASH3 is the first '\\''bad'\\'' commit\" nocheckout.log\n '\n \n \n@@ -841,7 +841,7 @@ test_expect_success 'test bisection on bare repo - --no-checkout defaulted' '\n \t\t\t\"test \\$(git rev-list BISECT_HEAD ^$HASH2 --max-count=1 | wc -l) = 0\" \\\n \t\t\t>../defaulted.log\n \t) &&\n-\tgrep \"$HASH3 is the first bad commit\" defaulted.log\n+\tgrep \"$HASH3 is the first '\\''bad'\\'' commit\" defaulted.log\n '\n \n #\n@@ -969,7 +969,7 @@ cat > expected.bisect-log <<EOF\n git bisect start '$HASH4' '$HASH2'\n # good: [$HASH3] Add <3: Another new day for git> into <hello>.\n git bisect good $HASH3\n-# first bad commit: [$HASH4] Add <4: Ciao for now> into <hello>.\n+# first 'bad' commit: [$HASH4] Add <4: Ciao for now> into <hello>.\n EOF\n \n test_expect_success 'bisect log: successful result' '\n@@ -988,8 +988,8 @@ git bisect start '$HASH4' '$HASH2'\n # skip: [$HASH3] Add <3: Another new day for git> into <hello>.\n git bisect skip $HASH3\n # only skipped commits left to test\n-# possible first bad commit: [$HASH4] Add <4: Ciao for now> into <hello>.\n-# possible first bad commit: [$HASH3] Add <3: Another new day for git> into <hello>.\n+# possible first 'bad' commit: [$HASH4] Add <4: Ciao for now> into <hello>.\n+# possible first 'bad' commit: [$HASH3] Add <3: Another new day for git> into <hello>.\n EOF\n \n test_expect_success 'bisect log: only skip commits left' '\n@@ -1031,21 +1031,21 @@ test_expect_success 'bisect start with one new and old' '\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+\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+\tgrep \"$HASH2 is the first '\\''new'\\'' commit\" bisect_result &&\n \tgit bisect reset\n '\n \n test_expect_success 'bisect replay with CRLF log' '\n \tappend_cr <log_to_replay.txt >log_to_replay_crlf.txt &&\n \tgit bisect replay log_to_replay_crlf.txt >bisect_result_crlf &&\n-\tgrep \"$HASH2 is the first new commit\" bisect_result_crlf &&\n+\tgrep \"$HASH2 is the first '\\''new'\\'' commit\" bisect_result_crlf &&\n \tgit bisect reset\n '\n \n@@ -1078,13 +1078,13 @@ test_expect_success 'bisect terms shows good/bad after start' '\n test_expect_success 'bisect start with one term1 and term2' '\n \tgit bisect reset &&\n \tgit bisect start --term-old term2 --term-new term1 >bisect_result &&\n-\tgrep \"status: waiting for both term2 and term1 commits\" bisect_result &&\n+\ttest_grep \"status: waiting for both '\\''term2'\\'' and '\\''term1'\\'' commits\" bisect_result &&\n \tgit bisect term2 $HASH1 >bisect_result &&\n-\tgrep \"status: waiting for term1 commit, 1 term2 commit known\" bisect_result &&\n+\ttest_grep \"status: waiting for '\\''term1'\\'' commit, 1 '\\''term2'\\'' commit known\" bisect_result &&\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+\ttest_grep \"$HASH2 is the first '\\''term1'\\'' commit\" bisect_result &&\n \tgit bisect log >log_to_replay.txt &&\n \tgit bisect reset\n '\n@@ -1101,7 +1101,7 @@ test_expect_success 'bogus command does not start bisect' '\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+\tgrep \"$HASH2 is the first '\\''term1'\\'' commit\" bisect_result &&\n \tgit bisect reset\n '\n \n@@ -1110,7 +1110,7 @@ test_expect_success 'bisect run term1 term2' '\n \tgit bisect start --term-new term1 --term-old term2 $HASH4 $HASH1 &&\n \tgit bisect term1 &&\n \tgit bisect run false >bisect_result &&\n-\tgrep \"bisect found first term1 commit\" bisect_result &&\n+\ttest_grep \"bisect found first '\\''term1'\\'' commit\" bisect_result &&\n \tgit bisect log >log_to_replay.txt &&\n \tgit bisect reset\n '\n@@ -1120,7 +1120,7 @@ test_expect_success 'bisect start term1 term2' '\n \tgit bisect start --term-new term1 --term-old term2 $HASH4 $HASH1 &&\n \tgit bisect term1 &&\n \tgit bisect term1 >bisect_result &&\n-\tgrep \"$HASH2 is the first term1 commit\" 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@@ -1154,8 +1154,8 @@ test_expect_success 'bisect start --term-* does store terms' '\n \tgit bisect start --term-bad=one --term-good=two &&\n \tgit bisect terms >actual &&\n \tcat <<-EOF >expected &&\n-\tYour current terms are two for the old state\n-\tand one for the new state.\n+\tYour current terms are '\\''two'\\'' for the old state\n+\tand '\\''one'\\'' for the new state.\n \tEOF\n \ttest_cmp expected actual &&\n \tgit bisect terms --term-bad >actual &&\n@@ -1212,7 +1212,7 @@ test_expect_success 'bisect handles annotated tags' '\n \tgit bisect good tag-one &&\n \tgit bisect bad tag-two >output &&\n \tbad=$(git rev-parse --verify tag-two^{commit}) &&\n-\tgrep \"$bad is the first bad commit\" output\n+\tgrep \"$bad is the first '\\''bad'\\'' commit\" output\n '\n \n test_expect_success 'bisect run fails with exit code equals or greater than 128' '\n@@ -1236,29 +1236,29 @@ test_expect_success 'bisect visualize with a filename with dash and space' '\n test_expect_success 'bisect state output with multiple good commits' '\n \tgit bisect reset &&\n \tgit bisect start >output &&\n-\tgrep \"waiting for both good and bad commits\" output &&\n+\tgrep \"waiting for both '\\''good'\\'' and '\\''bad'\\'' commits\" output &&\n \tgit bisect log >output &&\n-\tgrep \"waiting for both good and bad commits\" output &&\n+\tgrep \"waiting for both '\\''good'\\'' and '\\''bad'\\'' commits\" output &&\n \tgit bisect good \"$HASH1\" >output &&\n-\tgrep \"waiting for bad commit, 1 good commit known\" output &&\n+\tgrep \"waiting for '\\''bad'\\'' commit, 1 '\\''good'\\'' commit known\" output &&\n \tgit bisect log >output &&\n-\tgrep \"waiting for bad commit, 1 good commit known\" output &&\n+\tgrep \"waiting for '\\''bad'\\'' commit, 1 '\\''good'\\'' commit known\" output &&\n \tgit bisect good \"$HASH2\" >output &&\n-\tgrep \"waiting for bad commit, 2 good commits known\" output &&\n+\tgrep \"waiting for '\\''bad'\\'' commit, 2 '\\''good'\\'' commits known\" output &&\n \tgit bisect log >output &&\n-\tgrep \"waiting for bad commit, 2 good commits known\" output\n+\tgrep \"waiting for '\\''bad'\\'' commit, 2 '\\''good'\\'' commits known\" output\n '\n \n test_expect_success 'bisect state output with bad commit' '\n \tgit bisect reset &&\n \tgit bisect start >output &&\n-\tgrep \"waiting for both good and bad commits\" output &&\n+\tgrep \"waiting for both '\\''good'\\'' and '\\''bad'\\'' commits\" output &&\n \tgit bisect log >output &&\n-\tgrep \"waiting for both good and bad commits\" output &&\n+\tgrep \"waiting for both '\\''good'\\'' and '\\''bad'\\'' commits\" output &&\n \tgit bisect bad \"$HASH4\" >output &&\n-\tgrep -F \"waiting for good commit(s), bad commit known\" output &&\n+\tgrep -F \"waiting for '\\''good'\\'' commit(s), '\\''bad'\\'' commit known\" output &&\n \tgit bisect log >output &&\n-\tgrep -F \"waiting for good commit(s), bad commit known\" output\n+\tgrep -F \"waiting for '\\''good'\\'' commit(s), '\\''bad'\\'' commit known\" output\n '\n \n test_expect_success 'verify correct error message' '\n\n-- \n2.54.0\n\n"},{"id":"543294","messageId":"20260514-bisect-terms-v4-3-b3e3cf1b06ce@schlaraffenlan.de","threadId":"65634","inReplyTo":"20260514-bisect-terms-v4-0-b3e3cf1b06ce@schlaraffenlan.de","subject":"[PATCH v4 3/3] rev-parse: use selected alternate terms to look up refs","fromName":"Jonas Rebmann","fromEmail":"kernel@schlaraffenlan.de","sentAt":"2026-05-14T09:07:06Z","receivedAt":"2026-05-14T10:22:48Z","isPatch":true,"body":"git rev-parse --bisect does not work when alternate bisect terms are\nused, simply listing no revisions at all.\n\nThis is because a such bisect using e.g. \"old\" and \"new\" in place of\n\"good\" and \"bad\" will name refs \"refs/bisect/old\" (or new) accordingly\nso the hardcoded \"refs/bisect/bad\" (and good) yields no results in a\nbisect using alternate terms.\n\nUse the current bisect_terms to make rev-parse --bisect work in an\nalternate term bisect.\n\nSigned-off-by: Jonas Rebmann <kernel@schlaraffenlan.de>\n---\n builtin/rev-parse.c  | 15 +++++++++++++--\n t/t1500-rev-parse.sh | 25 +++++++++++++++++++++++++\n 2 files changed, 38 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/rev-parse.c b/builtin/rev-parse.c\nindex 218b5f34d6..7531edae9e 100644\n--- a/builtin/rev-parse.c\n+++ b/builtin/rev-parse.c\n@@ -10,6 +10,7 @@\n #include \"builtin.h\"\n \n #include \"abspath.h\"\n+#include \"bisect.h\"\n #include \"config.h\"\n #include \"commit.h\"\n #include \"environment.h\"\n@@ -940,13 +941,23 @@ int cmd_rev_parse(int argc,\n \t\t\t\tcontinue;\n \t\t\t}\n \t\t\tif (!strcmp(arg, \"--bisect\")) {\n+\t\t\t\tchar *prefix;\n+\t\t\t\tchar *term_bad = NULL;\n+\t\t\t\tchar *term_good = NULL;\n \t\t\t\tstruct refs_for_each_ref_options opts = { 0 };\n-\t\t\t\topts.prefix = \"refs/bisect/bad\";\n+\t\t\t\tread_bisect_terms(&term_bad, &term_good);\n+\t\t\t\tprefix = xstrfmt(\"refs/bisect/%s\", term_bad);\n+\t\t\t\topts.prefix = prefix;\n \t\t\t\trefs_for_each_ref_ext(get_main_ref_store(the_repository),\n \t\t\t\t\t\t      show_reference, NULL, &opts);\n-\t\t\t\topts.prefix = \"refs/bisect/good\";\n+\t\t\t\tfree(prefix);\n+\t\t\t\tprefix = xstrfmt(\"refs/bisect/%s\", term_good);\n+\t\t\t\topts.prefix = prefix;\n \t\t\t\trefs_for_each_ref_ext(get_main_ref_store(the_repository),\n \t\t\t\t\t\t      anti_reference, NULL, &opts);\n+\t\t\t\tfree(prefix);\n+\t\t\t\tfree(term_good);\n+\t\t\t\tfree(term_bad);\n \t\t\t\tcontinue;\n \t\t\t}\n \t\t\tif (opt_with_value(arg, \"--branches\", &arg)) {\ndiff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh\nindex 98c5a772bd..38067d95f7 100755\n--- a/t/t1500-rev-parse.sh\n+++ b/t/t1500-rev-parse.sh\n@@ -337,6 +337,31 @@ test_expect_success 'rev-parse --bisect includes bad, excludes good' '\n \ttest_cmp expect actual\n '\n \n+test_expect_success 'rev-parse --bisect works with alternate terms' '\n+\ttest_commit_bulk 6 &&\n+\n+\tgit bisect start --term-old=known --term-new=curious &&\n+\n+\tgit update-ref refs/bisect/curious-1 HEAD~1 &&\n+\tgit update-ref refs/bisect/bad HEAD~2 &&\n+\tgit update-ref refs/bisect/curious-3 HEAD~3 &&\n+\tgit update-ref refs/bisect/known-3 HEAD~3 &&\n+\tgit update-ref refs/bisect/curious-4 HEAD~4 &&\n+\tgit update-ref refs/bisect/good HEAD~4 &&\n+\n+\t# Note: refs/bisect/bad and refs/bisect/goood should be ignored because this\n+\t# is a bisect with custom terms (known/curious)\n+\tcat >expect <<-EOF &&\n+\trefs/bisect/curious-1\n+\trefs/bisect/curious-3\n+\trefs/bisect/curious-4\n+\t^refs/bisect/known-3\n+\tEOF\n+\n+\tgit rev-parse --symbolic-full-name --bisect >actual &&\n+\ttest_cmp expect actual\n+'\n+\n test_expect_success '--short= truncates to the actual hash length' '\n \tgit rev-parse HEAD >expect &&\n \tgit rev-parse --short=100 HEAD >actual &&\n\n-- \n2.54.0\n\n"},{"id":"543357","messageId":"xmqqv7cpepec.fsf@gitster.g","threadId":"65634","inReplyTo":"20260514-bisect-terms-v4-0-b3e3cf1b06ce@schlaraffenlan.de","subject":"Re: [PATCH v4 0/3] Avoid hardcoded \"good\"/\"bad\" bisect terms","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-05-14T19:56:27Z","receivedAt":"2026-05-14T19:56:30Z","isPatch":true,"body":"Jonas Rebmann <kernel@schlaraffenlan.de> writes:\n\n> While checking whether all output messages of git bisect were covered by\n> [PATCH 1/3] bisect: use selected alternate terms in status output I\n> found hardcoded good/bad refs leading to incompatibility of git\n> rev-parse --bisect with alternate bisect run terms. This is addressed by\n> [PATCH 3/3] rev-parse: use selected alternate terms to look up refs\n>\n> Signed-off-by: Jonas Rebmann <kernel@schlaraffenlan.de>\n> ---\n> Changes in v4:\n> - Always print bisect terms in single quote (Thanks, Junio)\n> - Split out quoting of bisect terms into separate commit\n>> - Link to v3: https://patch.msgid.link/20260417-bisect-terms-v3-0-d659fa547261@schlaraffenlan.de\n\nHaving this \"Link\" is better than nothing, but it alone is not\nsufficient to help those who mechanise patch consumption with b4.\n\n  https://b4.docs.kernel.org/en/latest/index.html\n\nPlease make sure that your cover letter of the (i+1)th iteration\n[v(i+1) 0/N] is a reply to the cover letter of the i-th iteration\n[v(i) 0/M].  With that, anybody who has the i-th iteration can\n\n 1. Check out the i-th iteration, e.g., \n\n    $ git checkout jr/bisect-custom-terms-in-output\n\n 2. Peek at any of the commits on the topic branch with notes/amlog\n    e.g.,\n\n    $ git notes --ref=amlog show HEAD\n\n 3. Check out the base, e.g.,\n\n    $ git checkout --detach master...\n\n    Note that the branch that holds the i-th iteration can now be\n    accessed via @{-1} (i.e., the branch previously checked out).\n\n 4. Tell B4 to fetch the latest round of the same series, by giving\n    one/any of the message-ID we learned earlier, and apply them.\n\n    $ b4 am -o- \\\n      \"<20260417-bisect-terms-v3-2-d659fa547261@schlaraffenlan.de>\" |\n      git am -s\n\n 5. See what changed with range-diff\n\n    $ git range-diff @{-1}...\n\n 6. When satisified, replace the topic with the new iteration.\n\n    $ git checkout -B @{-1}\n\nIt is crucial that b4 can find the newer iteration when given a\nmessage-ID from the older iteration in step 4 for this workflow to\nwork, and for that, [v4 0/3] must be a reply to [v3 0/2].  Otherwise\nb4 will say that v3 is still the last iteration and we cannot make\nprogress.\n\n> Changes in v3:\n> - when referencing newly introduced terms, reference them in single\n>   quotes (Thanks, Phillip)\n> - Prefer test_grep over grep in updated Tests (Thanks, Phillip)\n> - Improve commit messages (Thanks, Phillip)\n> - Don't leak memory after read_bisect_terms() (Thanks, Phillip)\n> - Don't leak memory after xstrfmt() (Thanks, Junio)\n> - Add test case to patch 2/2\n> - Link to v2: https://patch.msgid.link/20260323-bisect-terms-v2-0-8d6bdb2c9c7e@schlaraffenlan.de\n\nWith these improvements, v3 was already in a quite good shape, but\nthe latest makes it look even better.  Will replace.  Thanks.\n"},{"id":"543385","messageId":"074d95ed-001d-4d8d-b899-b3fd172185fd@schlaraffenlan.de","threadId":"65634","inReplyTo":"xmqqv7cpepec.fsf@gitster.g","subject":"Re: [PATCH v4 0/3] Avoid hardcoded \"good\"/\"bad\" bisect terms","fromName":"Jonas Rebmann","fromEmail":"kernel@schlaraffenlan.de","sentAt":"2026-05-15T08:07:01Z","receivedAt":"2026-05-15T08:07:04Z","isPatch":true,"body":"On 14/05/2026 21.56, Junio C Hamano wrote:\n> Please make sure that your cover letter of the (i+1)th iteration\n> [v(i+1) 0/N] is a reply to the cover letter of the i-th iteration\n> [v(i) 0/M].  With that, anybody who has the i-th iteration can\n> [...]\n\nThanks, I never knew! I've now set\n\n   git config b4.send-same-thread yes\n\nso b4 will send future rerolls In-Reply-To the cover of the\nprevious version.\n\nRegards,\nJonas\n"}]}