diff --git a/bisect.c b/bisect.c index 985b96ed132516..200921ef28b1d8 100644 --- a/bisect.c +++ b/bisect.c @@ -713,7 +713,7 @@ static int is_expected_rev(const struct object_id *oid) } enum bisect_error bisect_checkout(const struct object_id *bisect_rev, - int no_checkout) + int no_checkout, int force_checkout) { struct commit *commit; struct pretty_print_context pp = {0}; @@ -728,8 +728,11 @@ enum bisect_error bisect_checkout(const struct object_id *bisect_rev, struct child_process cmd = CHILD_PROCESS_INIT; cmd.git_cmd = 1; - strvec_pushl(&cmd.args, "checkout", "-q", - oid_to_hex(bisect_rev), "--", NULL); + strvec_pushl(&cmd.args, "checkout", "-q"); + if (force_checkout) { + strvec_pushl(&cmd.args, "--force"); + } + strvec_pushl(&cmd.args, oid_to_hex(bisect_rev), "--", NULL); if (run_command(&cmd)) /* * Errors in `run_command()` itself, signaled by res < 0, @@ -850,7 +853,7 @@ static enum bisect_error check_merge_bases(int rev_nr, struct commit **rev, int handle_skipped_merge_base(mb); } else { printf(_("Bisecting: a merge base must be tested\n")); - res = bisect_checkout(mb, no_checkout); + res = bisect_checkout(mb, no_checkout, 0); if (!res) /* indicate early success */ res = BISECT_INTERNAL_SUCCESS_MERGE_BASE; @@ -1104,7 +1107,7 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix) /* Clean up objects used, as they will be reused. */ repo_clear_commit_marks(r, ALL_REV_FLAGS); - res = bisect_checkout(bisect_rev, no_checkout); + res = bisect_checkout(bisect_rev, no_checkout, 0); cleanup: release_revisions(&revs); strvec_clear(&rev_argv); diff --git a/bisect.h b/bisect.h index ee3fd65f3bdb89..8e3287a37156a5 100644 --- a/bisect.h +++ b/bisect.h @@ -80,6 +80,6 @@ void read_bisect_terms(const char **bad, const char **good); int bisect_clean_state(void); enum bisect_error bisect_checkout(const struct object_id *bisect_rev, - int no_checkout); + int no_checkout, int force_checkout); #endif diff --git a/builtin/bisect.c b/builtin/bisect.c index 47fcce59ff78bf..23c4784e5113a5 100644 --- a/builtin/bisect.c +++ b/builtin/bisect.c @@ -1173,7 +1173,7 @@ static int do_bisect_run(const char *command) return run_command(&cmd); } -static int verify_good(const struct bisect_terms *terms, const char *command) +static int verify_good(const struct bisect_terms *terms, const char *command, int force_checkout) { int rc; enum bisect_error res; @@ -1189,13 +1189,13 @@ static int verify_good(const struct bisect_terms *terms, const char *command) if (read_ref(no_checkout ? "BISECT_HEAD" : "HEAD", ¤t_rev)) return -1; - res = bisect_checkout(&good_rev, no_checkout); + res = bisect_checkout(&good_rev, no_checkout, force_checkout); if (res != BISECT_OK) return -1; rc = do_bisect_run(command); - res = bisect_checkout(¤t_rev, no_checkout); + res = bisect_checkout(¤t_rev, no_checkout, force_checkout); if (res != BISECT_OK) return -1; @@ -1209,6 +1209,7 @@ static int bisect_run(struct bisect_terms *terms, int argc, const char **argv) const char *new_state; int temporary_stdout_fd, saved_stdout; int is_first_run = 1; + int force_checkout = 0; if (bisect_next_check(terms, NULL)) return BISECT_FAILED; @@ -1218,8 +1219,15 @@ static int bisect_run(struct bisect_terms *terms, int argc, const char **argv) return BISECT_FAILED; } - sq_quote_argv(&command, argv); - strbuf_ltrim(&command); + if (argv[0] == "--force") { + force_checkout = 1; + sq_quote_argv(&command, argv[1]); + strbuf_ltrim(&command); + } else { + sq_quote_argv(&command, argv); + strbuf_ltrim(&command); + } + while (1) { res = do_bisect_run(command.buf); @@ -1231,7 +1239,7 @@ static int bisect_run(struct bisect_terms *terms, int argc, const char **argv) * missing or non-executable script. */ if (is_first_run && (res == 126 || res == 127)) { - int rc = verify_good(terms, command.buf); + int rc = verify_good(terms, command.buf, force_checkout); is_first_run = 0; if (rc < 0 || 128 <= rc) { error(_("unable to verify %s on good"