Git development
 help / color / mirror / Atom feed
* [PATCH v3 0/2] Avoid hardcoded "good"/"bad" bisect terms
@ 2026-04-17 16:48 Jonas Rebmann
  2026-04-17 16:48 ` [PATCH v3 1/2] bisect: use selected alternate terms in status output Jonas Rebmann
  2026-04-17 16:48 ` [PATCH v3 2/2] rev-parse: use selected alternate terms to look up refs Jonas Rebmann
  0 siblings, 2 replies; 4+ messages in thread
From: Jonas Rebmann @ 2026-04-17 16:48 UTC (permalink / raw)
  To: git; +Cc: Chris Down, Jeff King, Jonas Rebmann, Phillip Wood

While checking whether all output messages of git bisect were 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 to look up refs

Signed-off-by: Jonas Rebmann <kernel@schlaraffenlan.de>
---
Changes in v3:
- when referencing newly introduced terms, reference them in single
  quotes (Thanks, Phillip)
- Prefer test_grep over grep in updated Tests (Thanks, Phillip)
- Improve commit messages (Thanks, Phillip)
- Don't leak memory after read_bisect_terms() (Thanks, Phillip)
- Don't leak memory after xstrfmt() (Thanks, Junio)
- Add test case to patch 2/2
- Link to v2: https://patch.msgid.link/20260323-bisect-terms-v2-0-8d6bdb2c9c7e@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 to look up refs

 builtin/bisect.c            | 23 +++++++++++++----------
 builtin/rev-parse.c         | 15 +++++++++++++--
 t/t1500-rev-parse.sh        | 25 +++++++++++++++++++++++++
 t/t6030-bisect-porcelain.sh | 38 +++++++++++++++++++++++++-------------
 4 files changed, 76 insertions(+), 25 deletions(-)
---
base-commit: 1b296b0f55885fa8fc649c4b31c37f3d86f3f9cf
change-id: 20260320-bisect-terms-76036676769c

Best regards,
--  
Jonas Rebmann <kernel@schlaraffenlan.de>


^ permalink raw reply	[flat|nested] 4+ messages in thread

* [PATCH v3 1/2] bisect: use selected alternate terms in status output
  2026-04-17 16:48 [PATCH v3 0/2] Avoid hardcoded "good"/"bad" bisect terms Jonas Rebmann
@ 2026-04-17 16:48 ` Jonas Rebmann
  2026-04-17 19:50   ` Junio C Hamano
  2026-04-17 16:48 ` [PATCH v3 2/2] rev-parse: use selected alternate terms to look up refs Jonas Rebmann
  1 sibling, 1 reply; 4+ messages in thread
From: Jonas Rebmann @ 2026-04-17 16:48 UTC (permalink / raw)
  To: git; +Cc: Chris Down, Jeff King, Jonas Rebmann, Phillip Wood

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 bad 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 | 38 +++++++++++++++++++++++++-------------
 2 files changed, 38 insertions(+), 23 deletions(-)

diff --git a/builtin/bisect.c b/builtin/bisect.c
index 4520e585d0..2b44911c0b 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..3751e5cc8b 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -1077,12 +1077,14 @@ 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 &&
+	test_grep "status: waiting for both '\''term2'\'' and '\''term1'\'' commits" bisect_result &&
+	git bisect term2 $HASH1 >bisect_result &&
+	test_grep "status: waiting for '\''term1'\'' commit, 1 '\''term2'\'' commit known" bisect_result &&
 	git bisect term1 $HASH4 &&
 	git bisect term1 &&
 	git bisect term1 >bisect_result &&
-	grep "$HASH2 is the first term1 commit" bisect_result &&
+	test_grep "$HASH2 is the first term1 commit" bisect_result &&
 	git bisect log >log_to_replay.txt &&
 	git bisect reset
 '
@@ -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 &&
+	test_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 &&
@@ -1224,29 +1236,29 @@ test_expect_success 'bisect visualize with a filename with dash and space' '
 test_expect_success 'bisect state output with multiple good commits' '
 	git bisect reset &&
 	git bisect start >output &&
-	grep "waiting for both good and bad commits" output &&
+	grep "waiting for both '\''good'\'' and '\''bad'\'' commits" output &&
 	git bisect log >output &&
-	grep "waiting for both good and bad commits" output &&
+	grep "waiting for both '\''good'\'' and '\''bad'\'' commits" output &&
 	git bisect good "$HASH1" >output &&
-	grep "waiting for bad commit, 1 good commit known" output &&
+	grep "waiting for '\''bad'\'' commit, 1 '\''good'\'' commit known" output &&
 	git bisect log >output &&
-	grep "waiting for bad commit, 1 good commit known" output &&
+	grep "waiting for '\''bad'\'' commit, 1 '\''good'\'' commit known" output &&
 	git bisect good "$HASH2" >output &&
-	grep "waiting for bad commit, 2 good commits known" output &&
+	grep "waiting for '\''bad'\'' commit, 2 '\''good'\'' commits known" output &&
 	git bisect log >output &&
-	grep "waiting for bad commit, 2 good commits known" output
+	grep "waiting for '\''bad'\'' commit, 2 '\''good'\'' commits known" output
 '
 
 test_expect_success 'bisect state output with bad commit' '
 	git bisect reset &&
 	git bisect start >output &&
-	grep "waiting for both good and bad commits" output &&
+	grep "waiting for both '\''good'\'' and '\''bad'\'' commits" output &&
 	git bisect log >output &&
-	grep "waiting for both good and bad commits" output &&
+	grep "waiting for both '\''good'\'' and '\''bad'\'' commits" output &&
 	git bisect bad "$HASH4" >output &&
-	grep -F "waiting for good commit(s), bad commit known" output &&
+	grep -F "waiting for '\''good'\'' commit(s), '\''bad'\'' commit known" output &&
 	git bisect log >output &&
-	grep -F "waiting for good commit(s), bad commit known" output
+	grep -F "waiting for '\''good'\'' commit(s), '\''bad'\'' commit known" output
 '
 
 test_expect_success 'verify correct error message' '

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [PATCH v3 2/2] rev-parse: use selected alternate terms to look up refs
  2026-04-17 16:48 [PATCH v3 0/2] Avoid hardcoded "good"/"bad" bisect terms Jonas Rebmann
  2026-04-17 16:48 ` [PATCH v3 1/2] bisect: use selected alternate terms in status output Jonas Rebmann
@ 2026-04-17 16:48 ` Jonas Rebmann
  1 sibling, 0 replies; 4+ messages in thread
From: Jonas Rebmann @ 2026-04-17 16:48 UTC (permalink / raw)
  To: git; +Cc: Chris Down, Jeff King, Jonas Rebmann, Phillip Wood

git rev-parse --bisect does not work when alternate bisect terms are
used, simply listing no revisions at all.

This is because a such bisect using e.g. "old" and "new" in place of
"good" and "bad" 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  | 15 +++++++++++++--
 t/t1500-rev-parse.sh | 25 +++++++++++++++++++++++++
 2 files changed, 38 insertions(+), 2 deletions(-)

diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c
index 218b5f34d6..7531edae9e 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,13 +941,23 @@ int cmd_rev_parse(int argc,
 				continue;
 			}
 			if (!strcmp(arg, "--bisect")) {
+				char *prefix;
+				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);
+				prefix = xstrfmt("refs/bisect/%s", term_bad);
+				opts.prefix = prefix;
 				refs_for_each_ref_ext(get_main_ref_store(the_repository),
 						      show_reference, NULL, &opts);
-				opts.prefix = "refs/bisect/good";
+				free(prefix);
+				prefix = xstrfmt("refs/bisect/%s", term_good);
+				opts.prefix = prefix;
 				refs_for_each_ref_ext(get_main_ref_store(the_repository),
 						      anti_reference, NULL, &opts);
+				free(prefix);
+				free(term_good);
+				free(term_bad);
 				continue;
 			}
 			if (opt_with_value(arg, "--branches", &arg)) {
diff --git a/t/t1500-rev-parse.sh b/t/t1500-rev-parse.sh
index 98c5a772bd..38067d95f7 100755
--- a/t/t1500-rev-parse.sh
+++ b/t/t1500-rev-parse.sh
@@ -337,6 +337,31 @@ test_expect_success 'rev-parse --bisect includes bad, excludes good' '
 	test_cmp expect actual
 '
 
+test_expect_success 'rev-parse --bisect works with alternate terms' '
+	test_commit_bulk 6 &&
+
+	git bisect start --term-old=known --term-new=curious &&
+
+	git update-ref refs/bisect/curious-1 HEAD~1 &&
+	git update-ref refs/bisect/bad HEAD~2 &&
+	git update-ref refs/bisect/curious-3 HEAD~3 &&
+	git update-ref refs/bisect/known-3 HEAD~3 &&
+	git update-ref refs/bisect/curious-4 HEAD~4 &&
+	git update-ref refs/bisect/good HEAD~4 &&
+
+	# Note: refs/bisect/bad and refs/bisect/goood should be ignored because this
+	# is a bisect with custom terms (known/curious)
+	cat >expect <<-EOF &&
+	refs/bisect/curious-1
+	refs/bisect/curious-3
+	refs/bisect/curious-4
+	^refs/bisect/known-3
+	EOF
+
+	git rev-parse --symbolic-full-name --bisect >actual &&
+	test_cmp expect actual
+'
+
 test_expect_success '--short= truncates to the actual hash length' '
 	git rev-parse HEAD >expect &&
 	git rev-parse --short=100 HEAD >actual &&

-- 
2.53.0


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH v3 1/2] bisect: use selected alternate terms in status output
  2026-04-17 16:48 ` [PATCH v3 1/2] bisect: use selected alternate terms in status output Jonas Rebmann
@ 2026-04-17 19:50   ` Junio C Hamano
  0 siblings, 0 replies; 4+ messages in thread
From: Junio C Hamano @ 2026-04-17 19:50 UTC (permalink / raw)
  To: Jonas Rebmann; +Cc: git, Chris Down, Jeff King, Phillip Wood

Jonas Rebmann <kernel@schlaraffenlan.de> writes:

>  	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);

I think this was new in v2 (which I somehow did not pick up).  Good
finding, but not limited to this one, I wonder how these custom
terms interact with localization.  The 'quotes' around these terms
do help by hinting that they are not a normal adjectives given to
the noun 'commits', so that might be good enough, but that still
assumes that the .term_good and .term_bad, even when they are not
'good' and 'bad', are good adjectives that can apply to 'commits'.
I'd expect in most use cases that would hold, but the command does
not prevent you from calling more recent ones 'dog commits' and the
ones before the transition point 'cat commits' ;-).

Of course, rephrasing the above to

	waiting for both commit(s) marked as '%s' and as '%s'

would be ultra-awkward, even if it may be the safest.  So I dunno.

> -				error(_("unable to verify %s on good"
> -					" revision"), command.buf);
> +				error(_("unable to verify %s on %s revision"),
> +				      command.buf, terms->term_good);

And from that point of view, this unquoted "ON good REVISION" might
become a problem, because it asssumes that .term_good would be
readable as an adjective given to the noun 'revision', which might
not hold true even without translation.  The command.buf contains a
command with its arguments, and .term_good contains the custom term.
Perhaps both should be placed in '%s' quotes?

>  				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);

Ditto for quoting 'good' that is no longer a normal adjective that
adorns the noun 'revision', in the context of a translated message.

> @@ -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);

Ditto for quoting 'bad' here.

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2026-04-17 19:50 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-04-17 16:48 [PATCH v3 0/2] Avoid hardcoded "good"/"bad" bisect terms Jonas Rebmann
2026-04-17 16:48 ` [PATCH v3 1/2] bisect: use selected alternate terms in status output Jonas Rebmann
2026-04-17 19:50   ` Junio C Hamano
2026-04-17 16:48 ` [PATCH v3 2/2] rev-parse: use selected alternate terms to look up refs Jonas Rebmann

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox