From: Pranit Bauva <pranit.bauva@xxxxxxxxx> Reimplement the `bisect_skip()` shell function in C and also add `bisect-skip` subcommand to `git bisect--helper` to call it from git-bisect.sh Using `--bisect-skip` subcommand is a temporary measure to port shell function to C so as to use the existing test suite. As more functions are ported, this subcommand will be retired and will be called by some other method. Mentored-by: Lars Schneider <larsxschneider@xxxxxxxxx> Mentored-by: Christian Couder <chriscool@xxxxxxxxxxxxx> Mentored-by: Johannes Schindelin <Johannes.Schindelin@xxxxxx> Signed-off-by: Pranit Bauva <pranit.bauva@xxxxxxxxx> Signed-off-by: Tanushree Tumane <tanushreetumane@xxxxxxxxx> --- builtin/bisect--helper.c | 45 +++++++++++++++++++++++++++++++++++++++- git-bisect.sh | 17 +-------------- 2 files changed, 45 insertions(+), 17 deletions(-) diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c index 4eb2580ba8..0818dbf8ff 100644 --- a/builtin/bisect--helper.c +++ b/builtin/bisect--helper.c @@ -30,6 +30,7 @@ static const char * const git_bisect_helper_usage[] = { N_("git bisect--helper --bisect-state (bad|new) [<rev>]"), N_("git bisect--helper --bisect-state (good|old) [<rev>...]"), N_("git bisect--helper --bisect-replay <filename>"), + N_("git bisect--helper --bisect-skip [(<rev>|<range>)...]"), NULL }; @@ -994,6 +995,41 @@ static int bisect_replay(struct bisect_terms *terms, const char *filename) return bisect_auto_next(terms, NULL); } +static int bisect_skip(struct bisect_terms *terms, const char **argv, int argc) +{ + int i, res; + const char *pattern = "*..*"; + struct argv_array argv_state = ARGV_ARRAY_INIT; + + argv_array_push(&argv_state, "skip"); + + for (i = 0; i < argc; i++) { + if (!wildmatch(pattern, argv[i], 0)) { + struct rev_info revs; + struct commit *commit; + struct argv_array rev_argv = ARGV_ARRAY_INIT; + + argv_array_pushl(&rev_argv, "skipped_commits", argv[i], NULL); + init_revisions(&revs, NULL); + setup_revisions(rev_argv.argc, rev_argv.argv, &revs, NULL); + argv_array_clear(&rev_argv); + + if (prepare_revision_walk(&revs)) + die(_("revision walk setup failed\n")); + while ((commit = get_revision(&revs)) != NULL) + argv_array_push(&argv_state, + oid_to_hex(&commit->object.oid)); + + reset_revision_walk(); + } else { + argv_array_push(&argv_state, argv[i]); + } + } + res = bisect_state(terms, argv_state.argv, argv_state.argc); + argv_array_clear(&argv_state); + return res; +} + int cmd_bisect__helper(int argc, const char **argv, const char *prefix) { enum { @@ -1005,7 +1041,8 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix) BISECT_NEXT, BISECT_STATE, BISECT_LOG, - BISECT_REPLAY + BISECT_REPLAY, + BISECT_SKIP } cmdmode = 0; int no_checkout = 0, res = 0, nolog = 0; struct option options[] = { @@ -1027,6 +1064,8 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix) N_("output the contents of BISECT_LOG"), BISECT_LOG), OPT_CMDMODE(0, "bisect-replay", &cmdmode, N_("replay the bisection process from the given file"), BISECT_REPLAY), + OPT_CMDMODE(0, "bisect-skip", &cmdmode, + N_("skip some commits for checkout"), BISECT_SKIP), OPT_BOOL(0, "no-checkout", &no_checkout, N_("update BISECT_HEAD instead of checking out the current commit")), OPT_BOOL(0, "no-log", &nolog, @@ -1093,6 +1132,10 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix) set_terms(&terms, "bad", "good"); res = bisect_replay(&terms, argv[0]); break; + case BISECT_SKIP: + set_terms(&terms, "bad", "good"); + res = bisect_skip(&terms, argv, argc); + break; default: return error("BUG: unknown subcommand '%d'", cmdmode); } diff --git a/git-bisect.sh b/git-bisect.sh index 0555191c41..edfd3f8b3d 100755 --- a/git-bisect.sh +++ b/git-bisect.sh @@ -39,21 +39,6 @@ _x40="$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40" TERM_BAD=bad TERM_GOOD=good -bisect_skip() { - all='' - for arg in "$@" - do - case "$arg" in - *..*) - revs=$(git rev-list "$arg") || die "$(eval_gettext "Bad rev input: \$arg")" ;; - *) - revs=$(git rev-parse --sq-quote "$arg") ;; - esac - all="$all $revs" - done - eval git bisect--helper --bisect-state 'skip' $all -} - bisect_visualize() { git bisect--helper --bisect-next-check $TERM_GOOD $TERM_BAD fail || exit @@ -162,7 +147,7 @@ case "$#" in bad|good|new|old|"$TERM_BAD"|"$TERM_GOOD") git bisect--helper --bisect-state "$cmd" "$@" ;; skip) - bisect_skip "$@" ;; + git bisect--helper --bisect-skip "$@" ;; next) # Not sure we want "next" at the UI level anymore. get_terms -- gitgitgadget