Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

bisect: introduce support for --update-ref=<ref> option.

If --update-ref=<ref> is specified, then the bisection process uses:

	git update-ref --no-deref <ref> <trial>

at each trial instead of:

	git checkout <trial>

Improved-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Jon Seymour <jon.seymour@gmail.com>
  • Loading branch information...
commit 3ac5d929c5d1afb59254bfa035866c5df7128f65 1 parent 5682883
@jonseymour authored
Showing with 29 additions and 14 deletions.
  1. +23 −11 bisect.c
  2. +1 −1  bisect.h
  3. +5 −2 builtin/bisect--helper.c
View
34 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", NULL, 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, const char *cursor_ref)
{
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 (!cursor_ref) {
+ res = run_command_v_opt(argv_checkout, RUN_GIT_CMD);
+ if (res)
+ exit(res);
+ } else {
+ argv_update_ref[2] = cursor_ref;
+ argv_update_ref[3] = bisect_rev_hex;
+ if (run_command_v_opt(argv_update_ref, RUN_GIT_CMD))
+ die("update-ref --no-deref %s failed on %s", cursor_ref, bisect_rev_hex);
+ }
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(const char *cursor_ref)
{
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), cursor_ref));
}
}
@@ -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, const char *cursor_ref)
{
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(cursor_ref);
/* Create file BISECT_ANCESTORS_OK. */
fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0600);
@@ -908,8 +916,12 @@ 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 cursor_ref_param is not null, the bisection process does not
+ * checkout the trial commit but instead simply updates the specified
+ * cursor reference.
*/
-int bisect_next_all(const char *prefix)
+int bisect_next_all(const char *prefix, const char *cursor_ref)
{
struct rev_info revs;
struct commit_list *tried;
@@ -920,7 +932,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, cursor_ref);
bisect_rev_setup(&revs, prefix, "%s", "^%s", 1);
revs.limited = 1;
@@ -966,6 +978,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, cursor_ref);
}
View
2  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, const char *no_checkout);

Please use "cursor_ref" instead of "no_checkout" here too. Or better use "update_ref" everywhere as I suggest below.

@jonseymour Owner

Changed to update_ref everywhere per your suggestions. See v6.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
extern int estimate_bisect_steps(int all);
View
7 builtin/bisect--helper.c
@@ -4,16 +4,19 @@
#include "bisect.h"
static const char * const git_bisect_helper_usage[] = {
- "git bisect--helper --next-all",
+ "git bisect--helper --next-all [--update-ref=<ref>]",
NULL
};
int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
{
int next_all = 0;
+ char * update_ref = NULL;

Style: no space between "*" and "update_ref" please.

@jonseymour Owner

Thanks. Fixed in v6.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
struct option options[] = {
OPT_BOOLEAN(0, "next-all", &next_all,
"perform 'git bisect next'"),
+ OPT_STRING(0, "update-ref", &update_ref, "ref",
+ "update the reference specified by <ref>"),
OPT_END()
};
@@ -24,5 +27,5 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
usage_with_options(git_bisect_helper_usage, options);
/* next-all */
- return bisect_next_all(prefix);
+ return bisect_next_all(prefix, update_ref);

I like "update_ref" better than "cursor_ref" and I think it would be better if the same name was used everywhere. So I think it would be better if you used "update_ref" instead of "cursor_ref" (and "no_checkout") everywhere.

@jonseymour Owner

Changed to update_ref in v6.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
}
Please sign in to comment.
Something went wrong with that request. Please try again.