[PATCH v13 4a/8] bisect: introduce support for --bisect-mode option in bisect--helper.
From: Jon Seymour <hidden>
Date: 2016-06-15 22:51:43
Subsystem:
the rest · Maintainer:
Linus Torvalds
If --bisect-mode=update-ref is specified, then the bisection process uses: git update-ref --no-deref HEAD <trial> at each trial instead of: git checkout <trial> Improved-by: Christian Couder [off-list ref] Signed-off-by: Jon Seymour <redacted> --- bisect.c | 33 ++++++++++++++++++++++----------- bisect.h | 2 +- builtin/bisect--helper.c | 9 +++++++-- 3 files changed, 30 insertions(+), 14 deletions(-) A replacement for [PATCH v13 4/8].
diff --git a/bisect.c b/bisect.c
index dd7e8ed..0427117 100644
--- a/bisect.c
+++ b/bisect.c@@ -24,6 +24,7 @@ struct argv_array { static const char *argv_checkout[] = {"checkout", "-q", NULL, "--", NULL}; static const char *argv_show_branch[] = {"show-branch", NULL, NULL}; +static const char *argv_update_ref[] = {"update-ref", "--no-deref", "HEAD", NULL, NULL}; /* bits #0-15 in revision.h */
@@ -707,16 +708,23 @@ static void mark_expected_rev(char *bisect_rev_hex) die("closing file %s: %s", filename, strerror(errno)); } -static int bisect_checkout(char *bisect_rev_hex) +static int bisect_checkout(char *bisect_rev_hex, int no_checkout) { int res; mark_expected_rev(bisect_rev_hex); argv_checkout[2] = bisect_rev_hex; - res = run_command_v_opt(argv_checkout, RUN_GIT_CMD); - if (res) - exit(res); + if (no_checkout) { + argv_update_ref[3] = bisect_rev_hex; + if (run_command_v_opt(argv_update_ref, RUN_GIT_CMD)) + die("update-ref --no-deref HEAD failed on %s", + bisect_rev_hex); + } else { + res = run_command_v_opt(argv_checkout, RUN_GIT_CMD); + if (res) + exit(res); + } argv_show_branch[1] = bisect_rev_hex; return run_command_v_opt(argv_show_branch, RUN_GIT_CMD);
@@ -788,7 +796,7 @@ static void handle_skipped_merge_base(const unsigned char *mb) * - If one is "skipped", we can't know but we should warn. * - If we don't know, we should check it out and ask the user to test. */ -static void check_merge_bases(void) +static void check_merge_bases(int no_checkout) { struct commit_list *result; int rev_nr;
@@ -806,7 +814,7 @@ static void check_merge_bases(void) handle_skipped_merge_base(mb); } else { printf("Bisecting: a merge base must be tested\n"); - exit(bisect_checkout(sha1_to_hex(mb))); + exit(bisect_checkout(sha1_to_hex(mb), no_checkout)); } }
@@ -849,7 +857,7 @@ static int check_ancestors(const char *prefix) * If a merge base must be tested by the user, its source code will be * checked out to be tested by the user and we will exit. */ -static void check_good_are_ancestors_of_bad(const char *prefix) +static void check_good_are_ancestors_of_bad(const char *prefix, int no_checkout) { const char *filename = git_path("BISECT_ANCESTORS_OK"); struct stat st;
@@ -868,7 +876,7 @@ static void check_good_are_ancestors_of_bad(const char *prefix) /* Check if all good revs are ancestor of the bad rev. */ if (check_ancestors(prefix)) - check_merge_bases(); + check_merge_bases(no_checkout); /* Create file BISECT_ANCESTORS_OK. */ fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0600);
@@ -908,8 +916,11 @@ static void show_diff_tree(const char *prefix, struct commit *commit) * We use the convention that exiting with an exit code 10 means that * the bisection process finished successfully. * In this case the calling shell script should exit 0. + * + * If no_checkout is non-zero, the bisection process does not + * checkout the trial commit but instead simply updates HEAD. */ -int bisect_next_all(const char *prefix) +int bisect_next_all(const char *prefix, int no_checkout) { struct rev_info revs; struct commit_list *tried;
@@ -920,7 +931,7 @@ int bisect_next_all(const char *prefix) if (read_bisect_refs()) die("reading bisect refs failed"); - check_good_are_ancestors_of_bad(prefix); + check_good_are_ancestors_of_bad(prefix, no_checkout); bisect_rev_setup(&revs, prefix, "%s", "^%s", 1); revs.limited = 1;
@@ -966,6 +977,6 @@ int bisect_next_all(const char *prefix) "(roughly %d step%s)\n", nr, (nr == 1 ? "" : "s"), steps, (steps == 1 ? "" : "s")); - return bisect_checkout(bisect_rev_hex); + return bisect_checkout(bisect_rev_hex, no_checkout); }
diff --git a/bisect.h b/bisect.h
index 0862ce5..22f2e4d 100644
--- a/bisect.h
+++ b/bisect.h@@ -27,7 +27,7 @@ struct rev_list_info { const char *header_prefix; }; -extern int bisect_next_all(const char *prefix); +extern int bisect_next_all(const char *prefix, int no_checkout); extern int estimate_bisect_steps(int all);
diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c
index 5b22639..1f072d4 100644
--- a/builtin/bisect--helper.c
+++ b/builtin/bisect--helper.c@@ -4,16 +4,20 @@ #include "bisect.h" static const char * const git_bisect_helper_usage[] = { - "git bisect--helper --next-all", + "git bisect--helper --next-all [--bisect-mode=checkout|update-ref]", NULL }; int cmd_bisect__helper(int argc, const char **argv, const char *prefix) { int next_all = 0; + int no_checkout = 0; + char *bisect_mode=NULL; struct option options[] = { OPT_BOOLEAN(0, "next-all", &next_all, "perform 'git bisect next'"), + OPT_STRING(0, "bisect-mode", &bisect_mode, "mode", + "bisection mode: 'checkout' (default) or 'update-ref'"), OPT_END() };
@@ -23,6 +27,7 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix) if (!next_all) usage_with_options(git_bisect_helper_usage, options); + no_checkout = bisect_mode && !strcmp(bisect_mode, "update-ref"); /* next-all */ - return bisect_next_all(prefix); + return bisect_next_all(prefix, no_checkout); }
--
1.7.6.353.g794b