From: Pranit Bauva <pranit.bauva@xxxxxxxxx> 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 <negetive-value>`. Follow POSIX conventions to return <negative-value> to indicate error. Turn `exit()` to `return` calls in `check_good_are_ancestors_of_bad()`. In `check_merge_bases()` there is an early success special case, so we have introduced special error code `-11` which indicates early success. This `-11` is converted back to `0` in `cmd_bisect_helper()`. Mentored-by: Christian Couder <chriscool@xxxxxxxxxxxxx> Mentored by: Johannes Schindelin <Johannes.Schindelin@xxxxxx> Signed-off-by: Pranit Bauva <pranit.bauva@xxxxxxxxx> Signed-off-by: Tanushree Tumane <tanushreetumane@xxxxxxxxx> --- bisect.c | 41 +++++++++++++++++++++++++--------------- builtin/bisect--helper.c | 12 ++++++++++-- 2 files changed, 36 insertions(+), 17 deletions(-) diff --git a/bisect.c b/bisect.c index 1134854fe2..87db1cc4be 100644 --- a/bisect.c +++ b/bisect.c @@ -859,17 +859,24 @@ static int check_ancestors(int rev_nr, struct commit **rev, const char *prefix) * * 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(const char *prefix, int no_checkout) +static int check_good_are_ancestors_of_bad(const char *prefix, int no_checkout) { char *filename = git_pathdup("BISECT_ANCESTORS_OK"); struct stat st; int fd, rev_nr, res = 0; struct commit **rev; - if (!current_bad_oid) - die(_("a %s revision is needed"), term_bad); + /* + * We don't want to clean the bisection state + * as we need to get back to where we started + * by using `git bisect reset`. + */ + if (!current_bad_oid) { + res = error(_("a %s revision is needed"), term_bad); + goto done; + } /* Check if file BISECT_ANCESTORS_OK exists. */ if (!stat(filename, &st) && S_ISREG(st.st_mode)) @@ -884,18 +891,20 @@ static void check_good_are_ancestors_of_bad(const char *prefix, int no_checkout) if (check_ancestors(rev_nr, rev, prefix)) res = check_merge_bases(rev_nr, rev, no_checkout); free(rev); - if(res) - exit(res == -11 ? 0 : -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) + warning_errno(_("could not create file '%s'"), + filename); + else + close(fd); + } done: free(filename); + return res; } /* @@ -973,7 +982,9 @@ int bisect_next_all(const char *prefix, int no_checkout) if (read_bisect_refs()) die(_("reading bisect refs failed")); - check_good_are_ancestors_of_bad(prefix, no_checkout); + res = check_good_are_ancestors_of_bad(prefix, no_checkout); + if (res) + return res; bisect_rev_setup(&revs, prefix, "%s", "^%s", 1); revs.limited = 1; diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c index f441ea85ff..ffb5dbe4b3 100644 --- a/builtin/bisect--helper.c +++ b/builtin/bisect--helper.c @@ -663,7 +663,8 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix) switch (cmdmode) { case NEXT_ALL: - return bisect_next_all(prefix, no_checkout); + res = bisect_next_all(prefix, no_checkout); + break; case WRITE_TERMS: if (argc != 2) return error(_("--write-terms requires two arguments")); @@ -710,5 +711,12 @@ 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 == -11) + res = 0; + + return res < 0 ? -res : res; } -- gitgitgadget