bisect: introduce support for --no-checkout option.
If --no-checkout 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 <chriscool@tuxfamily.org> Signed-off-by: Jon Seymour <jon.seymour@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
committed by
Junio C Hamano
parent
d3dfeedf2e
commit
fee92fc1dd
27
bisect.c
27
bisect.c
@@ -24,6 +24,7 @@ struct argv_array {
|
|||||||
|
|
||||||
static const char *argv_checkout[] = {"checkout", "-q", NULL, "--", NULL};
|
static const char *argv_checkout[] = {"checkout", "-q", NULL, "--", NULL};
|
||||||
static const char *argv_show_branch[] = {"show-branch", NULL, NULL};
|
static const char *argv_show_branch[] = {"show-branch", NULL, NULL};
|
||||||
|
static const char *argv_update_ref[] = {"update-ref", "--no-deref", "BISECT_HEAD", NULL, NULL};
|
||||||
|
|
||||||
/* bits #0-15 in revision.h */
|
/* 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));
|
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;
|
int res;
|
||||||
|
|
||||||
mark_expected_rev(bisect_rev_hex);
|
mark_expected_rev(bisect_rev_hex);
|
||||||
|
|
||||||
argv_checkout[2] = bisect_rev_hex;
|
argv_checkout[2] = bisect_rev_hex;
|
||||||
|
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);
|
res = run_command_v_opt(argv_checkout, RUN_GIT_CMD);
|
||||||
if (res)
|
if (res)
|
||||||
exit(res);
|
exit(res);
|
||||||
|
}
|
||||||
|
|
||||||
argv_show_branch[1] = bisect_rev_hex;
|
argv_show_branch[1] = bisect_rev_hex;
|
||||||
return run_command_v_opt(argv_show_branch, RUN_GIT_CMD);
|
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 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.
|
* - 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;
|
struct commit_list *result;
|
||||||
int rev_nr;
|
int rev_nr;
|
||||||
@@ -806,7 +814,7 @@ static void check_merge_bases(void)
|
|||||||
handle_skipped_merge_base(mb);
|
handle_skipped_merge_base(mb);
|
||||||
} else {
|
} else {
|
||||||
printf("Bisecting: a merge base must be tested\n");
|
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
|
* 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.
|
* 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");
|
const char *filename = git_path("BISECT_ANCESTORS_OK");
|
||||||
struct stat st;
|
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. */
|
/* Check if all good revs are ancestor of the bad rev. */
|
||||||
if (check_ancestors(prefix))
|
if (check_ancestors(prefix))
|
||||||
check_merge_bases();
|
check_merge_bases(no_checkout);
|
||||||
|
|
||||||
/* Create file BISECT_ANCESTORS_OK. */
|
/* Create file BISECT_ANCESTORS_OK. */
|
||||||
fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0600);
|
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
|
* We use the convention that exiting with an exit code 10 means that
|
||||||
* the bisection process finished successfully.
|
* the bisection process finished successfully.
|
||||||
* In this case the calling shell script should exit 0.
|
* 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 BISECT_HEAD.
|
||||||
*/
|
*/
|
||||||
int bisect_next_all(const char *prefix)
|
int bisect_next_all(const char *prefix, int no_checkout)
|
||||||
{
|
{
|
||||||
struct rev_info revs;
|
struct rev_info revs;
|
||||||
struct commit_list *tried;
|
struct commit_list *tried;
|
||||||
@@ -920,7 +931,7 @@ int bisect_next_all(const char *prefix)
|
|||||||
if (read_bisect_refs())
|
if (read_bisect_refs())
|
||||||
die("reading bisect refs failed");
|
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);
|
bisect_rev_setup(&revs, prefix, "%s", "^%s", 1);
|
||||||
revs.limited = 1;
|
revs.limited = 1;
|
||||||
@@ -966,6 +977,6 @@ int bisect_next_all(const char *prefix)
|
|||||||
"(roughly %d step%s)\n", nr, (nr == 1 ? "" : "s"),
|
"(roughly %d step%s)\n", nr, (nr == 1 ? "" : "s"),
|
||||||
steps, (steps == 1 ? "" : "s"));
|
steps, (steps == 1 ? "" : "s"));
|
||||||
|
|
||||||
return bisect_checkout(bisect_rev_hex);
|
return bisect_checkout(bisect_rev_hex, no_checkout);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
bisect.h
2
bisect.h
@@ -27,7 +27,7 @@ struct rev_list_info {
|
|||||||
const char *header_prefix;
|
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);
|
extern int estimate_bisect_steps(int all);
|
||||||
|
|
||||||
|
|||||||
@@ -4,16 +4,19 @@
|
|||||||
#include "bisect.h"
|
#include "bisect.h"
|
||||||
|
|
||||||
static const char * const git_bisect_helper_usage[] = {
|
static const char * const git_bisect_helper_usage[] = {
|
||||||
"git bisect--helper --next-all",
|
"git bisect--helper --next-all [--no-checkout]",
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
|
int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
|
||||||
{
|
{
|
||||||
int next_all = 0;
|
int next_all = 0;
|
||||||
|
int no_checkout = 0;
|
||||||
struct option options[] = {
|
struct option options[] = {
|
||||||
OPT_BOOLEAN(0, "next-all", &next_all,
|
OPT_BOOLEAN(0, "next-all", &next_all,
|
||||||
"perform 'git bisect next'"),
|
"perform 'git bisect next'"),
|
||||||
|
OPT_BOOLEAN(0, "no-checkout", &no_checkout,
|
||||||
|
"update BISECT_HEAD instead of checking out the current commit"),
|
||||||
OPT_END()
|
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);
|
usage_with_options(git_bisect_helper_usage, options);
|
||||||
|
|
||||||
/* next-all */
|
/* next-all */
|
||||||
return bisect_next_all(prefix);
|
return bisect_next_all(prefix, no_checkout);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user