bisect--helper: `get_terms` & `bisect_terms` shell function in C

Reimplement the `get_terms` and `bisect_terms` shell function in C and add `bisect-terms` subcommand to `git bisect--helper` to call it from git-bisect.sh . Using `--bisect-terms` subcommand is a temporary measure to port shell function in 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. Also use error() to report "no terms defined" and accordingly change the test in t6030. We need to use PARSE_OPT_KEEP_UNKNOWN here to allow for parameters that look like options (e.g --term-good) but should not be parsed by cmd_bisect__helper(). This change is safe because all other cmdmodes have strict argc checks already. Mentored-by: Lars Schneider <larsxschneider@gmail.com> Mentored-by: Christian Couder <chriscool@tuxfamily.org> Mentored-by: Johannes Schindelin <Johannes.Schindelin@gmx.de> Signed-off-by: Pranit Bauva <pranit.bauva@gmail.com> Signed-off-by: Tanushree Tumane <tanushreetumane@gmail.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>

Pranit Bauva committed Jan 2, 2019 at 07:38 UTC 450ebb7359ec379a282670e85536540734c45eed
3 files changed +63 -36
builtin/bisect--helper.c
+60 -2
@@ -23,6 +23,7 @@ static const char * const git_bisect_helper_usage[] = {
23 N_("git bisect--helper --bisect-write [--no-log] <state> <revision> <good_term> <bad_term>"),
24 N_("git bisect--helper --bisect-check-and-set-terms <command> <good_term> <bad_term>"),
25 N_("git bisect--helper --bisect-next-check <good_term> <bad_term> [<term>]"),
26 + N_("git bisect--helper --bisect-terms [--term-good | --term-old | --term-bad | --term-new]"),
27 NULL
28 };
29
@@ -339,6 +340,55 @@ finish:
340 return retval;
341 }
342
343 +static int get_terms(struct bisect_terms *terms)
344 +{
345 + struct strbuf str = STRBUF_INIT;
346 + FILE *fp = NULL;
347 + int res = 0;
348 +
349 + fp = fopen(git_path_bisect_terms(), "r");
350 + if (!fp) {
351 + res = -1;
352 + goto finish;
353 + }
354 +
355 + free_terms(terms);
356 + strbuf_getline_lf(&str, fp);
357 + terms->term_bad = strbuf_detach(&str, NULL);
358 + strbuf_getline_lf(&str, fp);
359 + terms->term_good = strbuf_detach(&str, NULL);
360 +
361 +finish:
362 + if (fp)
363 + fclose(fp);
364 + strbuf_release(&str);
365 + return res;
366 +}
367 +
368 +static int bisect_terms(struct bisect_terms *terms, const char *option)
369 +{
370 + if (get_terms(terms))
371 + return error(_("no terms defined"));
372 +
373 + if (option == NULL) {
374 + printf(_("Your current terms are %s for the old state\n"
375 + "and %s for the new state.\n"),
376 + terms->term_good, terms->term_bad);
377 + return 0;
378 + }
379 + if (one_of(option, "--term-good", "--term-old", NULL))
380 + printf("%s\n", terms->term_good);
381 + else if (one_of(option, "--term-bad", "--term-new", NULL))
382 + printf("%s\n", terms->term_bad);
383 + else
384 + return error(_("invalid argument %s for 'git bisect terms'.\n"
385 + "Supported options are: "
386 + "--term-good|--term-old and "
387 + "--term-bad|--term-new."), option);
388 +
389 + return 0;
390 +}
391 +
392 int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
393 {
394 enum {
@@ -349,7 +399,8 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
399 BISECT_RESET,
400 BISECT_WRITE,
401 CHECK_AND_SET_TERMS,
352 - BISECT_NEXT_CHECK
402 + BISECT_NEXT_CHECK,
403 + BISECT_TERMS
404 } cmdmode = 0;
405 int no_checkout = 0, res = 0, nolog = 0;
406 struct option options[] = {
@@ -369,6 +420,8 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
420 N_("check and set terms in a bisection state"), CHECK_AND_SET_TERMS),
421 OPT_CMDMODE(0, "bisect-next-check", &cmdmode,
422 N_("check whether bad or good terms exist"), BISECT_NEXT_CHECK),
423 + OPT_CMDMODE(0, "bisect-terms", &cmdmode,
424 + N_("print out the bisect terms"), BISECT_TERMS),
425 OPT_BOOL(0, "no-checkout", &no_checkout,
426 N_("update BISECT_HEAD instead of checking out the current commit")),
427 OPT_BOOL(0, "no-log", &nolog,
@@ -378,7 +431,7 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
431 struct bisect_terms terms = { .term_good = NULL, .term_bad = NULL };
432
433 argc = parse_options(argc, argv, prefix, options,
381 - git_bisect_helper_usage, 0);
434 + git_bisect_helper_usage, PARSE_OPT_KEEP_UNKNOWN);
435
436 if (!cmdmode)
437 usage_with_options(git_bisect_helper_usage, options);
@@ -419,6 +472,11 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
472 set_terms(&terms, argv[1], argv[0]);
473 res = bisect_next_check(&terms, argc == 3 ? argv[2] : NULL);
474 break;
475 + case BISECT_TERMS:
476 + if (argc > 1)
477 + return error(_("--bisect-terms requires 0 or 1 argument"));
478 + res = bisect_terms(&terms, argc == 1 ? argv[0] : NULL);
479 + break;
480 default:
481 return error("BUG: unknown subcommand '%d'", cmdmode);
482 }
git-bisect.sh
+2 -33
@@ -355,7 +355,7 @@ bisect_replay () {
355 "$TERM_GOOD"|"$TERM_BAD"|skip)
356 git bisect--helper --bisect-write "$command" "$rev" "$TERM_GOOD" "$TERM_BAD" || exit;;
357 terms)
358 - bisect_terms $rev ;;
358 + git bisect--helper --bisect-terms $rev || exit;;
359 *)
360 die "$(gettext "?? what are you talking about?")" ;;
361 esac
@@ -439,37 +439,6 @@ get_terms () {
439 fi
440 }
441
442 -bisect_terms () {
443 - get_terms
444 - if ! test -s "$GIT_DIR/BISECT_TERMS"
445 - then
446 - die "$(gettext "no terms defined")"
447 - fi
448 - case "$#" in
449 - 0)
450 - gettextln "Your current terms are $TERM_GOOD for the old state
451 -and $TERM_BAD for the new state."
452 - ;;
453 - 1)
454 - arg=$1
455 - case "$arg" in
456 - --term-good|--term-old)
457 - printf '%s\n' "$TERM_GOOD"
458 - ;;
459 - --term-bad|--term-new)
460 - printf '%s\n' "$TERM_BAD"
461 - ;;
462 - *)
463 - die "$(eval_gettext "invalid argument \$arg for 'git bisect terms'.
464 -Supported options are: --term-good|--term-old and --term-bad|--term-new.")"
465 - ;;
466 - esac
467 - ;;
468 - *)
469 - usage ;;
470 - esac
471 -}
472 -
442 case "$#" in
443 0)
444 usage ;;
@@ -500,7 +469,7 @@ case "$#" in
469 run)
470 bisect_run "$@" ;;
471 terms)
503 - bisect_terms "$@" ;;
472 + git bisect--helper --bisect-terms "$@" || exit;;
473 *)
474 usage ;;
475 esac
t/t6030-bisect-porcelain.sh
+1 -1
@@ -802,7 +802,7 @@ test_expect_success 'bisect terms needs 0 or 1 argument' '
802 test_must_fail git bisect terms only-one &&
803 test_must_fail git bisect terms 1 2 &&
804 test_must_fail git bisect terms 2>actual &&
805 - echo "no terms defined" >expected &&
805 + echo "error: no terms defined" >expected &&
806 test_i18ncmp expected actual
807 '
808