Hi Miriam, On Tue, 28 Jan 2020, Miriam Rubio wrote: > @@ -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) > + { Please move the opening `{` to the same line as the `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); > + } I wonder whether this would be easier to read: if (res == -11) res = 0; else if (res) ; /* error out */ else if ((fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0600)) < 0) res = warning_errno(_("could not create file '%s'"), filename); else close(fd); Note: my code explicitly assigns `res = -1` if the file could not be created, which is technically a change in behavior, but I think it is actually a bug fix. > 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")); I see that there is still a `die()` here, and you left it alone in this patch because at this point, only the callers of `check_good_are_ancestors_of_bad()` need to be addressed. Good. At a later point, this will have to be dealt with, of course. Another thing will need to be handled, too: while I was looking at the code whether any resources need to be released (returning a negative integer does not release memory or close file handles, unlike `die()`), I stumbled across the fact that `term_bad` and `term_good` are file-local variables. They will need to be made attributes of a `struct` and will need to be released properly, i.e. the ownership will have to be clarified (is a failed `bisect_next_all()` responsible for releasing the memory it allocated via `read_bisect_terms()`, or its caller?). Just something to keep in mind. Or better: to jot down in a TODO list. > > - 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..3442bfe2cb 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; Hmm. Is this the correct place, though? Should `bisect_next_all()` not be the function that already turns `-11` into `0`? In other words, _which_ code are we supposed to skip over when `check_good_are_ancestors_of_bad()` returns `-11`? In other words, where would the `catch` of the `try`/`catch` be, if we had portable exceptions in C? > + > + return res < 0 ? -res : res; This is a change in behavior, though: previously we guaranteed that the exit code is either 0 on success or 1 upon failure. I am not quite sure that we want to change that behavior. Ciao, Dscho > } > -- > 2.21.1 (Apple Git-122.3) > >