{"thread":{"id":"54384","subject":"[PATCH v10 7/7] bisect--helper: retire `--bisect-autostart` subcommand","startedAt":"2020-10-10T22:56:29Z","lastAt":"2020-10-12T10:45:43Z","messageCount":9,"participants":["Miriam Rubio","Johannes Schindelin"],"isPatch":true,"patchVersion":10,"patchTotal":7},"messages":[{"id":"407267","messageId":"20201010140743.580-8-mirucam@gmail.com","threadId":"54384","inReplyTo":"20201010140743.580-1-mirucam@gmail.com","subject":"[PATCH v10 7/7] bisect--helper: retire `--bisect-autostart` subcommand","fromName":"Miriam Rubio","fromEmail":"mirucam@gmail.com","sentAt":"2020-10-10T14:07:43Z","receivedAt":"2020-10-10T22:56:29Z","isPatch":true,"sender":{"key":"mirucam@gmail.com","avatar":"https://avatars.githubusercontent.com/u/56339109?v=4"},"body":"From: Pranit Bauva <pranit.bauva@gmail.com>\n\nThe `--bisect-autostart` subcommand is no longer used from the\ngit-bisect.sh shell script. Instead the function\n`bisect_autostart()` is directly called from the C implementation.\n\nMentored-by: Lars Schneider <larsxschneider@gmail.com>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nMentored-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\nSigned-off-by: Pranit Bauva <pranit.bauva@gmail.com>\nSigned-off-by: Tanushree Tumane <tanushreetumane@gmail.com>\nSigned-off-by: Miriam Rubio <mirucam@gmail.com>\n---\n builtin/bisect--helper.c | 9 ---------\n 1 file changed, 9 deletions(-)\n\ndiff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\nindex f90b3efdd1..ee65f97079 100644\n--- a/builtin/bisect--helper.c\n+++ b/builtin/bisect--helper.c\n@@ -29,7 +29,6 @@ static const char * const git_bisect_helper_usage[] = {\n \t\t\t\t\t    \" [--no-checkout] [--first-parent] [<bad> [<good>...]] [--] [<paths>...]\"),\n \tN_(\"git bisect--helper --bisect-next\"),\n \tN_(\"git bisect--helper --bisect-auto-next\"),\n-\tN_(\"git bisect--helper --bisect-autostart\"),\n \tN_(\"git bisect--helper --bisect-state (bad|new) [<rev>]\"),\n \tN_(\"git bisect--helper --bisect-state (good|old) [<rev>...]\"),\n \tNULL\n@@ -935,8 +934,6 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \t\t\t N_(\"find the next bisection commit\"), BISECT_NEXT),\n \t\tOPT_CMDMODE(0, \"bisect-auto-next\", &cmdmode,\n \t\t\t N_(\"verify the next bisection state then checkout the next bisection commit\"), BISECT_AUTO_NEXT),\n-\t\tOPT_CMDMODE(0, \"bisect-autostart\", &cmdmode,\n-\t\t\t N_(\"start the bisection if it has not yet been started\"), BISECT_AUTOSTART),\n \t\tOPT_CMDMODE(0, \"bisect-state\", &cmdmode,\n \t\t\t N_(\"mark the state of ref (or refs)\"), BISECT_STATE),\n \t\tOPT_BOOL(0, \"no-log\", &nolog,\n@@ -996,12 +993,6 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \t\tget_terms(&terms);\n \t\tres = bisect_auto_next(&terms, prefix);\n \t\tbreak;\n-\tcase BISECT_AUTOSTART:\n-\t\tif (argc)\n-\t\t\treturn error(_(\"--bisect-autostart does not accept arguments\"));\n-\t\tset_terms(&terms, \"bad\", \"good\");\n-\t\tres = bisect_autostart(&terms);\n-\t\tbreak;\n \tcase BISECT_STATE:\n \t\tset_terms(&terms, \"bad\", \"good\");\n \t\tget_terms(&terms);\n-- \n2.25.0\n\n"},{"id":"407268","messageId":"20201010140743.580-2-mirucam@gmail.com","threadId":"54384","inReplyTo":"20201010140743.580-1-mirucam@gmail.com","subject":"[PATCH v10 1/7] bisect--helper: finish porting `bisect_start()` to C","fromName":"Miriam Rubio","fromEmail":"mirucam@gmail.com","sentAt":"2020-10-10T14:07:37Z","receivedAt":"2020-10-10T22:56:35Z","isPatch":true,"sender":{"key":"mirucam@gmail.com","avatar":"https://avatars.githubusercontent.com/u/56339109?v=4"},"body":"From: Pranit Bauva <pranit.bauva@gmail.com>\n\nAdd the subcommand to `git bisect--helper` and call it from\ngit-bisect.sh.\n\nWith the conversion of `bisect_auto_next()` from shell to C in a\nprevious commit, `bisect_start()` can now be fully ported to C.\n\nSo let's complete the `--bisect-start` subcommand of\n`git bisect--helper` so that it fully implements `bisect_start()`,\nand let's use this subcommand in `git-bisect.sh` instead of\n`bisect_start()`.\n\nNote that the `eval` in the changed line of `git-bisect.sh` cannot be\ndropped: it is necessary because the `rev` and the `tail`\nvariables may contain multiple, quoted arguments that need to be\npassed to `bisect--helper` (without the quotes, naturally).\n\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nMentored-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\nSigned-off-by: Pranit Bauva <pranit.bauva@gmail.com>\nSigned-off-by: Tanushree Tumane <tanushreetumane@gmail.com>\nSigned-off-by: Miriam Rubio <mirucam@gmail.com>\n---\n builtin/bisect--helper.c | 41 ++++++++++++++++++++++++++--------------\n git-bisect.sh            | 26 ++-----------------------\n 2 files changed, 29 insertions(+), 38 deletions(-)\n\ndiff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\nindex 7512b880f0..8adad68268 100644\n--- a/builtin/bisect--helper.c\n+++ b/builtin/bisect--helper.c\n@@ -85,6 +85,19 @@ static int one_of(const char *term, ...)\n \treturn res;\n }\n \n+/*\n+ * return code BISECT_INTERNAL_SUCCESS_MERGE_BASE\n+ * and BISECT_INTERNAL_SUCCESS_1ST_BAD_FOUND are codes\n+ * that indicate special success.\n+ */\n+\n+static int is_bisect_success(enum bisect_error res)\n+{\n+\treturn !res ||\n+\t\tres == BISECT_INTERNAL_SUCCESS_1ST_BAD_FOUND ||\n+\t\tres == BISECT_INTERNAL_SUCCESS_MERGE_BASE;\n+}\n+\n static int write_in_file(const char *path, const char *mode, const char *format, va_list args)\n {\n \tFILE *fp = NULL;\n@@ -609,12 +622,13 @@ static enum bisect_error bisect_auto_next(struct bisect_terms *terms, const char\n \treturn bisect_next(terms, prefix);\n }\n \n-static int bisect_start(struct bisect_terms *terms, const char **argv, int argc)\n+static enum bisect_error bisect_start(struct bisect_terms *terms, const char **argv, int argc)\n {\n \tint no_checkout = 0;\n \tint first_parent_only = 0;\n \tint i, has_double_dash = 0, must_write_terms = 0, bad_seen = 0;\n-\tint flags, pathspec_pos, res = 0;\n+\tint flags, pathspec_pos;\n+\tenum bisect_error res = BISECT_OK;\n \tstruct string_list revs = STRING_LIST_INIT_DUP;\n \tstruct string_list states = STRING_LIST_INIT_DUP;\n \tstruct strbuf start_head = STRBUF_INIT;\n@@ -753,14 +767,7 @@ static int bisect_start(struct bisect_terms *terms, const char **argv, int argc)\n \t * Get rid of any old bisect state.\n \t */\n \tif (bisect_clean_state())\n-\t\treturn -1;\n-\n-\t/*\n-\t * In case of mistaken revs or checkout error, or signals received,\n-\t * \"bisect_auto_next\" below may exit or misbehave.\n-\t * We have to trap this to be able to clean up using\n-\t * \"bisect_clean_state\".\n-\t */\n+\t\treturn BISECT_FAILED;\n \n \t/*\n \t * Write new start state\n@@ -777,7 +784,7 @@ static int bisect_start(struct bisect_terms *terms, const char **argv, int argc)\n \t\t}\n \t\tif (update_ref(NULL, \"BISECT_HEAD\", &oid, NULL, 0,\n \t\t\t       UPDATE_REFS_MSG_ON_ERR)) {\n-\t\t\tres = -1;\n+\t\t\tres = BISECT_FAILED;\n \t\t\tgoto finish;\n \t\t}\n \t}\n@@ -789,25 +796,31 @@ static int bisect_start(struct bisect_terms *terms, const char **argv, int argc)\n \tfor (i = 0; i < states.nr; i++)\n \t\tif (bisect_write(states.items[i].string,\n \t\t\t\t revs.items[i].string, terms, 1)) {\n-\t\t\tres = -1;\n+\t\t\tres = BISECT_FAILED;\n \t\t\tgoto finish;\n \t\t}\n \n \tif (must_write_terms && write_terms(terms->term_bad,\n \t\t\t\t\t    terms->term_good)) {\n-\t\tres = -1;\n+\t\tres = BISECT_FAILED;\n \t\tgoto finish;\n \t}\n \n \tres = bisect_append_log_quoted(argv);\n \tif (res)\n-\t\tres = -1;\n+\t\tres = BISECT_FAILED;\n \n finish:\n \tstring_list_clear(&revs, 0);\n \tstring_list_clear(&states, 0);\n \tstrbuf_release(&start_head);\n \tstrbuf_release(&bisect_names);\n+\tif (res)\n+\t\treturn res;\n+\n+\tres = bisect_auto_next(terms, NULL);\n+\tif (!is_bisect_success(res))\n+\t\tbisect_clean_state();\n \treturn res;\n }\n \ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex ea7e684ebb..dda386bc3a 100755\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -49,27 +49,6 @@ bisect_head()\n \tfi\n }\n \n-bisect_start() {\n-\tgit bisect--helper --bisect-start $@ || exit\n-\n-\t#\n-\t# Change state.\n-\t# In case of mistaken revs or checkout error, or signals received,\n-\t# \"bisect_auto_next\" below may exit or misbehave.\n-\t# We have to trap this to be able to clean up using\n-\t# \"bisect_clean_state\".\n-\t#\n-\ttrap 'git bisect--helper --bisect-clean-state' 0\n-\ttrap 'exit 255' 1 2 3 15\n-\n-\t#\n-\t# Check if we can proceed to the next bisect state.\n-\t#\n-\tgit bisect--helper --bisect-auto-next || exit\n-\n-\ttrap '-' 0\n-}\n-\n bisect_skip() {\n \tall=''\n \tfor arg in \"$@\"\n@@ -163,8 +142,7 @@ bisect_replay () {\n \t\tget_terms\n \t\tcase \"$command\" in\n \t\tstart)\n-\t\t\tcmd=\"bisect_start $rev $tail\"\n-\t\t\teval \"$cmd\" ;;\n+\t\t\teval \"git bisect--helper --bisect-start $rev $tail\" ;;\n \t\t\"$TERM_GOOD\"|\"$TERM_BAD\"|skip)\n \t\t\tgit bisect--helper --bisect-write \"$command\" \"$rev\" \"$TERM_GOOD\" \"$TERM_BAD\" || exit;;\n \t\tterms)\n@@ -264,7 +242,7 @@ case \"$#\" in\n \thelp)\n \t\tgit bisect -h ;;\n \tstart)\n-\t\tbisect_start \"$@\" ;;\n+\t\tgit bisect--helper --bisect-start \"$@\" ;;\n \tbad|good|new|old|\"$TERM_BAD\"|\"$TERM_GOOD\")\n \t\tbisect_state \"$cmd\" \"$@\" ;;\n \tskip)\n-- \n2.25.0\n\n"},{"id":"407272","messageId":"20201010140743.580-1-mirucam@gmail.com","threadId":"54384","inReplyTo":null,"subject":"[PATCH v10 0/7]Finish converting git bisect to C part 2 subset 2","fromName":"Miriam Rubio","fromEmail":"mirucam@gmail.com","sentAt":"2020-10-10T14:07:36Z","receivedAt":"2020-10-10T22:56:42Z","isPatch":true,"sender":{"key":"mirucam@gmail.com","avatar":"https://avatars.githubusercontent.com/u/56339109?v=4"},"body":"These patches correspond to a second part of patch series \nof Outreachy project \"Finish converting `git bisect` from shell to C\" \nstarted by Pranit Bauva and Tanushree Tumane\n(https://public-inbox.org/git/pull.117.git.gitgitgadget@gmail.com) and\ncontinued by me.\n\nThis patch series version is composed by the last seven patches of part2\nset. \n\nThese patch series emails were generated from:\nhttps://gitlab.com/mirucam/git/commits/git-bisect-work-part2-v10-subset2.\n\nI would like to thank Johannes Schindelin for reviewing this patch series\nand to Christian Couder for his advice and help.\n\n\nGeneral information\n-------------------\n\n* Rebased on d4a392452e (Git 2.29-rc1, 2020-10-08) to build with latest\nchanges in bisect--helper.c file.\n\nSpecific changes\n----------------\n\n[1/7]bisect--helper: finish porting `bisect_start()` to C\n\n* Add comment in commit message related with `eval` command.\n* Remove code comment that does not apply anymore.\n\n---\n\n[4/7]bisect--helper: reimplement `bisect_state` & `bisect_head` shell\n    functions in C\n    \n* Add comment in commit message related with `eval` command.\n* Change some code to convert shell command more faithfully.\n* Add call to bisect_autostart() in bisect_state().\n* Amend error message.\n    \n---\n\n\nPranit Bauva (7):\n  bisect--helper: finish porting `bisect_start()` to C\n  bisect--helper: retire `--bisect-clean-state` subcommand\n  bisect--helper: retire `--next-all` subcommand\n  bisect--helper: reimplement `bisect_state` & `bisect_head` shell\n    functions in C\n  bisect--helper: retire `--check-expected-revs` subcommand\n  bisect--helper: retire `--write-terms` subcommand\n  bisect--helper: retire `--bisect-autostart` subcommand\n\n builtin/bisect--helper.c | 185 +++++++++++++++++++++++----------------\n git-bisect.sh            |  81 ++---------------\n 2 files changed, 115 insertions(+), 151 deletions(-)\n\n-- \n2.25.0\n\n"},{"id":"407275","messageId":"20201010140743.580-6-mirucam@gmail.com","threadId":"54384","inReplyTo":"20201010140743.580-1-mirucam@gmail.com","subject":"[PATCH v10 5/7] bisect--helper: retire `--check-expected-revs` subcommand","fromName":"Miriam Rubio","fromEmail":"mirucam@gmail.com","sentAt":"2020-10-10T14:07:41Z","receivedAt":"2020-10-10T23:10:02Z","isPatch":true,"sender":{"key":"mirucam@gmail.com","avatar":"https://avatars.githubusercontent.com/u/56339109?v=4"},"body":"From: Pranit Bauva <pranit.bauva@gmail.com>\n\nThe `--check-expected-revs` subcommand is no longer used from the\ngit-bisect.sh shell script. Functions `check_expected_revs` and\n`is_expected_revs` are also deleted.\n\nMentored-by: Lars Schneider <larsxschneider@gmail.com>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nMentored-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\nSigned-off-by: Pranit Bauva <pranit.bauva@gmail.com>\nSigned-off-by: Tanushree Tumane <tanushreetumane@gmail.com>\nSigned-off-by: Miriam Rubio <mirucam@gmail.com>\n---\n builtin/bisect--helper.c | 30 ------------------------------\n 1 file changed, 30 deletions(-)\n\ndiff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\nindex 66b5346e42..14a8f2b9df 100644\n--- a/builtin/bisect--helper.c\n+++ b/builtin/bisect--helper.c\n@@ -187,30 +187,6 @@ static int write_terms(const char *bad, const char *good)\n \treturn res;\n }\n \n-static int is_expected_rev(const char *expected_hex)\n-{\n-\tstruct strbuf actual_hex = STRBUF_INIT;\n-\tint res = 0;\n-\tif (strbuf_read_file(&actual_hex, git_path_bisect_expected_rev(), 0) >= 40) {\n-\t\tstrbuf_trim(&actual_hex);\n-\t\tres = !strcmp(actual_hex.buf, expected_hex);\n-\t}\n-\tstrbuf_release(&actual_hex);\n-\treturn res;\n-}\n-\n-static void check_expected_revs(const char **revs, int rev_nr)\n-{\n-\tint i;\n-\n-\tfor (i = 0; i < rev_nr; i++) {\n-\t\tif (!is_expected_rev(revs[i])) {\n-\t\t\tunlink_or_warn(git_path_bisect_ancestors_ok());\n-\t\t\tunlink_or_warn(git_path_bisect_expected_rev());\n-\t\t}\n-\t}\n-}\n-\n static int bisect_reset(const char *commit)\n {\n \tstruct strbuf branch = STRBUF_INIT;\n@@ -932,7 +908,6 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n {\n \tenum {\n \t\tWRITE_TERMS = 1,\n-\t\tCHECK_EXPECTED_REVS,\n \t\tBISECT_RESET,\n \t\tBISECT_WRITE,\n \t\tCHECK_AND_SET_TERMS,\n@@ -948,8 +923,6 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \tstruct option options[] = {\n \t\tOPT_CMDMODE(0, \"write-terms\", &cmdmode,\n \t\t\t N_(\"write the terms to .git/BISECT_TERMS\"), WRITE_TERMS),\n-\t\tOPT_CMDMODE(0, \"check-expected-revs\", &cmdmode,\n-\t\t\t N_(\"check for expected revs\"), CHECK_EXPECTED_REVS),\n \t\tOPT_CMDMODE(0, \"bisect-reset\", &cmdmode,\n \t\t\t N_(\"reset the bisection state\"), BISECT_RESET),\n \t\tOPT_CMDMODE(0, \"bisect-write\", &cmdmode,\n@@ -988,9 +961,6 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \t\tif (argc != 2)\n \t\t\treturn error(_(\"--write-terms requires two arguments\"));\n \t\treturn write_terms(argv[0], argv[1]);\n-\tcase CHECK_EXPECTED_REVS:\n-\t\tcheck_expected_revs(argv, argc);\n-\t\treturn 0;\n \tcase BISECT_RESET:\n \t\tif (argc > 1)\n \t\t\treturn error(_(\"--bisect-reset requires either no argument or a commit\"));\n-- \n2.25.0\n\n"},{"id":"407274","messageId":"20201010140743.580-7-mirucam@gmail.com","threadId":"54384","inReplyTo":"20201010140743.580-1-mirucam@gmail.com","subject":"[PATCH v10 6/7] bisect--helper: retire `--write-terms` subcommand","fromName":"Miriam Rubio","fromEmail":"mirucam@gmail.com","sentAt":"2020-10-10T14:07:42Z","receivedAt":"2020-10-10T23:10:13Z","isPatch":true,"sender":{"key":"mirucam@gmail.com","avatar":"https://avatars.githubusercontent.com/u/56339109?v=4"},"body":"From: Pranit Bauva <pranit.bauva@gmail.com>\n\nThe `--write-terms` subcommand is no longer used from the\ngit-bisect.sh shell script. Instead the function `write_terms()`\nis called from the C implementation of `set_terms()` and\n`bisect_start()`.\n\nMentored-by: Lars Schneider <larsxschneider@gmail.com>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nMentored-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\nSigned-off-by: Pranit Bauva <pranit.bauva@gmail.com>\nSigned-off-by: Tanushree Tumane <tanushreetumane@gmail.com>\nSigned-off-by: Miriam Rubio <mirucam@gmail.com>\n---\n builtin/bisect--helper.c | 10 +---------\n 1 file changed, 1 insertion(+), 9 deletions(-)\n\ndiff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\nindex 14a8f2b9df..f90b3efdd1 100644\n--- a/builtin/bisect--helper.c\n+++ b/builtin/bisect--helper.c\n@@ -20,7 +20,6 @@ static GIT_PATH_FUNC(git_path_bisect_names, \"BISECT_NAMES\")\n static GIT_PATH_FUNC(git_path_bisect_first_parent, \"BISECT_FIRST_PARENT\")\n \n static const char * const git_bisect_helper_usage[] = {\n-\tN_(\"git bisect--helper --write-terms <bad_term> <good_term>\"),\n \tN_(\"git bisect--helper --bisect-reset [<commit>]\"),\n \tN_(\"git bisect--helper --bisect-write [--no-log] <state> <revision> <good_term> <bad_term>\"),\n \tN_(\"git bisect--helper --bisect-check-and-set-terms <command> <good_term> <bad_term>\"),\n@@ -907,8 +906,7 @@ static enum bisect_error bisect_state(struct bisect_terms *terms, const char **a\n int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n {\n \tenum {\n-\t\tWRITE_TERMS = 1,\n-\t\tBISECT_RESET,\n+\t\tBISECT_RESET = 1,\n \t\tBISECT_WRITE,\n \t\tCHECK_AND_SET_TERMS,\n \t\tBISECT_NEXT_CHECK,\n@@ -921,8 +919,6 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \t} cmdmode = 0;\n \tint res = 0, nolog = 0;\n \tstruct option options[] = {\n-\t\tOPT_CMDMODE(0, \"write-terms\", &cmdmode,\n-\t\t\t N_(\"write the terms to .git/BISECT_TERMS\"), WRITE_TERMS),\n \t\tOPT_CMDMODE(0, \"bisect-reset\", &cmdmode,\n \t\t\t N_(\"reset the bisection state\"), BISECT_RESET),\n \t\tOPT_CMDMODE(0, \"bisect-write\", &cmdmode,\n@@ -957,10 +953,6 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \t\tusage_with_options(git_bisect_helper_usage, options);\n \n \tswitch (cmdmode) {\n-\tcase WRITE_TERMS:\n-\t\tif (argc != 2)\n-\t\t\treturn error(_(\"--write-terms requires two arguments\"));\n-\t\treturn write_terms(argv[0], argv[1]);\n \tcase BISECT_RESET:\n \t\tif (argc > 1)\n \t\t\treturn error(_(\"--bisect-reset requires either no argument or a commit\"));\n-- \n2.25.0\n\n"},{"id":"407277","messageId":"20201010140743.580-3-mirucam@gmail.com","threadId":"54384","inReplyTo":"20201010140743.580-1-mirucam@gmail.com","subject":"[PATCH v10 2/7] bisect--helper: retire `--bisect-clean-state` subcommand","fromName":"Miriam Rubio","fromEmail":"mirucam@gmail.com","sentAt":"2020-10-10T14:07:38Z","receivedAt":"2020-10-10T23:10:19Z","isPatch":true,"sender":{"key":"mirucam@gmail.com","avatar":"https://avatars.githubusercontent.com/u/56339109?v=4"},"body":"From: Pranit Bauva <pranit.bauva@gmail.com>\n\nThe `--bisect-clean-state` subcommand is no longer used from the\ngit-bisect.sh shell script. Instead the function\n`bisect_clean_state()` is directly called from the C\nimplementation.\n\nMentored-by: Lars Schneider <larsxschneider@gmail.com>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Pranit Bauva <pranit.bauva@gmail.com>\nSigned-off-by: Tanushree Tumane <tanushreetumane@gmail.com>\nSigned-off-by: Miriam Rubio <mirucam@gmail.com>\n---\n builtin/bisect--helper.c | 8 --------\n 1 file changed, 8 deletions(-)\n\ndiff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\nindex 8adad68268..fbb9046737 100644\n--- a/builtin/bisect--helper.c\n+++ b/builtin/bisect--helper.c\n@@ -22,7 +22,6 @@ static GIT_PATH_FUNC(git_path_bisect_first_parent, \"BISECT_FIRST_PARENT\")\n static const char * const git_bisect_helper_usage[] = {\n \tN_(\"git bisect--helper --next-all\"),\n \tN_(\"git bisect--helper --write-terms <bad_term> <good_term>\"),\n-\tN_(\"git bisect--helper --bisect-clean-state\"),\n \tN_(\"git bisect--helper --bisect-reset [<commit>]\"),\n \tN_(\"git bisect--helper --bisect-write [--no-log] <state> <revision> <good_term> <bad_term>\"),\n \tN_(\"git bisect--helper --bisect-check-and-set-terms <command> <good_term> <bad_term>\"),\n@@ -861,7 +860,6 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \tenum {\n \t\tNEXT_ALL = 1,\n \t\tWRITE_TERMS,\n-\t\tBISECT_CLEAN_STATE,\n \t\tCHECK_EXPECTED_REVS,\n \t\tBISECT_RESET,\n \t\tBISECT_WRITE,\n@@ -879,8 +877,6 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \t\t\t N_(\"perform 'git bisect next'\"), NEXT_ALL),\n \t\tOPT_CMDMODE(0, \"write-terms\", &cmdmode,\n \t\t\t N_(\"write the terms to .git/BISECT_TERMS\"), WRITE_TERMS),\n-\t\tOPT_CMDMODE(0, \"bisect-clean-state\", &cmdmode,\n-\t\t\t N_(\"cleanup the bisection state\"), BISECT_CLEAN_STATE),\n \t\tOPT_CMDMODE(0, \"check-expected-revs\", &cmdmode,\n \t\t\t N_(\"check for expected revs\"), CHECK_EXPECTED_REVS),\n \t\tOPT_CMDMODE(0, \"bisect-reset\", &cmdmode,\n@@ -922,10 +918,6 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \t\tif (argc != 2)\n \t\t\treturn error(_(\"--write-terms requires two arguments\"));\n \t\treturn write_terms(argv[0], argv[1]);\n-\tcase BISECT_CLEAN_STATE:\n-\t\tif (argc != 0)\n-\t\t\treturn error(_(\"--bisect-clean-state requires no arguments\"));\n-\t\treturn bisect_clean_state();\n \tcase CHECK_EXPECTED_REVS:\n \t\tcheck_expected_revs(argv, argc);\n \t\treturn 0;\n-- \n2.25.0\n\n"},{"id":"407276","messageId":"20201010140743.580-5-mirucam@gmail.com","threadId":"54384","inReplyTo":"20201010140743.580-1-mirucam@gmail.com","subject":"[PATCH v10 4/7] bisect--helper: reimplement `bisect_state` & `bisect_head` shell functions in C","fromName":"Miriam Rubio","fromEmail":"mirucam@gmail.com","sentAt":"2020-10-10T14:07:40Z","receivedAt":"2020-10-10T23:10:21Z","isPatch":true,"sender":{"key":"mirucam@gmail.com","avatar":"https://avatars.githubusercontent.com/u/56339109?v=4"},"body":"From: Pranit Bauva <pranit.bauva@gmail.com>\n\nReimplement the `bisect_state()` shell functions in C and also add a\nsubcommand `--bisect-state` to `git-bisect--helper` to call them from\ngit-bisect.sh .\n\nUsing `--bisect-state` subcommand is a temporary measure to port shell\nfunction to C so as to use the existing test suite. As more functions\nare ported, this subcommand will be retired and will be called by some\nother methods.\n\n`bisect_head()` is only called from `bisect_state()`, thus it is not\nrequired to introduce another subcommand.\n\nNote that the `eval` in the changed line of `git-bisect.sh` cannot be\ndropped: it is necessary because the `rev` and the `tail`\nvariables may contain multiple, quoted arguments that need to be\npassed to `bisect--helper` (without the quotes, naturally).\n\nMentored-by: Lars Schneider <larsxschneider@gmail.com>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nMentored-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\nSigned-off-by: Pranit Bauva <pranit.bauva@gmail.com>\nSigned-off-by: Tanushree Tumane <tanushreetumane@gmail.com>\nSigned-off-by: Miriam Rubio <mirucam@gmail.com>\n---\n builtin/bisect--helper.c | 84 +++++++++++++++++++++++++++++++++++++++-\n git-bisect.sh            | 55 ++------------------------\n 2 files changed, 87 insertions(+), 52 deletions(-)\n\ndiff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\nindex f1a7cfbfaf..66b5346e42 100644\n--- a/builtin/bisect--helper.c\n+++ b/builtin/bisect--helper.c\n@@ -31,6 +31,8 @@ static const char * const git_bisect_helper_usage[] = {\n \tN_(\"git bisect--helper --bisect-next\"),\n \tN_(\"git bisect--helper --bisect-auto-next\"),\n \tN_(\"git bisect--helper --bisect-autostart\"),\n+\tN_(\"git bisect--helper --bisect-state (bad|new) [<rev>]\"),\n+\tN_(\"git bisect--helper --bisect-state (good|old) [<rev>...]\"),\n \tNULL\n };\n \n@@ -854,6 +856,78 @@ static int bisect_autostart(struct bisect_terms *terms)\n \treturn res;\n }\n \n+static enum bisect_error bisect_state(struct bisect_terms *terms, const char **argv,\n+\t\t\t\t      int argc)\n+{\n+\tconst char *state;\n+\tint i, verify_expected = 1;\n+\tstruct object_id oid, expected;\n+\tstruct strbuf buf = STRBUF_INIT;\n+\tstruct oid_array revs = OID_ARRAY_INIT;\n+\n+\tif (!argc)\n+\t\treturn error(_(\"Please call `--bisect-state` with at least one argument\"));\n+\n+\tif (bisect_autostart(terms))\n+\t\treturn BISECT_FAILED;\n+\n+\tstate = argv[0];\n+\tif (check_and_set_terms(terms, state) ||\n+\t    !one_of(state, terms->term_good, terms->term_bad, \"skip\", NULL))\n+\t\treturn BISECT_FAILED;\n+\n+\targv++;\n+\targc--;\n+\tif (argc > 1 && !strcmp(state, terms->term_bad))\n+\t\treturn error(_(\"'git bisect %s' can take only one argument.\"), terms->term_bad);\n+\n+\tif (argc == 0) {\n+\t\tconst char *head = \"BISECT_HEAD\";\n+\t\tenum get_oid_result res_head = get_oid(head, &oid);\n+\n+\t\tif (res_head == MISSING_OBJECT) {\n+\t\t\thead = \"HEAD\";\n+\t\t\tres_head = get_oid(head, &oid);\n+\t\t}\n+\n+\t\tif (res_head)\n+\t\t\terror(_(\"Bad rev input: %s\"), head);\n+\t\toid_array_append(&revs, &oid);\n+\t}\n+\n+\t/*\n+\t * All input revs must be checked before executing bisect_write()\n+\t * to discard junk revs.\n+\t */\n+\n+\tfor (; argc; argc--, argv++) {\n+\t\tif (get_oid(*argv, &oid)){\n+\t\t\terror(_(\"Bad rev input: %s\"), *argv);\n+\t\t\treturn BISECT_FAILED;\n+\t\t}\n+\t\toid_array_append(&revs, &oid);\n+\t}\n+\n+\tif (strbuf_read_file(&buf, git_path_bisect_expected_rev(), 0) < the_hash_algo->hexsz ||\n+\t    get_oid_hex(buf.buf, &expected) < 0)\n+\t\tverify_expected = 0; /* Ignore invalid file contents */\n+\tstrbuf_release(&buf);\n+\n+\tfor (i = 0; i < revs.nr; i++) {\n+\t\tif (bisect_write(state, oid_to_hex(&revs.oid[i]), terms, 0))\n+\t\t\treturn BISECT_FAILED;\n+\n+\t\tif (verify_expected && !oideq(&revs.oid[i], &expected)) {\n+\t\t\tunlink_or_warn(git_path_bisect_ancestors_ok());\n+\t\t\tunlink_or_warn(git_path_bisect_expected_rev());\n+\t\t\tverify_expected = 0;\n+\t\t}\n+\t}\n+\n+\toid_array_clear(&revs);\n+\treturn bisect_auto_next(terms, NULL);\n+}\n+\n int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n {\n \tenum {\n@@ -867,7 +941,8 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \t\tBISECT_START,\n \t\tBISECT_AUTOSTART,\n \t\tBISECT_NEXT,\n-\t\tBISECT_AUTO_NEXT\n+\t\tBISECT_AUTO_NEXT,\n+\t\tBISECT_STATE\n \t} cmdmode = 0;\n \tint res = 0, nolog = 0;\n \tstruct option options[] = {\n@@ -893,6 +968,8 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \t\t\t N_(\"verify the next bisection state then checkout the next bisection commit\"), BISECT_AUTO_NEXT),\n \t\tOPT_CMDMODE(0, \"bisect-autostart\", &cmdmode,\n \t\t\t N_(\"start the bisection if it has not yet been started\"), BISECT_AUTOSTART),\n+\t\tOPT_CMDMODE(0, \"bisect-state\", &cmdmode,\n+\t\t\t N_(\"mark the state of ref (or refs)\"), BISECT_STATE),\n \t\tOPT_BOOL(0, \"no-log\", &nolog,\n \t\t\t N_(\"no log for BISECT_WRITE\")),\n \t\tOPT_END()\n@@ -963,6 +1040,11 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \t\tset_terms(&terms, \"bad\", \"good\");\n \t\tres = bisect_autostart(&terms);\n \t\tbreak;\n+\tcase BISECT_STATE:\n+\t\tset_terms(&terms, \"bad\", \"good\");\n+\t\tget_terms(&terms);\n+\t\tres = bisect_state(&terms, argv, argc);\n+\t\tbreak;\n \tdefault:\n \t\tBUG(\"unknown subcommand %d\", cmdmode);\n \t}\ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex dda386bc3a..1f3f6e9fc5 100755\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -39,16 +39,6 @@ _x40=\"$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40\"\n TERM_BAD=bad\n TERM_GOOD=good\n \n-bisect_head()\n-{\n-\tif git rev-parse --verify -q BISECT_HEAD > /dev/null\n-\tthen\n-\t\techo BISECT_HEAD\n-\telse\n-\t\techo HEAD\n-\tfi\n-}\n-\n bisect_skip() {\n \tall=''\n \tfor arg in \"$@\"\n@@ -61,43 +51,7 @@ bisect_skip() {\n \t\tesac\n \t\tall=\"$all $revs\"\n \tdone\n-\teval bisect_state 'skip' $all\n-}\n-\n-bisect_state() {\n-\tgit bisect--helper --bisect-autostart || exit\n-\tstate=$1\n-\tgit bisect--helper --check-and-set-terms $state $TERM_GOOD $TERM_BAD || exit\n-\tget_terms\n-\tcase \"$#,$state\" in\n-\t0,*)\n-\t\tdie \"Please call 'bisect_state' with at least one argument.\" ;;\n-\t1,\"$TERM_BAD\"|1,\"$TERM_GOOD\"|1,skip)\n-\t\tbisected_head=$(bisect_head)\n-\t\trev=$(git rev-parse --verify \"$bisected_head\") ||\n-\t\t\tdie \"$(eval_gettext \"Bad rev input: \\$bisected_head\")\"\n-\t\tgit bisect--helper --bisect-write \"$state\" \"$rev\" \"$TERM_GOOD\" \"$TERM_BAD\" || exit\n-\t\tgit bisect--helper --check-expected-revs \"$rev\" ;;\n-\t2,\"$TERM_BAD\"|*,\"$TERM_GOOD\"|*,skip)\n-\t\tshift\n-\t\thash_list=''\n-\t\tfor rev in \"$@\"\n-\t\tdo\n-\t\t\tsha=$(git rev-parse --verify \"$rev^{commit}\") ||\n-\t\t\t\tdie \"$(eval_gettext \"Bad rev input: \\$rev\")\"\n-\t\t\thash_list=\"$hash_list $sha\"\n-\t\tdone\n-\t\tfor rev in $hash_list\n-\t\tdo\n-\t\t\tgit bisect--helper --bisect-write \"$state\" \"$rev\" \"$TERM_GOOD\" \"$TERM_BAD\" || exit\n-\t\tdone\n-\t\tgit bisect--helper --check-expected-revs $hash_list ;;\n-\t*,\"$TERM_BAD\")\n-\t\tdie \"$(eval_gettext \"'git bisect \\$TERM_BAD' can take only one argument.\")\" ;;\n-\t*)\n-\t\tusage ;;\n-\tesac\n-\tgit bisect--helper --bisect-auto-next\n+\teval git bisect--helper --bisect-state 'skip' $all\n }\n \n bisect_visualize() {\n@@ -187,8 +141,7 @@ exit code \\$res from '\\$command' is < 0 or >= 128\" >&2\n \t\t\tstate=\"$TERM_GOOD\"\n \t\tfi\n \n-\t\t# We have to use a subshell because \"bisect_state\" can exit.\n-\t\t( bisect_state $state >\"$GIT_DIR/BISECT_RUN\" )\n+\t\tgit bisect--helper --bisect-state $state >\"$GIT_DIR/BISECT_RUN\"\n \t\tres=$?\n \n \t\tcat \"$GIT_DIR/BISECT_RUN\"\n@@ -203,7 +156,7 @@ exit code \\$res from '\\$command' is < 0 or >= 128\" >&2\n \t\tif [ $res -ne 0 ]\n \t\tthen\n \t\t\teval_gettextln \"bisect run failed:\n-'bisect_state \\$state' exited with error code \\$res\" >&2\n+'bisect-state \\$state' exited with error code \\$res\" >&2\n \t\t\texit $res\n \t\tfi\n \n@@ -244,7 +197,7 @@ case \"$#\" in\n \tstart)\n \t\tgit bisect--helper --bisect-start \"$@\" ;;\n \tbad|good|new|old|\"$TERM_BAD\"|\"$TERM_GOOD\")\n-\t\tbisect_state \"$cmd\" \"$@\" ;;\n+\t\tgit bisect--helper --bisect-state \"$cmd\" \"$@\" ;;\n \tskip)\n \t\tbisect_skip \"$@\" ;;\n \tnext)\n-- \n2.25.0\n\n"},{"id":"407281","messageId":"20201010140743.580-4-mirucam@gmail.com","threadId":"54384","inReplyTo":"20201010140743.580-1-mirucam@gmail.com","subject":"[PATCH v10 3/7] bisect--helper: retire `--next-all` subcommand","fromName":"Miriam Rubio","fromEmail":"mirucam@gmail.com","sentAt":"2020-10-10T14:07:39Z","receivedAt":"2020-10-10T23:10:28Z","isPatch":true,"sender":{"key":"mirucam@gmail.com","avatar":"https://avatars.githubusercontent.com/u/56339109?v=4"},"body":"From: Pranit Bauva <pranit.bauva@gmail.com>\n\nThe `--next-all` subcommand is no longer used from the git-bisect.sh\nshell script. Instead the function `bisect_next_all()` is called from\nthe C implementation of `bisect_next()`.\n\nMentored-by: Lars Schneider <larsxschneider@gmail.com>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Pranit Bauva <pranit.bauva@gmail.com>\nSigned-off-by: Tanushree Tumane <tanushreetumane@gmail.com>\nSigned-off-by: Miriam Rubio <mirucam@gmail.com>\n---\n builtin/bisect--helper.c | 9 +--------\n 1 file changed, 1 insertion(+), 8 deletions(-)\n\ndiff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\nindex fbb9046737..f1a7cfbfaf 100644\n--- a/builtin/bisect--helper.c\n+++ b/builtin/bisect--helper.c\n@@ -20,7 +20,6 @@ static GIT_PATH_FUNC(git_path_bisect_names, \"BISECT_NAMES\")\n static GIT_PATH_FUNC(git_path_bisect_first_parent, \"BISECT_FIRST_PARENT\")\n \n static const char * const git_bisect_helper_usage[] = {\n-\tN_(\"git bisect--helper --next-all\"),\n \tN_(\"git bisect--helper --write-terms <bad_term> <good_term>\"),\n \tN_(\"git bisect--helper --bisect-reset [<commit>]\"),\n \tN_(\"git bisect--helper --bisect-write [--no-log] <state> <revision> <good_term> <bad_term>\"),\n@@ -858,8 +857,7 @@ static int bisect_autostart(struct bisect_terms *terms)\n int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n {\n \tenum {\n-\t\tNEXT_ALL = 1,\n-\t\tWRITE_TERMS,\n+\t\tWRITE_TERMS = 1,\n \t\tCHECK_EXPECTED_REVS,\n \t\tBISECT_RESET,\n \t\tBISECT_WRITE,\n@@ -873,8 +871,6 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \t} cmdmode = 0;\n \tint res = 0, nolog = 0;\n \tstruct option options[] = {\n-\t\tOPT_CMDMODE(0, \"next-all\", &cmdmode,\n-\t\t\t N_(\"perform 'git bisect next'\"), NEXT_ALL),\n \t\tOPT_CMDMODE(0, \"write-terms\", &cmdmode,\n \t\t\t N_(\"write the terms to .git/BISECT_TERMS\"), WRITE_TERMS),\n \t\tOPT_CMDMODE(0, \"check-expected-revs\", &cmdmode,\n@@ -911,9 +907,6 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \t\tusage_with_options(git_bisect_helper_usage, options);\n \n \tswitch (cmdmode) {\n-\tcase NEXT_ALL:\n-\t\tres = bisect_next_all(the_repository, prefix);\n-\t\tbreak;\n \tcase WRITE_TERMS:\n \t\tif (argc != 2)\n \t\t\treturn error(_(\"--write-terms requires two arguments\"));\n-- \n2.25.0\n\n"},{"id":"407323","messageId":"nycvar.QRO.7.76.6.2010121242000.50@tvgsbejvaqbjf.bet","threadId":"54384","inReplyTo":"20201010140743.580-5-mirucam@gmail.com","subject":"Re: [PATCH v10 4/7] bisect--helper: reimplement `bisect_state` & `bisect_head` shell functions in C","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2020-10-12T10:45:33Z","receivedAt":"2020-10-12T10:45:43Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Miriam,\n\nI read through the entire patch series, and have only _tiny_ nitpicks\nleft. Well done!\n\nOn Sat, 10 Oct 2020, Miriam Rubio wrote:\n\n> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\n> index f1a7cfbfaf..66b5346e42 100644\n> --- a/builtin/bisect--helper.c\n> +++ b/builtin/bisect--helper.c\n> @@ -31,6 +31,8 @@ static const char * const git_bisect_helper_usage[] = {\n>  \tN_(\"git bisect--helper --bisect-next\"),\n>  \tN_(\"git bisect--helper --bisect-auto-next\"),\n>  \tN_(\"git bisect--helper --bisect-autostart\"),\n> +\tN_(\"git bisect--helper --bisect-state (bad|new) [<rev>]\"),\n> +\tN_(\"git bisect--helper --bisect-state (good|old) [<rev>...]\"),\n>  \tNULL\n>  };\n>\n> @@ -854,6 +856,78 @@ static int bisect_autostart(struct bisect_terms *terms)\n>  \treturn res;\n>  }\n>\n> +static enum bisect_error bisect_state(struct bisect_terms *terms, const char **argv,\n> +\t\t\t\t      int argc)\n> +{\n> +\tconst char *state;\n> +\tint i, verify_expected = 1;\n> +\tstruct object_id oid, expected;\n> +\tstruct strbuf buf = STRBUF_INIT;\n> +\tstruct oid_array revs = OID_ARRAY_INIT;\n> +\n> +\tif (!argc)\n> +\t\treturn error(_(\"Please call `--bisect-state` with at least one argument\"));\n> +\n> +\tif (bisect_autostart(terms))\n> +\t\treturn BISECT_FAILED;\n> +\n> +\tstate = argv[0];\n> +\tif (check_and_set_terms(terms, state) ||\n> +\t    !one_of(state, terms->term_good, terms->term_bad, \"skip\", NULL))\n> +\t\treturn BISECT_FAILED;\n> +\n> +\targv++;\n> +\targc--;\n> +\tif (argc > 1 && !strcmp(state, terms->term_bad))\n> +\t\treturn error(_(\"'git bisect %s' can take only one argument.\"), terms->term_bad);\n> +\n> +\tif (argc == 0) {\n> +\t\tconst char *head = \"BISECT_HEAD\";\n> +\t\tenum get_oid_result res_head = get_oid(head, &oid);\n> +\n> +\t\tif (res_head == MISSING_OBJECT) {\n> +\t\t\thead = \"HEAD\";\n> +\t\t\tres_head = get_oid(head, &oid);\n> +\t\t}\n> +\n> +\t\tif (res_head)\n> +\t\t\terror(_(\"Bad rev input: %s\"), head);\n> +\t\toid_array_append(&revs, &oid);\n> +\t}\n> +\n> +\t/*\n> +\t * All input revs must be checked before executing bisect_write()\n> +\t * to discard junk revs.\n> +\t */\n> +\n> +\tfor (; argc; argc--, argv++) {\n> +\t\tif (get_oid(*argv, &oid)){\n> +\t\t\terror(_(\"Bad rev input: %s\"), *argv);\n\nHere, we leak `revs`. Maybe\n\n\t\t\toid_array_clear(&revs);\n\n?\n\n> +\t\t\treturn BISECT_FAILED;\n> +\t\t}\n> +\t\toid_array_append(&revs, &oid);\n> +\t}\n> +\n> +\tif (strbuf_read_file(&buf, git_path_bisect_expected_rev(), 0) < the_hash_algo->hexsz ||\n> +\t    get_oid_hex(buf.buf, &expected) < 0)\n> +\t\tverify_expected = 0; /* Ignore invalid file contents */\n> +\tstrbuf_release(&buf);\n> +\n> +\tfor (i = 0; i < revs.nr; i++) {\n> +\t\tif (bisect_write(state, oid_to_hex(&revs.oid[i]), terms, 0))\n\nSame here.\n\nIt is not exactly clear to me how problematic this leak would be, as we're\nonly calling this function from `cmd_*()` and return immediately\nafterwards. It might be worth cleaning up memory, though, in case we want\nto move this code into `libgit.a` and potentially call it from elsewhere\n(where we would _not_ necessarily `exit()` immediately upon seeing a\nfailure).\n\nOtherwise, the patch series looks good to me!\n\nThank you for your patient efforts,\nDscho\n\n> +\t\t\treturn BISECT_FAILED;\n> +\n> +\t\tif (verify_expected && !oideq(&revs.oid[i], &expected)) {\n> +\t\t\tunlink_or_warn(git_path_bisect_ancestors_ok());\n> +\t\t\tunlink_or_warn(git_path_bisect_expected_rev());\n> +\t\t\tverify_expected = 0;\n> +\t\t}\n> +\t}\n> +\n> +\toid_array_clear(&revs);\n> +\treturn bisect_auto_next(terms, NULL);\n> +}\n> +\n>  int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>  {\n>  \tenum {\n> @@ -867,7 +941,8 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>  \t\tBISECT_START,\n>  \t\tBISECT_AUTOSTART,\n>  \t\tBISECT_NEXT,\n> -\t\tBISECT_AUTO_NEXT\n> +\t\tBISECT_AUTO_NEXT,\n> +\t\tBISECT_STATE\n>  \t} cmdmode = 0;\n>  \tint res = 0, nolog = 0;\n>  \tstruct option options[] = {\n> @@ -893,6 +968,8 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>  \t\t\t N_(\"verify the next bisection state then checkout the next bisection commit\"), BISECT_AUTO_NEXT),\n>  \t\tOPT_CMDMODE(0, \"bisect-autostart\", &cmdmode,\n>  \t\t\t N_(\"start the bisection if it has not yet been started\"), BISECT_AUTOSTART),\n> +\t\tOPT_CMDMODE(0, \"bisect-state\", &cmdmode,\n> +\t\t\t N_(\"mark the state of ref (or refs)\"), BISECT_STATE),\n>  \t\tOPT_BOOL(0, \"no-log\", &nolog,\n>  \t\t\t N_(\"no log for BISECT_WRITE\")),\n>  \t\tOPT_END()\n> @@ -963,6 +1040,11 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>  \t\tset_terms(&terms, \"bad\", \"good\");\n>  \t\tres = bisect_autostart(&terms);\n>  \t\tbreak;\n> +\tcase BISECT_STATE:\n> +\t\tset_terms(&terms, \"bad\", \"good\");\n> +\t\tget_terms(&terms);\n> +\t\tres = bisect_state(&terms, argv, argc);\n> +\t\tbreak;\n>  \tdefault:\n>  \t\tBUG(\"unknown subcommand %d\", cmdmode);\n>  \t}\n> diff --git a/git-bisect.sh b/git-bisect.sh\n> index dda386bc3a..1f3f6e9fc5 100755\n> --- a/git-bisect.sh\n> +++ b/git-bisect.sh\n> @@ -39,16 +39,6 @@ _x40=\"$_x40$_x40$_x40$_x40$_x40$_x40$_x40$_x40\"\n>  TERM_BAD=bad\n>  TERM_GOOD=good\n>\n> -bisect_head()\n> -{\n> -\tif git rev-parse --verify -q BISECT_HEAD > /dev/null\n> -\tthen\n> -\t\techo BISECT_HEAD\n> -\telse\n> -\t\techo HEAD\n> -\tfi\n> -}\n> -\n>  bisect_skip() {\n>  \tall=''\n>  \tfor arg in \"$@\"\n> @@ -61,43 +51,7 @@ bisect_skip() {\n>  \t\tesac\n>  \t\tall=\"$all $revs\"\n>  \tdone\n> -\teval bisect_state 'skip' $all\n> -}\n> -\n> -bisect_state() {\n> -\tgit bisect--helper --bisect-autostart || exit\n> -\tstate=$1\n> -\tgit bisect--helper --check-and-set-terms $state $TERM_GOOD $TERM_BAD || exit\n> -\tget_terms\n> -\tcase \"$#,$state\" in\n> -\t0,*)\n> -\t\tdie \"Please call 'bisect_state' with at least one argument.\" ;;\n> -\t1,\"$TERM_BAD\"|1,\"$TERM_GOOD\"|1,skip)\n> -\t\tbisected_head=$(bisect_head)\n> -\t\trev=$(git rev-parse --verify \"$bisected_head\") ||\n> -\t\t\tdie \"$(eval_gettext \"Bad rev input: \\$bisected_head\")\"\n> -\t\tgit bisect--helper --bisect-write \"$state\" \"$rev\" \"$TERM_GOOD\" \"$TERM_BAD\" || exit\n> -\t\tgit bisect--helper --check-expected-revs \"$rev\" ;;\n> -\t2,\"$TERM_BAD\"|*,\"$TERM_GOOD\"|*,skip)\n> -\t\tshift\n> -\t\thash_list=''\n> -\t\tfor rev in \"$@\"\n> -\t\tdo\n> -\t\t\tsha=$(git rev-parse --verify \"$rev^{commit}\") ||\n> -\t\t\t\tdie \"$(eval_gettext \"Bad rev input: \\$rev\")\"\n> -\t\t\thash_list=\"$hash_list $sha\"\n> -\t\tdone\n> -\t\tfor rev in $hash_list\n> -\t\tdo\n> -\t\t\tgit bisect--helper --bisect-write \"$state\" \"$rev\" \"$TERM_GOOD\" \"$TERM_BAD\" || exit\n> -\t\tdone\n> -\t\tgit bisect--helper --check-expected-revs $hash_list ;;\n> -\t*,\"$TERM_BAD\")\n> -\t\tdie \"$(eval_gettext \"'git bisect \\$TERM_BAD' can take only one argument.\")\" ;;\n> -\t*)\n> -\t\tusage ;;\n> -\tesac\n> -\tgit bisect--helper --bisect-auto-next\n> +\teval git bisect--helper --bisect-state 'skip' $all\n>  }\n>\n>  bisect_visualize() {\n> @@ -187,8 +141,7 @@ exit code \\$res from '\\$command' is < 0 or >= 128\" >&2\n>  \t\t\tstate=\"$TERM_GOOD\"\n>  \t\tfi\n>\n> -\t\t# We have to use a subshell because \"bisect_state\" can exit.\n> -\t\t( bisect_state $state >\"$GIT_DIR/BISECT_RUN\" )\n> +\t\tgit bisect--helper --bisect-state $state >\"$GIT_DIR/BISECT_RUN\"\n>  \t\tres=$?\n>\n>  \t\tcat \"$GIT_DIR/BISECT_RUN\"\n> @@ -203,7 +156,7 @@ exit code \\$res from '\\$command' is < 0 or >= 128\" >&2\n>  \t\tif [ $res -ne 0 ]\n>  \t\tthen\n>  \t\t\teval_gettextln \"bisect run failed:\n> -'bisect_state \\$state' exited with error code \\$res\" >&2\n> +'bisect-state \\$state' exited with error code \\$res\" >&2\n>  \t\t\texit $res\n>  \t\tfi\n>\n> @@ -244,7 +197,7 @@ case \"$#\" in\n>  \tstart)\n>  \t\tgit bisect--helper --bisect-start \"$@\" ;;\n>  \tbad|good|new|old|\"$TERM_BAD\"|\"$TERM_GOOD\")\n> -\t\tbisect_state \"$cmd\" \"$@\" ;;\n> +\t\tgit bisect--helper --bisect-state \"$cmd\" \"$@\" ;;\n>  \tskip)\n>  \t\tbisect_skip \"$@\" ;;\n>  \tnext)\n> --\n> 2.25.0\n>\n>\n"}]}