Hi, On Mon, 20 Jan 2020, Miriam Rubio wrote: > 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 <negative-value>`. Follow POSIX conventions to return > <negative-value> to indicate error. > > Turn `exit()` to `return` calls in `check_good_are_ancestors_of_bad()`. > > Code that turns -11(early success code) to 0 from > `check_good_are_ancestors_of_bad()` has been moved to > `cmd_bisect__helper()`. > > Handle the return value in dependent function `bisect_next_all()`. > > 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> > Signed-off-by: Miriam Rubio <mirucam@xxxxxxxxx> > --- > bisect.c | 42 ++++++++++++++++++++++++++-------------- > builtin/bisect--helper.c | 12 ++++++++++-- > 2 files changed, 37 insertions(+), 17 deletions(-) > > diff --git a/bisect.c b/bisect.c > index 367258b0dd..2b80597a1d 100644 > --- a/bisect.c > +++ b/bisect.c > @@ -865,9 +865,10 @@ 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 int check_good_are_ancestors_of_bad(struct repository *r, > const char *prefix, > int no_checkout) > { > @@ -876,8 +877,15 @@ static void check_good_are_ancestors_of_bad(struct repository *r, > 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; > + } Why not just return here? Ah, there is a `filename` that was allocated... it is too bad that we have a mailing-list based review, as the hunk context simply cannot be extended in a mail. Personally, I think it would be nicer to split the definition of `filename` from its declaration and move it _after_ this conditional code, so that we can `return` right away. However, there is a more pressing issue than that: `die()` exits with exit code 128, so in keeping with the idea to hand down negative exit codes as return values, should we not assign `res = -128` here? > > /* Check if file BISECT_ANCESTORS_OK exists. */ > if (!stat(filename, &st) && S_ISREG(st.st_mode)) > @@ -893,18 +901,20 @@ 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 == -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) > + { We usually put the `{` on the same line as the `if` condition (like you did in the `if (!current_bad_oid)` line above. The rest looks reasonable. Thank you, Johannes > + /* 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; > } > > /* > @@ -975,7 +985,9 @@ int bisect_next_all(struct repository *r, const char *prefix, int no_checkout) > 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; > diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c > index 826fcba2ed..5e0f759d50 100644 > --- a/builtin/bisect--helper.c > +++ b/builtin/bisect--helper.c > @@ -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,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; > } > -- > 2.21.1 (Apple Git-122.3) > >