All of lore.kernel.org
 help / color / mirror / Atom feed
From: Chris Down <chris@chrisdown.name>
To: git@vger.kernel.org
Cc: Junio C Hamano <gitster@pobox.com>,
	Johannes Schindelin <johannes.schindelin@gmx.de>,
	Christian Couder <chriscool@tuxfamily.org>,
	kernel-team@fb.com
Subject: [PATCH v2 1/2] bisect: output state before we are ready to compute bisection
Date: Fri, 6 May 2022 01:52:46 +0100	[thread overview]
Message-ID: <11edd3e4dbaac7fada8a3bcd43f4bbd353087637.1651796862.git.chris@chrisdown.name> (raw)
In-Reply-To: <cover.1651796862.git.chris@chrisdown.name>

Commit 73c6de06aff8 ("bisect: don't use invalid oid as rev when
starting") changes the behaviour of `git bisect` to consider invalid
oids as pathspecs again, as in the old shell implementation.

While that behaviour may be desirable, it can also cause confusion. For
example, while bisecting in a particular repo I encountered this:

    $ git bisect start d93ff48803f0 v6.3
    $

...which led to me sitting for a few moments, wondering why there's no
printout stating the first rev to check.

It turns out that the tag was actually "6.3", not "v6.3", and thus the
bisect was still silently started with only a bad rev, because
d93ff48803f0 was a valid oid and "v6.3" was silently considered to be a
pathspec.

While this behaviour may be desirable, it can be confusing, especially
with different repo conventions either using or not using "v" before
release names, or when a branch name or tag is simply misspelled on the
command line.

In order to avoid situations like this, make it more clear what we're
waiting for:

    $ git bisect start d93ff48803f0 v6.3
    status: waiting for good commit(s), bad commit known

We already have good output once the bisect process has begun in
earnest, so we don't need to do anything more there.

Signed-off-by: Chris Down <chris@chrisdown.name>
---
 bisect.h                    |  6 +++++
 builtin/bisect--helper.c    | 54 ++++++++++++++++++++++++++++---------
 t/t6030-bisect-porcelain.sh | 18 +++++++++++++
 3 files changed, 65 insertions(+), 13 deletions(-)

diff --git a/bisect.h b/bisect.h
index 1015aeb8ea..ccd9ad31f6 100644
--- a/bisect.h
+++ b/bisect.h
@@ -62,6 +62,12 @@ enum bisect_error {
 	BISECT_INTERNAL_SUCCESS_MERGE_BASE = -11
 };
 
+struct bisect_state {
+	int nr_good;  /* How many good commits do we have? */
+	int nr_bad;   /* How many bad commits do we have? (Well, you can only
+			  have 0 or 1, but...) */
+};
+
 enum bisect_error bisect_next_all(struct repository *r, const char *prefix);
 
 int estimate_bisect_steps(int all);
diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c
index 8b2b259ff0..9d583f651c 100644
--- a/builtin/bisect--helper.c
+++ b/builtin/bisect--helper.c
@@ -329,12 +329,12 @@ static int check_and_set_terms(struct bisect_terms *terms, const char *cmd)
 	return 0;
 }
 
-static int mark_good(const char *refname, const struct object_id *oid,
-		     int flag, void *cb_data)
+static int inc_nr(const char *refname, const struct object_id *oid,
+		  int flag, void *cb_data)
 {
-	int *m_good = (int *)cb_data;
-	*m_good = 0;
-	return 1;
+	int *nr = (int *)cb_data;
+	(*nr)++;
+	return 0;
 }
 
 static const char need_bad_and_good_revision_warning[] =
@@ -384,23 +384,49 @@ static int decide_next(const struct bisect_terms *terms,
 			     vocab_good, vocab_bad, vocab_good, vocab_bad);
 }
 
-static int bisect_next_check(const struct bisect_terms *terms,
-			     const char *current_term)
+static struct bisect_state bisect_status(const struct bisect_terms *terms)
 {
-	int missing_good = 1, missing_bad = 1;
 	char *bad_ref = xstrfmt("refs/bisect/%s", terms->term_bad);
 	char *good_glob = xstrfmt("%s-*", terms->term_good);
+	struct bisect_state bs;
+
+	memset(&bs, 0, sizeof(bs));
 
 	if (ref_exists(bad_ref))
-		missing_bad = 0;
+		bs.nr_bad = 1;
 
-	for_each_glob_ref_in(mark_good, good_glob, "refs/bisect/",
-			     (void *) &missing_good);
+	for_each_glob_ref_in(inc_nr, good_glob, "refs/bisect/",
+			     (void *) &bs.nr_good);
 
 	free(good_glob);
 	free(bad_ref);
 
-	return decide_next(terms, current_term, missing_good, missing_bad);
+	return bs;
+}
+
+static void bisect_print_status(const struct bisect_terms *terms)
+{
+	const struct bisect_state bs = bisect_status(terms);
+
+	/* If we had both, we'd already be started, and shouldn't get here. */
+	if (bs.nr_good && bs.nr_bad)
+		return;
+
+	if (!bs.nr_good && !bs.nr_bad)
+		printf(_("status: waiting for both good and bad commits\n"));
+	else if (bs.nr_good)
+		printf(Q_("status: waiting for bad commit, %d good commit known\n",
+			  "status: waiting for bad commit, %d good commits known\n",
+			  bs.nr_good), bs.nr_good);
+	else
+		printf(_("status: waiting for good commit(s), bad commit known\n"));
+}
+
+static int bisect_next_check(const struct bisect_terms *terms,
+			     const char *current_term)
+{
+	const struct bisect_state bs = bisect_status(terms);
+	return decide_next(terms, current_term, !bs.nr_good, !bs.nr_bad);
 }
 
 static int get_terms(struct bisect_terms *terms)
@@ -606,8 +632,10 @@ static enum bisect_error bisect_next(struct bisect_terms *terms, const char *pre
 
 static enum bisect_error bisect_auto_next(struct bisect_terms *terms, const char *prefix)
 {
-	if (bisect_next_check(terms, NULL))
+	if (bisect_next_check(terms, NULL)) {
+		bisect_print_status(terms);
 		return BISECT_OK;
+	}
 
 	return bisect_next(terms, prefix);
 }
diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh
index 5382e5d216..a02587d1a7 100755
--- a/t/t6030-bisect-porcelain.sh
+++ b/t/t6030-bisect-porcelain.sh
@@ -1025,4 +1025,22 @@ test_expect_success 'bisect visualize with a filename with dash and space' '
 	git bisect visualize -p -- "-hello 2"
 '
 
+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 &&
+       git bisect good "$HASH1" >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
+'
+
+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 &&
+       git bisect bad "$HASH4" >output &&
+       grep -F "waiting for good commit(s), bad commit known" output
+'
+
 test_done
-- 
2.36.0


  reply	other threads:[~2022-05-06  0:52 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-05-06  0:52 [PATCH v2 0/2] bisect: status improvements when bisect is not fully fleshed out Chris Down
2022-05-06  0:52 ` Chris Down [this message]
2022-05-06  2:52   ` [PATCH v2 1/2] bisect: output state before we are ready to compute bisection Taylor Blau
2022-05-06 10:14     ` Chris Down
2022-05-06 16:42     ` Junio C Hamano
2022-05-06 18:12   ` Junio C Hamano
2022-05-06  0:52 ` [PATCH v2 2/2] bisect: output bisect setup status in bisect log Chris Down
2022-05-06  3:03   ` Taylor Blau
2022-05-06 10:09     ` Chris Down
2022-05-09 15:41       ` Taylor Blau
2022-05-06 16:57     ` Junio C Hamano
2022-05-06 16:47   ` Junio C Hamano
2022-05-06 18:18   ` Junio C Hamano
2022-05-09 15:43     ` Taylor Blau
2022-05-09 16:08       ` Junio C Hamano
2022-05-09 16:27         ` Taylor Blau
2022-05-07 10:58 ` [PATCH v2 0/2] bisect: status improvements when bisect is not fully fleshed out Chris Down
2022-05-07 18:25   ` Junio C Hamano
2022-05-07 21:22     ` Chris Down

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=11edd3e4dbaac7fada8a3bcd43f4bbd353087637.1651796862.git.chris@chrisdown.name \
    --to=chris@chrisdown.name \
    --cc=chriscool@tuxfamily.org \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=johannes.schindelin@gmx.de \
    --cc=kernel-team@fb.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.