Git development
 help / color / mirror / Atom feed
From: "Harald Nordgren via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Johannes Sixt <j6t@kdbg.org>, Harald Nordgren <haraldnordgren@gmail.com>
Subject: [PATCH v6 0/2] bisect: add --reset-when-found to leave when done
Date: Sun, 02 Aug 2026 21:24:18 +0000	[thread overview]
Message-ID: <pull.2335.v6.git.git.1785705860.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.2335.v5.git.git.1785663075.gitgitgadget@gmail.com>

Add a --reset-when-found option to git bisect that resets the bisect session
when culprit is found.

Changes in v6:

 * Reuse the existing bad bisect ref instead of propagating the culprit OID
   through bisect_next_all().
 * Remove the redundant reset_when_found_arg_seen flag and use
   RESET_WHEN_FOUND_NONE to detect whether the option was given.

Changes in v5:

 * Move automatic reset handling to cmd_bisect() after subcommand resources
   are closed.
 * Propagate the first-bad commit OID from bisect_next_all() and remove
   defer_reset plumbing.
 * Separate checkout from state cleanup in bisect_reset(), and use bool for
   its quiet flag.

Changes in v4:

 * Simplify translation calls.
 * Avoid git subshell calls in tests, that can bury errors.

Changes in v3:

 * Rename --auto-reset to --reset-when-found, including internal names.
 * Defer git bisect run cleanup until captured output is printed and
   BISECT_RUN is closed. Drop the open-descriptor preparatory change,
   retaining the existing filename-based output handling.

Changes in v2:

 * Add option --auto-reset[=<where>] with option to go to final commit as
   well as original.
 * Refactored tests.

Harald Nordgren (2):
  bisect: let bisect_reset() optionally check out quietly
  bisect: add --reset-when-found to leave when done

 Documentation/git-bisect.adoc |  14 ++-
 bisect.c                      |   2 +
 builtin/bisect.c              | 162 +++++++++++++++++++++++++++++++---
 t/t6030-bisect-porcelain.sh   | 121 +++++++++++++++++++++++++
 4 files changed, 285 insertions(+), 14 deletions(-)


base-commit: a97fcc37c2bc6340a8d7ce78dedf227aac4e9aa7
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2335%2FHaraldNordgren%2Fbisect-auto-reset-v6
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2335/HaraldNordgren/bisect-auto-reset-v6
Pull-Request: https://github.com/git/git/pull/2335

Range-diff vs v5:

 1:  b6ab87fd29 = 1:  b6ab87fd29 bisect: let bisect_reset() optionally check out quietly
 2:  ec362f3b82 ! 2:  97a4da5537 bisect: add --reset-when-found to leave when done
     @@ Commit message
          Persist the selected target in a BISECT_RESET_WHEN_FOUND state file
          and perform the reset quietly.
      
     -    Propagate the internal first-bad result and its commit to
     -    cmd_bisect(), which performs the reset after the subcommand has
     -    returned. For "git bisect run", this means BISECT_RUN has been printed
     -    and closed before cleanup, which also works on systems that cannot
     -    unlink an open file.
     +    Let the internal first-bad result propagate to cmd_bisect(), which
     +    performs the reset using the existing bad bisect ref after the
     +    subcommand has returned. For "git bisect run", this means BISECT_RUN
     +    has been printed and closed before cleanup, which also works on systems
     +    that cannot unlink an open file.
      
          Reject this option together with "--no-checkout", since that mode must
          not check out either target.
     @@ bisect.c: static GIT_PATH_FUNC(git_path_bisect_start, "BISECT_START")
       
       static void read_bisect_paths(struct strvec *array)
       {
     -@@ bisect.c: void read_bisect_terms(char **read_bad, char **read_good)
     -  * the end of bisect_helper::cmd_bisect__helper() helps bypassing
     -  * all the code related to finding a commit to test.
     -  */
     --enum bisect_error bisect_next_all(struct repository *r, const char *prefix)
     -+enum bisect_error bisect_next_all(struct repository *r, const char *prefix,
     -+				  struct object_id *first_bad)
     - {
     - 	struct strvec rev_argv = STRVEC_INIT;
     - 	struct rev_info revs = REV_INFO_INIT;
     -@@ bisect.c: enum bisect_error bisect_next_all(struct repository *r, const char *prefix)
     - 		res = error_if_skipped_commits(tried, current_bad_oid);
     - 		if (res)
     - 			goto cleanup;
     -+		oidcpy(first_bad, bisect_rev);
     - 		printf("%s is the first '%s' commit\n", oid_to_hex(bisect_rev),
     - 			term_bad);
     - 
      @@ bisect.c: int bisect_clean_state(void)
       	unlink_or_warn(git_path_bisect_run());
       	unlink_or_warn(git_path_bisect_terms());
     @@ bisect.c: int bisect_clean_state(void)
       	 * Cleanup BISECT_START last to support the --no-checkout option
       	 * introduced in the commit 4796e823a.
      
     - ## bisect.h ##
     -@@ bisect.h: struct bisect_state {
     - 	unsigned int nr_bad;
     - };
     - 
     --enum bisect_error bisect_next_all(struct repository *r, const char *prefix);
     -+enum bisect_error bisect_next_all(struct repository *r, const char *prefix,
     -+				  struct object_id *first_bad);
     - 
     - int estimate_bisect_steps(int all);
     - 
     -
       ## builtin/bisect.c ##
      @@ builtin/bisect.c: static GIT_PATH_FUNC(git_path_bisect_start, "BISECT_START")
       static GIT_PATH_FUNC(git_path_bisect_log, "BISECT_LOG")
     @@ builtin/bisect.c: static const char * const git_bisect_usage[] = {
       struct add_bisect_ref_data {
       	struct rev_info *revs;
       	unsigned int object_flags;
     -@@ builtin/bisect.c: struct bisect_terms {
     - 	char *term_bad;
     - };
     - 
     -+static struct object_id first_bad_oid;
     -+
     - static void free_terms(struct bisect_terms *terms)
     - {
     - 	FREE_AND_NULL(terms->term_good);
      @@ builtin/bisect.c: static int bisect_reset(const char *commit, bool quiet)
       	}
       
     @@ builtin/bisect.c: static int bisect_reset(const char *commit, bool quiet)
      +
      +static int bisect_reset_when_found(enum reset_when_found_mode mode)
      +{
     -+	char first_bad_hex[GIT_MAX_HEXSZ + 1];
     -+	const char *commit = NULL;
     ++	struct bisect_terms terms = { 0 };
     ++	char *commit = NULL;
      +	int res;
      +
     -+	if (mode == RESET_WHEN_FOUND_TO_FOUND)
     -+		commit = oid_to_hex_r(first_bad_hex, &first_bad_oid);
     -+	else if (mode == RESET_WHEN_FOUND_NONE)
     ++	if (mode == RESET_WHEN_FOUND_TO_FOUND) {
     ++		read_bisect_terms(&terms.term_bad, &terms.term_good);
     ++		commit = xstrfmt("refs/bisect/%s", terms.term_bad);
     ++	} else if (mode == RESET_WHEN_FOUND_NONE) {
      +		BUG("automatic reset requested without a reset mode");
     ++	}
      +
      +	res = bisect_reset(commit, true);
      +	if (!res)
      +		res = bisect_clean_state();
      +
     ++	free(commit);
     ++	free_terms(&terms);
      +	return res;
       }
       
     @@ builtin/bisect.c: static int bisect_successful(struct bisect_terms *terms)
       {
       	enum bisect_error res;
       
     -@@ builtin/bisect.c: static enum bisect_error bisect_next(struct bisect_terms *terms, const char *pre
     - 		return BISECT_FAILED;
     - 
     - 	/* Perform all bisection computation */
     --	res = bisect_next_all(the_repository, prefix);
     -+	res = bisect_next_all(the_repository, prefix, &first_bad_oid);
     - 
     - 	if (res == BISECT_INTERNAL_SUCCESS_1ST_BAD_FOUND) {
     - 		res = bisect_successful(terms);
      @@ builtin/bisect.c: static enum bisect_error bisect_next(struct bisect_terms *terms, const char *pre
       	return res;
       }
     @@ builtin/bisect.c: static int bisect_run(struct bisect_terms *terms, int argc, co
       	int temporary_stdout_fd, saved_stdout;
       	int is_first_run = 1;
      +	enum reset_when_found_mode reset_when_found = RESET_WHEN_FOUND_NONE;
     -+	bool reset_when_found_arg_seen = false;
       
       	if (bisect_next_check(terms, NULL))
       		return BISECT_FAILED;
       
      +	if (argc && !strcmp(argv[0], "--reset-when-found")) {
      +		reset_when_found = RESET_WHEN_FOUND_TO_ORIGINAL;
     -+		reset_when_found_arg_seen = true;
      +	} else if (argc && skip_prefix(argv[0], "--reset-when-found=",
      +				    &reset_when_found_arg)) {
      +		if (parse_reset_when_found(reset_when_found_arg,
      +					   &reset_when_found))
      +			return BISECT_FAILED;
     -+		reset_when_found_arg_seen = true;
      +	}
      +
      +	if (reset_when_found != RESET_WHEN_FOUND_NONE &&
     @@ builtin/bisect.c: static int bisect_run(struct bisect_terms *terms, int argc, co
      +		return error(_("options '%s' and '%s' cannot be used together"),
      +			     "--reset-when-found", "--no-checkout");
      +
     -+	if (reset_when_found_arg_seen) {
     ++	if (reset_when_found != RESET_WHEN_FOUND_NONE) {
      +		write_file(git_path_bisect_reset_when_found(), "%s\n",
      +			   reset_when_found_mode_name(reset_when_found));
      +		argc--;

-- 
gitgitgadget

  parent reply	other threads:[~2026-08-02 21:24 UTC|newest]

Thread overview: 38+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-07-16  5:35 [PATCH 0/3] bisect: add --auto-reset to leave when done Harald Nordgren via GitGitGadget
2026-07-16  5:35 ` [PATCH 1/3] bisect: read run output from the open descriptor Harald Nordgren via GitGitGadget
2026-07-16  5:35 ` [PATCH 2/3] bisect: let bisect_reset() optionally check out quietly Harald Nordgren via GitGitGadget
2026-07-16  5:35 ` [PATCH 3/3] bisect: add --auto-reset to leave when done Harald Nordgren via GitGitGadget
2026-07-16 17:22   ` Junio C Hamano
2026-07-16 21:22     ` Harald Nordgren
2026-07-17  5:00       ` Junio C Hamano
2026-07-17  9:16         ` Harald Nordgren
2026-07-17 16:43           ` Junio C Hamano
2026-07-17 18:27 ` [PATCH v2 0/3] " Harald Nordgren via GitGitGadget
2026-07-17 18:27   ` [PATCH v2 1/3] bisect: read run output from the open descriptor Harald Nordgren via GitGitGadget
2026-07-17 22:42     ` Junio C Hamano
2026-07-18 16:24     ` Johannes Sixt
2026-07-17 18:27   ` [PATCH v2 2/3] bisect: let bisect_reset() optionally check out quietly Harald Nordgren via GitGitGadget
2026-07-17 18:27   ` [PATCH v2 3/3] bisect: add --auto-reset to leave when done Harald Nordgren via GitGitGadget
2026-07-18 16:18     ` Johannes Sixt
2026-07-20  1:14       ` Junio C Hamano
2026-07-20  9:10   ` [PATCH v3 0/2] " Harald Nordgren via GitGitGadget
2026-07-20  9:10     ` [PATCH v3 1/2] bisect: let bisect_reset() optionally check out quietly Harald Nordgren via GitGitGadget
2026-07-20  9:10     ` [PATCH v3 2/2] bisect: add --reset-when-found to leave when done Harald Nordgren via GitGitGadget
2026-07-23  9:17       ` Johannes Sixt
2026-07-23 14:27         ` Junio C Hamano
2026-08-01  6:51         ` Harald Nordgren
2026-07-20 17:20     ` [PATCH v3 0/2] bisect: add --auto-reset " Junio C Hamano
2026-08-01  9:44     ` [PATCH v4 0/2] bisect: add --reset-when-found " Harald Nordgren via GitGitGadget
2026-08-01  9:44       ` [PATCH v4 1/2] bisect: let bisect_reset() optionally check out quietly Harald Nordgren via GitGitGadget
2026-08-01 19:15         ` Junio C Hamano
2026-08-01  9:44       ` [PATCH v4 2/2] bisect: add --reset-when-found to leave when done Harald Nordgren via GitGitGadget
2026-08-01 19:54         ` Junio C Hamano
2026-08-01 21:40           ` Junio C Hamano
2026-08-02  9:31       ` [PATCH v5 0/2] " Harald Nordgren via GitGitGadget
2026-08-02  9:31         ` [PATCH v5 1/2] bisect: let bisect_reset() optionally check out quietly Harald Nordgren via GitGitGadget
2026-08-02  9:31         ` [PATCH v5 2/2] bisect: add --reset-when-found to leave when done Harald Nordgren via GitGitGadget
2026-08-02 16:01         ` [PATCH v5 0/2] " Junio C Hamano
2026-08-02 21:24         ` Harald Nordgren via GitGitGadget [this message]
2026-08-02 21:24           ` [PATCH v6 1/2] bisect: let bisect_reset() optionally check out quietly Harald Nordgren via GitGitGadget
2026-08-02 21:24           ` [PATCH v6 2/2] bisect: add --reset-when-found to leave when done Harald Nordgren via GitGitGadget
2026-08-03  0:08             ` Junio C Hamano

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=pull.2335.v6.git.git.1785705860.gitgitgadget@gmail.com \
    --to=gitgitgadget@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=haraldnordgren@gmail.com \
    --cc=j6t@kdbg.org \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox