On 27/10/17 16:06, Pranit Bauva wrote: > Reimplement `bisect_next_check` shell function in C and add > `bisect-next-check` subcommand to `git bisect--helper` to call it from > git-bisect.sh . > > `bisect_voc` shell function is no longer useful now and is replaced by > using a char *[] of "new|bad" and "good|old" values. > > Using `--bisect-next-check` 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 but its implementation will > be called by some other methods. > > Helped-by: Stephan Beyer <s-beyer@xxxxxxx> > Mentored-by: Lars Schneider <larsxschneider@xxxxxxxxx> > Mentored-by: Christian Couder <chriscool@xxxxxxxxxxxxx> > Signed-off-by: Pranit Bauva <pranit.bauva@xxxxxxxxx> > --- > builtin/bisect--helper.c | 91 +++++++++++++++++++++++++++++++++++++++++++++++- > git-bisect.sh | 60 +++---------------------------- > 2 files changed, 94 insertions(+), 57 deletions(-) > > diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c > index 65abf8a70c6d9..0f9c3e63821b8 100644 > --- a/builtin/bisect--helper.c > +++ b/builtin/bisect--helper.c > @@ -6,6 +6,7 @@ > #include "dir.h" > #include "argv-array.h" > #include "run-command.h" > +#include "prompt.h" > > static GIT_PATH_FUNC(git_path_bisect_terms, "BISECT_TERMS") > static GIT_PATH_FUNC(git_path_bisect_expected_rev, "BISECT_EXPECTED_REV") > @@ -21,6 +22,7 @@ static const char * const git_bisect_helper_usage[] = { > N_("git bisect--helper --bisect-reset [<commit>]"), > N_("git bisect--helper --bisect-write <state> <revision> <good_term> <bad_term> [<nolog>]"), > N_("git bisect--helper --bisect-check-and-set-terms <command> <good_term> <bad_term>"), > + N_("git bisect--helper --bisect-next-check [<term>] <good_term> <bad_term>"), > NULL > }; > > @@ -44,6 +46,11 @@ static void set_terms(struct bisect_terms *terms, const char *bad, > terms->term_bad = xstrdup(bad); > } > > +static const char *voc[] = { > + "bad|new", > + "good|old" > +}; > + In my version I had this instead: +static const char *vocab_bad = "bad|new"; +static const char *vocab_good = "good|old"; + which I prefer, because ... > /* > * Check whether the string `term` belongs to the set of strings > * included in the variable arguments. > @@ -264,6 +271,79 @@ static int check_and_set_terms(struct bisect_terms *terms, const char *cmd) > return 0; > } > > +static int mark_good(const char *refname, const struct object_id *oid, > + int flag, void *cb_data) > +{ > + int *m_good = (int *)cb_data; > + *m_good = 0; > + return 1; > +} > + > +static int bisect_next_check(const struct bisect_terms *terms, > + const char *current_term) > +{ > + int missing_good = 1, missing_bad = 1, retval = 0; > + const char *bad_ref = xstrfmt("refs/bisect/%s", terms->term_bad); > + const char *good_glob = xstrfmt("%s-*", terms->term_good); > + > + if (ref_exists(bad_ref)) > + missing_bad = 0; > + > + for_each_glob_ref_in(mark_good, good_glob, "refs/bisect/", > + (void *) &missing_good); > + > + if (!missing_good && !missing_bad) > + goto finish; > + > + if (!current_term) > + goto fail; > + > + if (missing_good && !missing_bad && current_term && > + !strcmp(current_term, terms->term_good)) { > + char *yesno; > + /* > + * have bad (or new) but not good (or old). We could bisect > + * although this is less optimum. > + */ > + fprintf(stderr, _("Warning: bisecting only with a %s commit\n"), > + terms->term_bad); > + if (!isatty(0)) > + goto finish; > + /* > + * TRANSLATORS: Make sure to include [Y] and [n] in your > + * translation. The program will only accept English input > + * at this point. > + */ > + yesno = git_prompt(_("Are you sure [Y/n]? "), PROMPT_ECHO); > + if (starts_with(yesno, "N") || starts_with(yesno, "n")) > + goto fail; > + > + goto finish; > + } > + if (!is_empty_or_missing_file(git_path_bisect_start())) { > + error(_("You need to give me at least one %s and " > + "%s revision. You can use \"git bisect %s\" " > + "and \"git bisect %s\" for that.\n"), > + voc[0], voc[1], voc[0], voc[1]); ... this is (arguably) easier to read: + vocab_bad, vocab_good, vocab_bad, vocab_good); > + goto fail; > + } else { > + error(_("You need to start by \"git bisect start\". You " > + "then need to give me at least one %s and %s " > + "revision. You can use \"git bisect %s\" and " > + "\"git bisect %s\" for that.\n"), > + voc[1], voc[0], voc[1], voc[0]); ditto ATB, Ramsay Jones