@@ -967,10 +967,10 @@ void read_bisect_terms(const char **read_bad, const char **read_good)
}
/*
- * We use the convention that exiting with an exit code 10 means that
- * the bisection process finished successfully.
- * In this case the calling shell script should exit 0.
- *
+ * We use the convention that return -10 means the bisection process
+ * finished successfully.
+ * In this case the calling function or command should not turn a -10
+ * return code into an error or a non zero exit code.
* If no_checkout is non-zero, the bisection process does not
* checkout the trial commit but instead simply updates BISECT_HEAD.
*/
@@ -1000,23 +1000,35 @@ int bisect_next_all(struct repository *r, const char *prefix, int no_checkout)
if (!revs.commits) {
/*
- * We should exit here only if the "bad"
+ * We should return error here only if the "bad"
* commit is also a "skip" commit.
*/
res = error_if_skipped_commits(tried, NULL);
if (res < 0)
- exit(-res);
+ return res;
printf(_("%s was both %s and %s\n"),
oid_to_hex(current_bad_oid),
term_good,
term_bad);
- exit(1);
+
+ /*
+ * We don't want to clean the bisection state
+ * as we need to get back to where we started
+ * by using `git bisect reset`.
+ */
+ return -1;
}
if (!all) {
fprintf(stderr, _("No testable commit found.\n"
"Maybe you started with bad path parameters?\n"));
- exit(4);
+
+ /*
+ * We don't want to clean the bisection state
+ * as we need to get back to where we started
+ * by using `git bisect reset`.
+ */
+ return -4;
}
bisect_rev = &revs.commits->item->object.oid;
@@ -1024,12 +1036,18 @@ int bisect_next_all(struct repository *r, const char *prefix, int no_checkout)
if (oideq(bisect_rev, current_bad_oid)) {
res = error_if_skipped_commits(tried, current_bad_oid);
if (res)
- exit(-res);
+ return res;
printf("%s is the first %s commit\n", oid_to_hex(bisect_rev),
term_bad);
+
show_diff_tree(r, prefix, revs.commits->item);
- /* This means the bisection process succeeded. */
- exit(10);
+ /*
+ * This means the bisection process succeeded.
+ * Using -10 so that the call chain can simply check
+ * for negative return values for early returns up
+ * until the cmd_bisect__helper() caller.
+ */
+ return -10;
}
nr = all - reaches - 1;
@@ -31,6 +31,29 @@ struct rev_list_info {
const char *header_prefix;
};
+/*
+ * bisect_next_all() could return the following codes:
+ * 0 success code (from bisect_checkout()): a new commit to test
+ * has been found (and possibly checked out too).
+ * -1 error code (from bisect_next_all()): default error code.
+ * -2 error code (from error_if_skipped_commits()): only skipped
+ * commits left to be tested.
+ * -3 error code (from handle_bad_merge_base() through
+ * check_merge_bases() and check_good_are_ancestors_of_bad()): merge
+ * base check failed.
+ * -4 error code (from bisect_next_all()): no testable commit found.
+ * -10 early success code (from bisect_next_all()): first term_bad
+ * commit found.
+ * This value is checked in builtin/bisect_helper::bisect_next().
+ * -11 early success code (from check_merge_bases() through
+ * check_good_are_ancestors_of_bad()): successfully tested
+ * merge base.
+ * Early success codes -10 and -11 should be only internal codes and
+ * converted to a 0 status code when the bisecting command exits.
+ * Different error codes might enable a bisecting script calling the
+ * bisect command that uses this function to do different things
+ * depending on the exit status of the bisect command.
+ */
int bisect_next_all(struct repository *r,
const char *prefix,
int no_checkout);