]> git.ipfire.org Git - thirdparty/git.git/blobdiff - builtin/bisect--helper.c
pull: don't warn if pull.ff has been set
[thirdparty/git.git] / builtin / bisect--helper.c
index 1718df7f09899afb37facf3754556520d361e13c..c1c40b516df7816b2cc0ce5cb20ee8beb7e9e000 100644 (file)
@@ -52,8 +52,8 @@ static void set_terms(struct bisect_terms *terms, const char *bad,
        terms->term_bad = xstrdup(bad);
 }
 
-static const char *vocab_bad = "bad|new";
-static const char *vocab_good = "good|old";
+static const char vocab_bad[] = "bad|new";
+static const char vocab_good[] = "good|old";
 
 /*
  * Check whether the string `term` belongs to the set of strings
@@ -206,31 +206,31 @@ static int bisect_write(const char *state, const char *rev,
        struct object_id oid;
        struct commit *commit;
        FILE *fp = NULL;
-       int retval = 0;
+       int res = 0;
 
        if (!strcmp(state, terms->term_bad)) {
                strbuf_addf(&tag, "refs/bisect/%s", state);
        } else if (one_of(state, terms->term_good, "skip", NULL)) {
                strbuf_addf(&tag, "refs/bisect/%s-%s", state, rev);
        } else {
-               retval = error(_("Bad bisect_write argument: %s"), state);
+               res = error(_("Bad bisect_write argument: %s"), state);
                goto finish;
        }
 
        if (get_oid(rev, &oid)) {
-               retval = error(_("couldn't get the oid of the rev '%s'"), rev);
+               res = error(_("couldn't get the oid of the rev '%s'"), rev);
                goto finish;
        }
 
        if (update_ref(NULL, tag.buf, &oid, NULL, 0,
                       UPDATE_REFS_MSG_ON_ERR)) {
-               retval = -1;
+               res = -1;
                goto finish;
        }
 
        fp = fopen(git_path_bisect_log(), "a");
        if (!fp) {
-               retval = error_errno(_("couldn't open the file '%s'"), git_path_bisect_log());
+               res = error_errno(_("couldn't open the file '%s'"), git_path_bisect_log());
                goto finish;
        }
 
@@ -244,7 +244,7 @@ finish:
        if (fp)
                fclose(fp);
        strbuf_release(&tag);
-       return retval;
+       return res;
 }
 
 static int check_and_set_terms(struct bisect_terms *terms, const char *cmd)
@@ -291,26 +291,14 @@ static const char need_bisect_start_warning[] =
           "You then need to give me at least one %s and %s revision.\n"
           "You can use \"git bisect %s\" and \"git bisect %s\" for that.");
 
-static int bisect_next_check(const struct bisect_terms *terms,
-                            const char *current_term)
+static int decide_next(const struct bisect_terms *terms,
+                      const char *current_term, int missing_good,
+                      int missing_bad)
 {
-       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) {
-               retval = -1;
-               goto finish;
-       }
+               return 0;
+       if (!current_term)
+               return -1;
 
        if (missing_good && !missing_bad &&
            !strcmp(current_term, terms->term_good)) {
@@ -321,7 +309,7 @@ static int bisect_next_check(const struct bisect_terms *terms,
                 */
                warning(_("bisecting only with a %s commit"), terms->term_bad);
                if (!isatty(0))
-                       goto finish;
+                       return 0;
                /*
                 * TRANSLATORS: Make sure to include [Y] and [n] in your
                 * translation. The program will only accept English input
@@ -329,21 +317,35 @@ static int bisect_next_check(const struct bisect_terms *terms,
                 */
                yesno = git_prompt(_("Are you sure [Y/n]? "), PROMPT_ECHO);
                if (starts_with(yesno, "N") || starts_with(yesno, "n"))
-                       retval = -1;
-               goto finish;
-       }
-       if (!is_empty_or_missing_file(git_path_bisect_start())) {
-               retval = error(_(need_bad_and_good_revision_warning),
-                              vocab_bad, vocab_good, vocab_bad, vocab_good);
-       } else {
-               retval = error(_(need_bisect_start_warning),
-                              vocab_good, vocab_bad, vocab_good, vocab_bad);
+                       return -1;
+               return 0;
        }
 
-finish:
-       free((void *) good_glob);
-       free((void *) bad_ref);
-       return retval;
+       if (!is_empty_or_missing_file(git_path_bisect_start()))
+               return error(_(need_bad_and_good_revision_warning),
+                            vocab_bad, vocab_good, vocab_bad, vocab_good);
+       else
+               return error(_(need_bisect_start_warning),
+                            vocab_good, vocab_bad, vocab_good, vocab_bad);
+}
+
+static int bisect_next_check(const struct bisect_terms *terms,
+                            const char *current_term)
+{
+       int missing_good = 1, missing_bad = 1;
+       char *bad_ref = xstrfmt("refs/bisect/%s", terms->term_bad);
+       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);
+
+       free(good_glob);
+       free(bad_ref);
+
+       return decide_next(terms, current_term, missing_good, missing_bad);
 }
 
 static int get_terms(struct bisect_terms *terms)
@@ -397,7 +399,7 @@ static int bisect_terms(struct bisect_terms *terms, const char *option)
 
 static int bisect_append_log_quoted(const char **argv)
 {
-       int retval = 0;
+       int res = 0;
        FILE *fp = fopen(git_path_bisect_log(), "a");
        struct strbuf orig_args = STRBUF_INIT;
 
@@ -405,25 +407,25 @@ static int bisect_append_log_quoted(const char **argv)
                return -1;
 
        if (fprintf(fp, "git bisect start") < 1) {
-               retval = -1;
+               res = -1;
                goto finish;
        }
 
        sq_quote_argv(&orig_args, argv);
        if (fprintf(fp, "%s\n", orig_args.buf) < 1)
-               retval = -1;
+               res = -1;
 
 finish:
        fclose(fp);
        strbuf_release(&orig_args);
-       return retval;
+       return res;
 }
 
 static int bisect_start(struct bisect_terms *terms, int no_checkout,
                        const char **argv, int argc)
 {
        int i, has_double_dash = 0, must_write_terms = 0, bad_seen = 0;
-       int flags, pathspec_pos, retval = 0;
+       int flags, pathspec_pos, res = 0;
        struct string_list revs = STRING_LIST_INIT_DUP;
        struct string_list states = STRING_LIST_INIT_DUP;
        struct strbuf start_head = STRBUF_INIT;
@@ -524,7 +526,7 @@ static int bisect_start(struct bisect_terms *terms, int no_checkout,
                        argv_array_pushl(&argv, "checkout", start_head.buf,
                                         "--", NULL);
                        if (run_command_v_opt(argv.argv, RUN_GIT_CMD)) {
-                               retval = error(_("checking out '%s' failed."
+                               res = error(_("checking out '%s' failed."
                                                 " Try 'git bisect start "
                                                 "<valid-branch>'."),
                                               start_head.buf);
@@ -572,12 +574,12 @@ static int bisect_start(struct bisect_terms *terms, int no_checkout,
 
        if (no_checkout) {
                if (get_oid(start_head.buf, &oid) < 0) {
-                       retval = error(_("invalid ref: '%s'"), start_head.buf);
+                       res = error(_("invalid ref: '%s'"), start_head.buf);
                        goto finish;
                }
                if (update_ref(NULL, "BISECT_HEAD", &oid, NULL, 0,
                               UPDATE_REFS_MSG_ON_ERR)) {
-                       retval = -1;
+                       res = -1;
                        goto finish;
                }
        }
@@ -589,26 +591,26 @@ static int bisect_start(struct bisect_terms *terms, int no_checkout,
        for (i = 0; i < states.nr; i++)
                if (bisect_write(states.items[i].string,
                                 revs.items[i].string, terms, 1)) {
-                       retval = -1;
+                       res = -1;
                        goto finish;
                }
 
        if (must_write_terms && write_terms(terms->term_bad,
                                            terms->term_good)) {
-               retval = -1;
+               res = -1;
                goto finish;
        }
 
-       retval = bisect_append_log_quoted(argv);
-       if (retval)
-               retval = -1;
+       res = bisect_append_log_quoted(argv);
+       if (res)
+               res = -1;
 
 finish:
        string_list_clear(&revs, 0);
        string_list_clear(&states, 0);
        strbuf_release(&start_head);
        strbuf_release(&bisect_names);
-       return retval;
+       return res;
 }
 
 int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
@@ -664,7 +666,8 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
 
        switch (cmdmode) {
        case NEXT_ALL:
-               return bisect_next_all(the_repository, prefix, no_checkout);
+               res = bisect_next_all(the_repository, prefix, no_checkout);
+               break;
        case WRITE_TERMS:
                if (argc != 2)
                        return error(_("--write-terms requires two arguments"));
@@ -711,5 +714,13 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
                return error("BUG: unknown subcommand '%d'", cmdmode);
        }
        free_terms(&terms);
-       return !!res;
+
+       /*
+        * Handle early success
+        * From check_merge_bases > check_good_are_ancestors_of_bad > bisect_next_all
+        */
+       if (res == BISECT_INTERNAL_SUCCESS_MERGE_BASE)
+               res = BISECT_OK;
+
+       return abs(res);
 }