Skip to content

Commit fee92fc

Browse files
jonseymourgitster
authored andcommitted
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 <[email protected]> Signed-off-by: Jon Seymour <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent d3dfeed commit fee92fc

File tree

3 files changed

+28
-14
lines changed

3 files changed

+28
-14
lines changed

bisect.c

Lines changed: 22 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ struct argv_array {
2424

2525
static const char *argv_checkout[] = {"checkout", "-q", NULL, "--", NULL};
2626
static const char *argv_show_branch[] = {"show-branch", NULL, NULL};
27+
static const char *argv_update_ref[] = {"update-ref", "--no-deref", "BISECT_HEAD", NULL, NULL};
2728

2829
/* bits #0-15 in revision.h */
2930

@@ -707,16 +708,23 @@ static void mark_expected_rev(char *bisect_rev_hex)
707708
die("closing file %s: %s", filename, strerror(errno));
708709
}
709710

710-
static int bisect_checkout(char *bisect_rev_hex)
711+
static int bisect_checkout(char *bisect_rev_hex, int no_checkout)
711712
{
712713
int res;
713714

714715
mark_expected_rev(bisect_rev_hex);
715716

716717
argv_checkout[2] = bisect_rev_hex;
717-
res = run_command_v_opt(argv_checkout, RUN_GIT_CMD);
718-
if (res)
719-
exit(res);
718+
if (no_checkout) {
719+
argv_update_ref[3] = bisect_rev_hex;
720+
if (run_command_v_opt(argv_update_ref, RUN_GIT_CMD))
721+
die("update-ref --no-deref HEAD failed on %s",
722+
bisect_rev_hex);
723+
} else {
724+
res = run_command_v_opt(argv_checkout, RUN_GIT_CMD);
725+
if (res)
726+
exit(res);
727+
}
720728

721729
argv_show_branch[1] = bisect_rev_hex;
722730
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)
788796
* - If one is "skipped", we can't know but we should warn.
789797
* - If we don't know, we should check it out and ask the user to test.
790798
*/
791-
static void check_merge_bases(void)
799+
static void check_merge_bases(int no_checkout)
792800
{
793801
struct commit_list *result;
794802
int rev_nr;
@@ -806,7 +814,7 @@ static void check_merge_bases(void)
806814
handle_skipped_merge_base(mb);
807815
} else {
808816
printf("Bisecting: a merge base must be tested\n");
809-
exit(bisect_checkout(sha1_to_hex(mb)));
817+
exit(bisect_checkout(sha1_to_hex(mb), no_checkout));
810818
}
811819
}
812820

@@ -849,7 +857,7 @@ static int check_ancestors(const char *prefix)
849857
* If a merge base must be tested by the user, its source code will be
850858
* checked out to be tested by the user and we will exit.
851859
*/
852-
static void check_good_are_ancestors_of_bad(const char *prefix)
860+
static void check_good_are_ancestors_of_bad(const char *prefix, int no_checkout)
853861
{
854862
const char *filename = git_path("BISECT_ANCESTORS_OK");
855863
struct stat st;
@@ -868,7 +876,7 @@ static void check_good_are_ancestors_of_bad(const char *prefix)
868876

869877
/* Check if all good revs are ancestor of the bad rev. */
870878
if (check_ancestors(prefix))
871-
check_merge_bases();
879+
check_merge_bases(no_checkout);
872880

873881
/* Create file BISECT_ANCESTORS_OK. */
874882
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)
908916
* We use the convention that exiting with an exit code 10 means that
909917
* the bisection process finished successfully.
910918
* In this case the calling shell script should exit 0.
919+
*
920+
* If no_checkout is non-zero, the bisection process does not
921+
* checkout the trial commit but instead simply updates BISECT_HEAD.
911922
*/
912-
int bisect_next_all(const char *prefix)
923+
int bisect_next_all(const char *prefix, int no_checkout)
913924
{
914925
struct rev_info revs;
915926
struct commit_list *tried;
@@ -920,7 +931,7 @@ int bisect_next_all(const char *prefix)
920931
if (read_bisect_refs())
921932
die("reading bisect refs failed");
922933

923-
check_good_are_ancestors_of_bad(prefix);
934+
check_good_are_ancestors_of_bad(prefix, no_checkout);
924935

925936
bisect_rev_setup(&revs, prefix, "%s", "^%s", 1);
926937
revs.limited = 1;
@@ -966,6 +977,6 @@ int bisect_next_all(const char *prefix)
966977
"(roughly %d step%s)\n", nr, (nr == 1 ? "" : "s"),
967978
steps, (steps == 1 ? "" : "s"));
968979

969-
return bisect_checkout(bisect_rev_hex);
980+
return bisect_checkout(bisect_rev_hex, no_checkout);
970981
}
971982

bisect.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ struct rev_list_info {
2727
const char *header_prefix;
2828
};
2929

30-
extern int bisect_next_all(const char *prefix);
30+
extern int bisect_next_all(const char *prefix, int no_checkout);
3131

3232
extern int estimate_bisect_steps(int all);
3333

builtin/bisect--helper.c

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,19 @@
44
#include "bisect.h"
55

66
static const char * const git_bisect_helper_usage[] = {
7-
"git bisect--helper --next-all",
7+
"git bisect--helper --next-all [--no-checkout]",
88
NULL
99
};
1010

1111
int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
1212
{
1313
int next_all = 0;
14+
int no_checkout = 0;
1415
struct option options[] = {
1516
OPT_BOOLEAN(0, "next-all", &next_all,
1617
"perform 'git bisect next'"),
18+
OPT_BOOLEAN(0, "no-checkout", &no_checkout,
19+
"update BISECT_HEAD instead of checking out the current commit"),
1720
OPT_END()
1821
};
1922

@@ -24,5 +27,5 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
2427
usage_with_options(git_bisect_helper_usage, options);
2528

2629
/* next-all */
27-
return bisect_next_all(prefix);
30+
return bisect_next_all(prefix, no_checkout);
2831
}

0 commit comments

Comments
 (0)