]> git.ipfire.org Git - thirdparty/git.git/commitdiff
bisect: libify `check_good_are_ancestors_of_bad` and its dependents
authorPranit Bauva <pranit.bauva@gmail.com>
Mon, 17 Feb 2020 08:40:37 +0000 (09:40 +0100)
committerJunio C Hamano <gitster@pobox.com>
Wed, 19 Feb 2020 17:37:14 +0000 (09:37 -0800)
Since we want to get rid of git-bisect.sh, it would be necessary to
convert those exit() calls to return statements so that errors can be
reported.

Emulate try catch in C by converting `exit(<positive-value>)` to
`return <negative-value>`. Follow POSIX conventions to return
<negative-value> to indicate error.

Code that turns BISECT_INTERNAL_SUCCESS_MERGE_BASE (-11)
 to BISECT_OK (0) from `check_good_are_ancestors_of_bad()` has been moved to
`cmd_bisect__helper()`.

Update all callers to handle the error returns.

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: Miriam Rubio <mirucam@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
bisect.c
builtin/bisect--helper.c

index 382e0b471f00967a1994989fa9a6ec61d0cc1628..f5ce3a4b70d536f4d3cc0ab93c914a7172f03787 100644 (file)
--- a/bisect.c
+++ b/bisect.c
@@ -872,20 +872,23 @@ static int check_ancestors(struct repository *r, int rev_nr,
  *
  * If that's not the case, we need to check the merge bases.
  * If a merge base must be tested by the user, its source code will be
- * checked out to be tested by the user and we will exit.
+ * checked out to be tested by the user and we will return.
  */
-static void check_good_are_ancestors_of_bad(struct repository *r,
+
+static enum bisect_error check_good_are_ancestors_of_bad(struct repository *r,
                                            const char *prefix,
                                            int no_checkout)
 {
-       char *filename = git_pathdup("BISECT_ANCESTORS_OK");
+       char *filename;
        struct stat st;
        int fd, rev_nr;
        enum bisect_error res = BISECT_OK;
        struct commit **rev;
 
        if (!current_bad_oid)
-               die(_("a %s revision is needed"), term_bad);
+               return error(_("a %s revision is needed"), term_bad);
+
+       filename = git_pathdup("BISECT_ANCESTORS_OK");
 
        /* Check if file BISECT_ANCESTORS_OK exists. */
        if (!stat(filename, &st) && S_ISREG(st.st_mode))
@@ -901,18 +904,26 @@ static void check_good_are_ancestors_of_bad(struct repository *r,
        if (check_ancestors(r, rev_nr, rev, prefix))
                res = check_merge_bases(rev_nr, rev, no_checkout);
        free(rev);
-       if (res)
-               exit(res == BISECT_INTERNAL_SUCCESS_MERGE_BASE ? BISECT_OK : -res);
 
-       /* Create file BISECT_ANCESTORS_OK. */
-       fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0600);
-       if (fd < 0)
-               warning_errno(_("could not create file '%s'"),
-                             filename);
-       else
-               close(fd);
+       if (!res) {
+               /* Create file BISECT_ANCESTORS_OK. */
+               fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0600);
+               if (fd < 0)
+                       /*
+                        * BISECT_ANCESTORS_OK file is not absolutely necessary,
+                        * the bisection process will continue at the next
+                        * bisection step.
+                        * So, just signal with a warning that something
+                        * might be wrong.
+                        */
+                       warning_errno(_("could not create file '%s'"),
+                               filename);
+               else
+                       close(fd);
+       }
  done:
        free(filename);
+       return res;
 }
 
 /*
@@ -984,7 +995,9 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix, int
        if (read_bisect_refs())
                die(_("reading bisect refs failed"));
 
-       check_good_are_ancestors_of_bad(r, prefix, no_checkout);
+       res = check_good_are_ancestors_of_bad(r, prefix, no_checkout);
+       if (res)
+               return res;
 
        bisect_rev_setup(r, &revs, prefix, "%s", "^%s", 1);
        revs.limited = 1;
index e6bd4d6645a1d5263dbaec38f2d52ab4b74985fc..c1c40b516df7816b2cc0ce5cb20ee8beb7e9e000 100644 (file)
@@ -666,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"));
@@ -713,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);
+
+       /*
+        * 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);
 }