diff mbox series

[v2,11/11] bisect: libify `bisect_next_all`

Message ID 20200128144026.53128-12-mirucam@gmail.com (mailing list archive)
State New, archived
Headers show
Series Finish converting git bisect to C part 1 | expand

Commit Message

Miriam R. Jan. 28, 2020, 2:40 p.m. UTC
From: Pranit Bauva <pranit.bauva@gmail.com>

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.

All the functions calling `bisect_next_all()` are already able to
handle return values from it.

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>
---
 bisect.c | 40 +++++++++++++++++++++++++++++-----------
 bisect.h | 23 +++++++++++++++++++++++
 2 files changed, 52 insertions(+), 11 deletions(-)
diff mbox series

Patch

diff --git a/bisect.c b/bisect.c
index 43baa3df28..d4b883f67d 100644
--- a/bisect.c
+++ b/bisect.c
@@ -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;
diff --git a/bisect.h b/bisect.h
index 4e69a11ea8..f640c4f963 100644
--- a/bisect.h
+++ b/bisect.h
@@ -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);