* [PATCH v2 0/2] Avoid hardcoded "good"/"bad" bisect terms
@ 2026-03-23 22:48 Jonas Rebmann
2026-03-23 22:48 ` [PATCH v2 1/2] bisect: use selected alternate terms in status output Jonas Rebmann
2026-03-23 22:49 ` [PATCH v2 2/2] rev-parse: use selected alternate terms too look up refs Jonas Rebmann
0 siblings, 2 replies; 9+ messages in thread
From: Jonas Rebmann @ 2026-03-23 22:48 UTC (permalink / raw)
To: git; +Cc: Chris Down, Jeff King, Jonas Rebmann
While checking whether all output messages of git bisect where covered
by [PATCH 1/2] bisect: use selected alternate terms in status output
I found hardcoded good/bad refs leading to incompatibility of git
rev-parse --bisect with alternate bisect run terms. This is addressed
by [PATCH 2/2] rev-parse: use selected alternate terms too look up refs
Signed-off-by: Jonas Rebmann <kernel@schlaraffenlan.de>
---
Changes in v2:
- Improve commit message
- Add tests
- Include second patch for hardcoded good/bad in rev-parse
- Link to v1: https://lore.kernel.org/r/20260320-bisect-terms-v1-1-c30c9540542a@schlaraffenlan.de
---
Jonas Rebmann (2):
bisect: use selected alternate terms in status output
rev-parse: use selected alternate terms too look up refs
builtin/bisect.c | 23 +++++++++++++----------
builtin/rev-parse.c | 8 ++++++--
t/t6030-bisect-porcelain.sh | 16 ++++++++++++++--
3 files changed, 33 insertions(+), 14 deletions(-)
---
base-commit: 1eceb487f285f1efa78465e6208770318f9f4892
change-id: 20260320-bisect-terms-76036676769c
Best regards,
--
Jonas Rebmann <kernel@schlaraffenlan.de>
^ permalink raw reply [flat|nested] 9+ messages in thread
* [PATCH v2 1/2] bisect: use selected alternate terms in status output
2026-03-23 22:48 [PATCH v2 0/2] Avoid hardcoded "good"/"bad" bisect terms Jonas Rebmann
@ 2026-03-23 22:48 ` Jonas Rebmann
2026-03-24 10:43 ` Phillip Wood
2026-03-23 22:49 ` [PATCH v2 2/2] rev-parse: use selected alternate terms too look up refs Jonas Rebmann
1 sibling, 1 reply; 9+ messages in thread
From: Jonas Rebmann @ 2026-03-23 22:48 UTC (permalink / raw)
To: git; +Cc: Chris Down, Jeff King, Jonas Rebmann
Alternate bisect terms are helpful when the terms "good" and "bad" are
confusing such as when bisecting for the resolution of an issue (the
first good commit) rather than the introduction of a regression.
These terms must be used when marking a commit (e.g. `git bisect new`),
they will be used in reference names (e.g. refs/bisect/new) and they are
used in parts of git's log output such as "<sha> was both old and new"
in git bisect skip's output.
However, hardcoded "good"/"bad" terms are still used in a few status
messages and can cause confusion about the status of the bisect such as:
$ git bisect old
[sha] is the first new commit
or about the required action such as:
status: waiting for bad commit, 1 good commit known
$ git bisect bad
error: Invalid command: you're currently in a new/old bisect
fatal: unknown command: 'bad'
This commit updates all remaining output messages which use hardcoded
"good" and "bad" terms to use the selected terms consistently across the
bisect output and adds tests.
Signed-off-by: Jonas Rebmann <kernel@schlaraffenlan.de>
---
builtin/bisect.c | 23 +++++++++++++----------
t/t6030-bisect-porcelain.sh | 16 ++++++++++++++--
2 files changed, 27 insertions(+), 12 deletions(-)
diff --git a/builtin/bisect.c b/builtin/bisect.c
index 4520e585d0..ee6a2c83b8 100644
--- a/builtin/bisect.c
+++ b/builtin/bisect.c
@@ -465,13 +465,16 @@ static void bisect_print_status(const struct bisect_terms *terms)
return;
if (!state.nr_good && !state.nr_bad)
- bisect_log_printf(_("status: waiting for both good and bad commits\n"));
+ bisect_log_printf(_("status: waiting for both %s and %s commits\n"),
+ terms->term_good, terms->term_bad);
else if (state.nr_good)
- bisect_log_printf(Q_("status: waiting for bad commit, %d good commit known\n",
- "status: waiting for bad commit, %d good commits known\n",
- state.nr_good), state.nr_good);
+ bisect_log_printf(Q_("status: waiting for %s commit, %d %s commit known\n",
+ "status: waiting for %s commit, %d %s commits known\n",
+ state.nr_good),
+ terms->term_bad, state.nr_good, terms->term_good);
else
- bisect_log_printf(_("status: waiting for good commit(s), bad commit known\n"));
+ bisect_log_printf(_("status: waiting for %s commit(s), %s commit known\n"),
+ terms->term_good, terms->term_bad);
}
static int bisect_next_check(const struct bisect_terms *terms,
@@ -1262,14 +1265,14 @@ static int bisect_run(struct bisect_terms *terms, int argc, const char **argv)
int rc = verify_good(terms, command.buf);
is_first_run = 0;
if (rc < 0 || 128 <= rc) {
- error(_("unable to verify %s on good"
- " revision"), command.buf);
+ error(_("unable to verify %s on %s"
+ " revision"), command.buf, terms->term_good);
res = BISECT_FAILED;
break;
}
if (rc == res) {
- error(_("bogus exit code %d for good revision"),
- rc);
+ error(_("bogus exit code %d for %s revision"),
+ rc, terms->term_good);
res = BISECT_FAILED;
break;
}
@@ -1314,7 +1317,7 @@ static int bisect_run(struct bisect_terms *terms, int argc, const char **argv)
puts(_("bisect run success"));
res = BISECT_OK;
} else if (res == BISECT_INTERNAL_SUCCESS_1ST_BAD_FOUND) {
- puts(_("bisect found first bad commit"));
+ printf(_("bisect found first %s commit\n"), terms->term_bad);
res = BISECT_OK;
} else if (res) {
error(_("bisect run failed: 'git bisect %s'"
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index 1ba9ca219e..9d28d1eedb 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -1077,8 +1077,10 @@ test_expect_success 'bisect terms shows good/bad after start' '
test_expect_success 'bisect start with one term1 and term2' '
git bisect reset &&
- git bisect start --term-old term2 --term-new term1 &&
- git bisect term2 $HASH1 &&
+ git bisect start --term-old term2 --term-new term1 >bisect_result &&
+ grep "status: waiting for both term2 and term1 commits" bisect_result &&
+ git bisect term2 $HASH1 >bisect_result &&
+ grep "status: waiting for term1 commit, 1 term2 commit known" bisect_result &&
git bisect term1 $HASH4 &&
git bisect term1 &&
git bisect term1 >bisect_result &&
@@ -1103,6 +1105,16 @@ test_expect_success 'bisect replay with term1 and term2' '
git bisect reset
'
+test_expect_success 'bisect run term1 term2' '
+ git bisect reset &&
+ git bisect start --term-new term1 --term-old term2 $HASH4 $HASH1 &&
+ git bisect term1 &&
+ git bisect run false >bisect_result &&
+ grep "bisect found first term1 commit" bisect_result &&
+ git bisect log >log_to_replay.txt &&
+ git bisect reset
+'
+
test_expect_success 'bisect start term1 term2' '
git bisect reset &&
git bisect start --term-new term1 --term-old term2 $HASH4 $HASH1 &&
--
2.53.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* [PATCH v2 2/2] rev-parse: use selected alternate terms too look up refs
2026-03-23 22:48 [PATCH v2 0/2] Avoid hardcoded "good"/"bad" bisect terms Jonas Rebmann
2026-03-23 22:48 ` [PATCH v2 1/2] bisect: use selected alternate terms in status output Jonas Rebmann
@ 2026-03-23 22:49 ` Jonas Rebmann
2026-03-24 10:49 ` Phillip Wood
2026-03-24 13:45 ` Junio C Hamano
1 sibling, 2 replies; 9+ messages in thread
From: Jonas Rebmann @ 2026-03-23 22:49 UTC (permalink / raw)
To: git; +Cc: Chris Down, Jeff King, Jonas Rebmann
An old/new bisect will name refs "refs/bisect/old" (or new) accordingly
so the hardcoded "refs/bisect/bad" (and good) yields no results in a
bisect using alternate terms.
Use the current bisect_terms to make rev-parse --bisect work in an
alternate term bisect.
Signed-off-by: Jonas Rebmann <kernel@schlaraffenlan.de>
---
builtin/rev-parse.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 01a62800e8..f20f0554ed 100644
--- a/builtin/rev-parse.c
+++ b/builtin/rev-parse.c
@@ -10,6 +10,7 @@
#include "builtin.h"
#include "abspath.h"
+#include "bisect.h"
#include "config.h"
#include "commit.h"
#include "environment.h"
@@ -940,11 +941,14 @@ int cmd_rev_parse(int argc,
continue;
}
if (!strcmp(arg, "--bisect")) {
+ char *term_bad = NULL;
+ char *term_good = NULL;
struct refs_for_each_ref_options opts = { 0 };
- opts.prefix = "refs/bisect/bad";
+ read_bisect_terms(&term_bad, &term_good);
+ opts.prefix = xstrfmt("refs/bisect/%s", term_bad);
refs_for_each_ref_ext(get_main_ref_store(the_repository),
show_reference, NULL, &opts);
- opts.prefix = "refs/bisect/good";
+ opts.prefix = xstrfmt("refs/bisect/%s", term_good);
refs_for_each_ref_ext(get_main_ref_store(the_repository),
anti_reference, NULL, &opts);
continue;
--
2.53.0
^ permalink raw reply related [flat|nested] 9+ messages in thread
* Re: [PATCH v2 1/2] bisect: use selected alternate terms in status output
2026-03-23 22:48 ` [PATCH v2 1/2] bisect: use selected alternate terms in status output Jonas Rebmann
@ 2026-03-24 10:43 ` Phillip Wood
2026-03-24 17:33 ` Junio C Hamano
0 siblings, 1 reply; 9+ messages in thread
From: Phillip Wood @ 2026-03-24 10:43 UTC (permalink / raw)
To: Jonas Rebmann, git; +Cc: Chris Down, Jeff King
Hi Jonas
On 23/03/2026 22:48, Jonas Rebmann wrote:
>
> diff --git a/builtin/bisect.c b/builtin/bisect.c
> index 4520e585d0..ee6a2c83b8 100644
> --- a/builtin/bisect.c
> +++ b/builtin/bisect.c
> @@ -465,13 +465,16 @@ static void bisect_print_status(const struct bisect_terms *terms)
> return;
>
> if (!state.nr_good && !state.nr_bad)
> - bisect_log_printf(_("status: waiting for both good and bad commits\n"));
> + bisect_log_printf(_("status: waiting for both %s and %s commits\n"),
> + terms->term_good, terms->term_bad);
If we're going to start using alternative terms it might be better to
enclose them in single quotes to make it clearer that we're referencing
the term names. Looking at the test below
"status: waiting for both 'term1' and 'term2' commits"
is clearer to me than
"status: waiting for both term1 and term2 commits"
> test_expect_success 'bisect start with one term1 and term2' '
> git bisect reset &&
> - git bisect start --term-old term2 --term-new term1 &&
> - git bisect term2 $HASH1 &&
> + git bisect start --term-old term2 --term-new term1 >bisect_result &&
> + grep "status: waiting for both term2 and term1 commits" bisect_result &&
Using test_grep would make debugging test failures easier as, if it
fails, it prints a helpful diagnostic message.
Thanks
Phillip
> + git bisect term2 $HASH1 >bisect_result &&
> + grep "status: waiting for term1 commit, 1 term2 commit known" bisect_result &&
> git bisect term1 $HASH4 &&
> git bisect term1 &&
> git bisect term1 >bisect_result &&
> @@ -1103,6 +1105,16 @@ test_expect_success 'bisect replay with term1 and term2' '
> git bisect reset
> '
>
> +test_expect_success 'bisect run term1 term2' '
> + git bisect reset &&
> + git bisect start --term-new term1 --term-old term2 $HASH4 $HASH1 &&
> + git bisect term1 &&
> + git bisect run false >bisect_result &&
> + grep "bisect found first term1 commit" bisect_result &&
> + git bisect log >log_to_replay.txt &&
> + git bisect reset
> +'
> +
> test_expect_success 'bisect start term1 term2' '
> git bisect reset &&
> git bisect start --term-new term1 --term-old term2 $HASH4 $HASH1 &&
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 2/2] rev-parse: use selected alternate terms too look up refs
2026-03-23 22:49 ` [PATCH v2 2/2] rev-parse: use selected alternate terms too look up refs Jonas Rebmann
@ 2026-03-24 10:49 ` Phillip Wood
2026-03-24 12:30 ` Jonas Rebmann
2026-03-24 13:45 ` Junio C Hamano
1 sibling, 1 reply; 9+ messages in thread
From: Phillip Wood @ 2026-03-24 10:49 UTC (permalink / raw)
To: Jonas Rebmann, git; +Cc: Chris Down, Jeff King
Hi Jonas
On 23/03/2026 22:49, Jonas Rebmann wrote:
> An old/new bisect will name refs "refs/bisect/old" (or new) accordingly
> so the hardcoded "refs/bisect/bad" (and good) yields no results in a
> bisect using alternate terms.
>
> Use the current bisect_terms to make rev-parse --bisect work in an
> alternate term bisect.
It would be clearer if the commit message started by stating the problem
that it is solving i.e. "git rev-parse --bisect" does not work if the
bisect is using alternate term names.
>
> Signed-off-by: Jonas Rebmann <kernel@schlaraffenlan.de>
> ---
> builtin/rev-parse.c | 8 ++++++--
> 1 file changed, 6 insertions(+), 2 deletions(-)
>
> diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
> index 01a62800e8..f20f0554ed 100644
> --- a/builtin/rev-parse.c
> +++ b/builtin/rev-parse.c
> @@ -10,6 +10,7 @@
> #include "builtin.h"
>
> #include "abspath.h"
> +#include "bisect.h"
> #include "config.h"
> #include "commit.h"
> #include "environment.h"
> @@ -940,11 +941,14 @@ int cmd_rev_parse(int argc,
> continue;
> }
> if (!strcmp(arg, "--bisect")) {
> + char *term_bad = NULL;
> + char *term_good = NULL;
> struct refs_for_each_ref_options opts = { 0 };
> - opts.prefix = "refs/bisect/bad";
> + read_bisect_terms(&term_bad, &term_good);
If we fail to read the terms because there is no bisect in progress then
term_bad and term_good will be NULL and so the next line will segfault.
We should also free term_bad and term_good once we've finished with them
to avoid a memory leak. It would be a good idea to add some tests.
Thanks
Phillip
> + opts.prefix = xstrfmt("refs/bisect/%s", term_bad);
> refs_for_each_ref_ext(get_main_ref_store(the_repository),
> show_reference, NULL, &opts);
> - opts.prefix = "refs/bisect/good";
> + opts.prefix = xstrfmt("refs/bisect/%s", term_good);
> refs_for_each_ref_ext(get_main_ref_store(the_repository),
> anti_reference, NULL, &opts);
> continue;
>
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 2/2] rev-parse: use selected alternate terms too look up refs
2026-03-24 10:49 ` Phillip Wood
@ 2026-03-24 12:30 ` Jonas Rebmann
2026-03-24 14:11 ` Phillip Wood
0 siblings, 1 reply; 9+ messages in thread
From: Jonas Rebmann @ 2026-03-24 12:30 UTC (permalink / raw)
To: phillip.wood, Jonas Rebmann, git; +Cc: Chris Down, Jeff King
Hi Phillip,
Thank you for your feedback, it will be addressed in v3.
On 24/03/2026 11.49, Phillip Wood wrote:
> If we fail to read the terms because there is no bisect in progress
> then term_bad and term_good will be NULL and so the next line will
> segfault.
My understanding of read_bisect_terms() was that it never sets the terms
to NULL, that if no bisect is in progress, .git/BISECT_TERMS does not
exist, and the terms default to "good"/"bad" here in bisect.c:
if (errno == ENOENT) {
free(*read_bad);
*read_bad = xstrdup("bad");
free(*read_good);
*read_good = xstrdup("good");
return;
} else {
die_errno(_("could not read file '%s'"), filename);
}
So is a NULL-check really needed on caller end?
Regards,
Jonas
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 2/2] rev-parse: use selected alternate terms too look up refs
2026-03-23 22:49 ` [PATCH v2 2/2] rev-parse: use selected alternate terms too look up refs Jonas Rebmann
2026-03-24 10:49 ` Phillip Wood
@ 2026-03-24 13:45 ` Junio C Hamano
1 sibling, 0 replies; 9+ messages in thread
From: Junio C Hamano @ 2026-03-24 13:45 UTC (permalink / raw)
To: Jonas Rebmann; +Cc: git, Chris Down, Jeff King
Jonas Rebmann <kernel@schlaraffenlan.de> writes:
> #include "abspath.h"
> +#include "bisect.h"
> #include "config.h"
> #include "commit.h"
> #include "environment.h"
> @@ -940,11 +941,14 @@ int cmd_rev_parse(int argc,
> continue;
> }
> if (!strcmp(arg, "--bisect")) {
> + char *term_bad = NULL;
> + char *term_good = NULL;
> struct refs_for_each_ref_options opts = { 0 };
> - opts.prefix = "refs/bisect/bad";
> + read_bisect_terms(&term_bad, &term_good);
> + opts.prefix = xstrfmt("refs/bisect/%s", term_bad);
> refs_for_each_ref_ext(get_main_ref_store(the_repository),
> show_reference, NULL, &opts);
> - opts.prefix = "refs/bisect/good";
> + opts.prefix = xstrfmt("refs/bisect/%s", term_good);
> refs_for_each_ref_ext(get_main_ref_store(the_repository),
> anti_reference, NULL, &opts);
Aren't return values from two xstrfmt() calls leaking in this code?
> continue;
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 2/2] rev-parse: use selected alternate terms too look up refs
2026-03-24 12:30 ` Jonas Rebmann
@ 2026-03-24 14:11 ` Phillip Wood
0 siblings, 0 replies; 9+ messages in thread
From: Phillip Wood @ 2026-03-24 14:11 UTC (permalink / raw)
To: Jonas Rebmann, phillip.wood, git; +Cc: Chris Down, Jeff King
Hi Jonas
On 24/03/2026 12:30, Jonas Rebmann wrote:
>
> On 24/03/2026 11.49, Phillip Wood wrote:
>> If we fail to read the terms because there is no bisect in progress
>> then term_bad and term_good will be NULL and so the next line will
>> segfault.
>
> My understanding of read_bisect_terms() was that it never sets the terms
> to NULL, that if no bisect is in progress, .git/BISECT_TERMS does not
> exist, and the terms default to "good"/"bad" here in bisect.c:
>
> if (errno == ENOENT) {
> free(*read_bad);
> *read_bad = xstrdup("bad");
> free(*read_good);
> *read_good = xstrdup("good");
> return;
> } else {
> die_errno(_("could not read file '%s'"), filename);
> }
>
> So is a NULL-check really needed on caller end?
Oh, sorry I'd misread it, you're correct that we don't need a NULL
check. Looking at the history of "git rev-parse --bisect" it was
introduced in ad3f9a71a82 (Add '--bisect' revision machinery argument,
2009-10-27) which also added a '--bisect' option to "git rev-list".
Looking at the implementation of that option I wonder if we should make
revision.c:for_each_bisect_ref() public and call it from
builtin/rev-parse.c rather than building the refnames and calling
refs_for_each_ref_ext().
Thanks
Phillip
>
> Regards,
> Jonas
^ permalink raw reply [flat|nested] 9+ messages in thread
* Re: [PATCH v2 1/2] bisect: use selected alternate terms in status output
2026-03-24 10:43 ` Phillip Wood
@ 2026-03-24 17:33 ` Junio C Hamano
0 siblings, 0 replies; 9+ messages in thread
From: Junio C Hamano @ 2026-03-24 17:33 UTC (permalink / raw)
To: Phillip Wood; +Cc: Jonas Rebmann, git, Chris Down, Jeff King
Phillip Wood <phillip.wood123@gmail.com> writes:
> Hi Jonas
>
> On 23/03/2026 22:48, Jonas Rebmann wrote:
>>
>> diff --git a/builtin/bisect.c b/builtin/bisect.c
>> index 4520e585d0..ee6a2c83b8 100644
>> --- a/builtin/bisect.c
>> +++ b/builtin/bisect.c
>> @@ -465,13 +465,16 @@ static void bisect_print_status(const struct bisect_terms *terms)
>> return;
>>
>> if (!state.nr_good && !state.nr_bad)
>> - bisect_log_printf(_("status: waiting for both good and bad commits\n"));
>> + bisect_log_printf(_("status: waiting for both %s and %s commits\n"),
>> + terms->term_good, terms->term_bad);
>
> If we're going to start using alternative terms it might be better to
> enclose them in single quotes to make it clearer that we're referencing
> the term names. Looking at the test below
>
> "status: waiting for both 'term1' and 'term2' commits"
>
> is clearer to me than
>
> "status: waiting for both term1 and term2 commits"
Excellent. I failed to consider this, but your reasoning makes
perfect sense. When we were limited to hardcoded good and bad,
they were clear enough without 'highlighting' with quotes, but that
is no longer the case.
>> test_expect_success 'bisect start with one term1 and term2' '
>> git bisect reset &&
>> - git bisect start --term-old term2 --term-new term1 &&
>> - git bisect term2 $HASH1 &&
>> + git bisect start --term-old term2 --term-new term1 >bisect_result &&
>> + grep "status: waiting for both term2 and term1 commits" bisect_result &&
>
> Using test_grep would make debugging test failures easier as, if it
> fails, it prints a helpful diagnostic message.
>
> Thanks
>
> Phillip
Thanks for helping.
^ permalink raw reply [flat|nested] 9+ messages in thread
end of thread, other threads:[~2026-03-24 17:33 UTC | newest]
Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-03-23 22:48 [PATCH v2 0/2] Avoid hardcoded "good"/"bad" bisect terms Jonas Rebmann
2026-03-23 22:48 ` [PATCH v2 1/2] bisect: use selected alternate terms in status output Jonas Rebmann
2026-03-24 10:43 ` Phillip Wood
2026-03-24 17:33 ` Junio C Hamano
2026-03-23 22:49 ` [PATCH v2 2/2] rev-parse: use selected alternate terms too look up refs Jonas Rebmann
2026-03-24 10:49 ` Phillip Wood
2026-03-24 12:30 ` Jonas Rebmann
2026-03-24 14:11 ` Phillip Wood
2026-03-24 13:45 ` Junio C Hamano
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox