bisect--helper: `is_expected_rev` & `check_expected_revs` shell function in C
authorPranit Bauva <pranit.bauva@gmail.com>
Fri, 29 Sep 2017 06:49:40 +0000 (06:49 +0000)
committerJunio C Hamano <gitster@pobox.com>
Fri, 6 Oct 2017 05:12:37 +0000 (14:12 +0900)
Reimplement `is_expected_rev` & `check_expected_revs` shell function in
C and add a `--check-expected-revs` subcommand to `git bisect--helper` to
call it from git-bisect.sh .

Using `--check-expected-revs` subcommand is a temporary measure to port
shell functions to C so as to use the existing test suite. As more
functions are ported, this subcommand would be retired but its
implementation will be called by some other method.

Helped-by: Eric Sunshine <sunshine@sunshineco.com>
Mentored-by: Lars Schneider <larsxschneider@gmail.com>
Mentored-by: Christian Couder <chriscool@tuxfamily.org>
Signed-off-by: Pranit Bauva <pranit.bauva@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
builtin/bisect--helper.c
git-bisect.sh
index 0f4d4e41cf23383cfc07cae24294daad21e75600..35d2105f941c66c7c45605a48af8494b51806fcf 100644 (file)
@@ -5,6 +5,8 @@
 #include "refs.h"
 
 static GIT_PATH_FUNC(git_path_bisect_terms, "BISECT_TERMS")
+static GIT_PATH_FUNC(git_path_bisect_expected_rev, "BISECT_EXPECTED_REV")
+static GIT_PATH_FUNC(git_path_bisect_ancestors_ok, "BISECT_ANCESTORS_OK")
 
 static const char * const git_bisect_helper_usage[] = {
        N_("git bisect--helper --next-all [--no-checkout]"),
@@ -80,12 +82,37 @@ static int write_terms(const char *bad, const char *good)
        return (res < 0) ? -1 : 0;
 }
 
+static int is_expected_rev(const char *expected_hex)
+{
+       struct strbuf actual_hex = STRBUF_INIT;
+       int res = 0;
+       if (strbuf_read_file(&actual_hex, git_path_bisect_expected_rev(), 0) >= 40) {
+               strbuf_trim(&actual_hex);
+               res = !strcmp(actual_hex.buf, expected_hex);
+       }
+       strbuf_release(&actual_hex);
+       return res;
+}
+
+static void check_expected_revs(const char **revs, int rev_nr)
+{
+       int i;
+
+       for (i = 0; i < rev_nr; i++) {
+               if (!is_expected_rev(revs[i])) {
+                       unlink_or_warn(git_path_bisect_ancestors_ok());
+                       unlink_or_warn(git_path_bisect_expected_rev());
+               }
+       }
+}
+
 int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
 {
        enum {
                NEXT_ALL = 1,
                WRITE_TERMS,
-               BISECT_CLEAN_STATE
+               BISECT_CLEAN_STATE,
+               CHECK_EXPECTED_REVS
        } cmdmode = 0;
        int no_checkout = 0;
        struct option options[] = {
@@ -95,6 +122,8 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
                         N_("write the terms to .git/BISECT_TERMS"), WRITE_TERMS),
                OPT_CMDMODE(0, "bisect-clean-state", &cmdmode,
                         N_("cleanup the bisection state"), BISECT_CLEAN_STATE),
+               OPT_CMDMODE(0, "check-expected-revs", &cmdmode,
+                        N_("check for expected revs"), CHECK_EXPECTED_REVS),
                OPT_BOOL(0, "no-checkout", &no_checkout,
                         N_("update BISECT_HEAD instead of checking out the current commit")),
                OPT_END()
@@ -117,6 +146,9 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
                if (argc != 0)
                        return error(_("--bisect-clean-state requires no arguments"));
                return bisect_clean_state();
+       case CHECK_EXPECTED_REVS:
+               check_expected_revs(argv, argc);
+               return 0;
        default:
                return error("BUG: unknown subcommand '%d'", cmdmode);
        }
index 045830c3998731e7f29d5814239415f9dcf43d38..0138a8860e3779cf62210d8d54d2eada020be12f 100755 (executable)
@@ -237,22 +237,6 @@ bisect_write() {
        test -n "$nolog" || echo "git bisect $state $rev" >>"$GIT_DIR/BISECT_LOG"
 }
 
-is_expected_rev() {
-       test -f "$GIT_DIR/BISECT_EXPECTED_REV" &&
-       test "$1" = $(cat "$GIT_DIR/BISECT_EXPECTED_REV")
-}
-
-check_expected_revs() {
-       for _rev in "$@"; do
-               if ! is_expected_rev "$_rev"
-               then
-                       rm -f "$GIT_DIR/BISECT_ANCESTORS_OK"
-                       rm -f "$GIT_DIR/BISECT_EXPECTED_REV"
-                       return
-               fi
-       done
-}
-
 bisect_skip() {
        all=''
        for arg in "$@"
@@ -280,7 +264,7 @@ bisect_state() {
                rev=$(git rev-parse --verify "$bisected_head") ||
                        die "$(eval_gettext "Bad rev input: \$bisected_head")"
                bisect_write "$state" "$rev"
-               check_expected_revs "$rev" ;;
+               git bisect--helper --check-expected-revs "$rev" ;;
        2,"$TERM_BAD"|*,"$TERM_GOOD"|*,skip)
                shift
                hash_list=''
@@ -294,7 +278,7 @@ bisect_state() {
                do
                        bisect_write "$state" "$rev"
                done
-               check_expected_revs $hash_list ;;
+               git bisect--helper --check-expected-revs $hash_list ;;
        *,"$TERM_BAD")
                die "$(eval_gettext "'git bisect \$TERM_BAD' can take only one argument.")" ;;
        *)