bisect: introduce first-parent flag

Upon seeing a merge commit when bisecting, this option may be used to
follow only the first parent.

In detecting regressions introduced through the merging of a branch, the
merge commit will be identified as introduction of the bug and its
ancestors will be ignored.

This option is particularly useful in avoiding false positives when a
merged branch contained broken or non-buildable commits, but the merge
itself was OK.

Signed-off-by: Aaron Lipman <alipman88@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Aaron Lipman
2020-08-07 17:58:37 -04:00
committed by Junio C Hamano
parent be5fe2000d
commit e8861ffc20
4 changed files with 42 additions and 3 deletions

View File

@ -17,6 +17,7 @@ static GIT_PATH_FUNC(git_path_bisect_head, "BISECT_HEAD")
static GIT_PATH_FUNC(git_path_bisect_log, "BISECT_LOG")
static GIT_PATH_FUNC(git_path_head_name, "head-name")
static GIT_PATH_FUNC(git_path_bisect_names, "BISECT_NAMES")
static GIT_PATH_FUNC(git_path_bisect_first_parent, "BISECT_FIRST_PARENT")
static const char * const git_bisect_helper_usage[] = {
N_("git bisect--helper --next-all"),
@ -28,7 +29,7 @@ static const char * const git_bisect_helper_usage[] = {
N_("git bisect--helper --bisect-next-check <good_term> <bad_term> [<term>]"),
N_("git bisect--helper --bisect-terms [--term-good | --term-old | --term-bad | --term-new]"),
N_("git bisect--helper --bisect-start [--term-{old,good}=<term> --term-{new,bad}=<term>]"
"[--no-checkout] [<bad> [<good>...]] [--] [<paths>...]"),
" [--no-checkout] [--first-parent] [<bad> [<good>...]] [--] [<paths>...]"),
NULL
};
@ -424,6 +425,7 @@ finish:
static int bisect_start(struct bisect_terms *terms, const char **argv, int argc)
{
int no_checkout = 0;
int first_parent_only = 0;
int i, has_double_dash = 0, must_write_terms = 0, bad_seen = 0;
int flags, pathspec_pos, res = 0;
struct string_list revs = STRING_LIST_INIT_DUP;
@ -453,6 +455,8 @@ static int bisect_start(struct bisect_terms *terms, const char **argv, int argc)
break;
} else if (!strcmp(arg, "--no-checkout")) {
no_checkout = 1;
} else if (!strcmp(arg, "--first-parent")) {
first_parent_only = 1;
} else if (!strcmp(arg, "--term-good") ||
!strcmp(arg, "--term-old")) {
i++;
@ -577,6 +581,9 @@ static int bisect_start(struct bisect_terms *terms, const char **argv, int argc)
*/
write_file(git_path_bisect_start(), "%s\n", start_head.buf);
if (first_parent_only)
write_file(git_path_bisect_first_parent(), "\n");
if (no_checkout) {
if (get_oid(start_head.buf, &oid) < 0) {
res = error(_("invalid ref: '%s'"), start_head.buf);