{"thread":{"id":"42831","subject":"[PATCH 0/9] Resend of gitster/pb/bisect","startedAt":"2016-07-12T22:41:02Z","lastAt":"2016-07-20T16:00:20Z","messageCount":12,"participants":["Pranit Bauva","Christian Couder"],"isPatch":true,"patchVersion":1,"patchTotal":9},"messages":[{"id":"291313","messageId":"20160712223538.28508-1-pranit.bauva@gmail.com","threadId":"42831","inReplyTo":null,"subject":"[PATCH 0/9] Resend of gitster/pb/bisect","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-07-12T22:35:29Z","receivedAt":"2016-07-12T22:41:02Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"Hey Junio,\n\nA small mistake got unnoticed by me which Lars recently pointed out.\nThe naming convention is \"git_path_<name_of_file>\" and underscore\ninstead of spaces.\n\nThanks!\n\nThe interdiff is:\ndiff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\nindex c2f3cee..88a1df8 100644\n--- a/builtin/bisect--helper.c\n+++ b/builtin/bisect--helper.c\n@@ -7,7 +7,7 @@\n #include \"argv-array.h\"\n #include \"run-command.h\"\n \n-static GIT_PATH_FUNC(git_path_bisect_write_terms, \"BISECT_TERMS\")\n+static GIT_PATH_FUNC(git_path_bisect_terms, \"BISECT_TERMS\")\n static GIT_PATH_FUNC(git_path_bisect_expected_rev, \"BISECT_EXPECTED_REV\")\n static GIT_PATH_FUNC(git_path_bisect_ancestors_ok, \"BISECT_ANCESTORS_OK\")\n static GIT_PATH_FUNC(git_path_bisect_log, \"BISECT_LOG\")\n@@ -100,7 +100,7 @@ static int write_terms(const char *bad, const char *good)\n \tif (check_term_format(bad, \"bad\") || check_term_format(good, \"good\"))\n \t\treturn -1;\n \n-\tfp = fopen(git_path_bisect_write_terms(), \"w\");\n+\tfp = fopen(git_path_bisect_terms(), \"w\");\n \tif (!fp)\n \t\treturn error_errno(_(\"could not open the file BISECT_TERMS\"));\n \n@@ -134,7 +134,7 @@ static int bisect_clean_state(void)\n \tremove_path(git_path_bisect_log());\n \tremove_path(git_path_bisect_names());\n \tremove_path(git_path_bisect_run());\n-\tremove_path(git_path_bisect_write_terms());\n+\tremove_path(git_path_bisect_terms());\n \t/* Cleanup head-name if it got left by an old version of git-bisect */\n \tremove_path(git_path_head_name());\n \t/*\n\n\nPranit Bauva (9):\n  bisect--helper: use OPT_CMDMODE instead of OPT_BOOL\n  bisect: rewrite `check_term_format` shell function in C\n  bisect--helper: `write_terms` shell function in C\n  bisect--helper: `bisect_clean_state` shell function in C\n  t6030: explicitly test for bisection cleanup\n  wrapper: move is_empty_file() and rename it as\n    is_empty_or_missing_file()\n  bisect--helper: `bisect_reset` shell function in C\n  bisect--helper: `is_expected_rev` & `check_expected_revs` shell\n    function in C\n  bisect--helper: `bisect_write` shell function in C\n\n builtin/am.c                |  20 +--\n builtin/bisect--helper.c    | 310 +++++++++++++++++++++++++++++++++++++++++++-\n cache.h                     |   3 +\n git-bisect.sh               | 146 +++------------------\n t/t6030-bisect-porcelain.sh |  17 +++\n wrapper.c                   |  13 ++\n 6 files changed, 355 insertions(+), 154 deletions(-)\n\n-- \n2.9.0\n\n"},{"id":"291314","messageId":"20160712223538.28508-3-pranit.bauva@gmail.com","threadId":"42831","inReplyTo":"20160712223538.28508-1-pranit.bauva@gmail.com","subject":"[PATCH 2/9] bisect: rewrite `check_term_format` shell function in C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-07-12T22:35:31Z","receivedAt":"2016-07-12T22:41:06Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"Reimplement the `check_term_format` shell function in C and add\na `--check-term-format` subcommand to `git bisect--helper` to call it\nfrom git-bisect.sh\n\nUsing `--check-term-format` subcommand is a temporary measure to port\nshell function to C so as to use the existing test suite. As more\nfunctions are ported, this subcommand will be retired and will\nbe called by some other method/subcommand. For eg. In conversion of\nwrite_terms() of git-bisect.sh, the subcommand will be removed and\ninstead check_term_format() will be called in its C implementation while\na new subcommand will be introduced for write_terms().\n\nHelped-by: Johannes Schindelein <Johannes.Schindelein@gmx.de>\nMentored-by: Lars Schneider <larsxschneider@gmail.com>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n---\n builtin/bisect--helper.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++-\n git-bisect.sh            | 31 ++-----------------------\n 2 files changed, 60 insertions(+), 30 deletions(-)\n\ndiff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\nindex 8111c91..3c748d1 100644\n--- a/builtin/bisect--helper.c\n+++ b/builtin/bisect--helper.c\n@@ -2,19 +2,72 @@\n #include \"cache.h\"\n #include \"parse-options.h\"\n #include \"bisect.h\"\n+#include \"refs.h\"\n \n static const char * const git_bisect_helper_usage[] = {\n \tN_(\"git bisect--helper --next-all [--no-checkout]\"),\n+\tN_(\"git bisect--helper --check-term-format <term> <orig_term>\"),\n \tNULL\n };\n \n+/*\n+ * Check whether the string `term` belongs to the set of strings\n+ * included in the variable arguments.\n+ */\n+static int one_of(const char *term, ...)\n+{\n+\tint res = 0;\n+\tva_list matches;\n+\tconst char *match;\n+\n+\tva_start(matches, term);\n+\twhile (!res && (match = va_arg(matches, const char *)))\n+\t\tres = !strcmp(term, match);\n+\tva_end(matches);\n+\n+\treturn res;\n+}\n+\n+static int check_term_format(const char *term, const char *orig_term)\n+{\n+\tstruct strbuf new_term = STRBUF_INIT;\n+\tstrbuf_addf(&new_term, \"refs/bisect/%s\", term);\n+\n+\tif (check_refname_format(new_term.buf, 0)) {\n+\t\tstrbuf_release(&new_term);\n+\t\treturn error(_(\"'%s' is not a valid term\"), term);\n+\t}\n+\tstrbuf_release(&new_term);\n+\n+\tif (one_of(term, \"help\", \"start\", \"skip\", \"next\", \"reset\",\n+\t\t\t\"visualize\", \"replay\", \"log\", \"run\", NULL))\n+\t\treturn error(_(\"can't use the builtin command '%s' as a term\"), term);\n+\n+\t/*\n+\t * In theory, nothing prevents swapping completely good and bad,\n+\t * but this situation could be confusing and hasn't been tested\n+\t * enough. Forbid it for now.\n+\t */\n+\n+\tif ((strcmp(orig_term, \"bad\") && one_of(term, \"bad\", \"new\", NULL)) ||\n+\t\t (strcmp(orig_term, \"good\") && one_of(term, \"good\", \"old\", NULL)))\n+\t\treturn error(_(\"can't change the meaning of the term '%s'\"), term);\n+\n+\treturn 0;\n+}\n+\n int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n {\n-\tenum { NEXT_ALL = 1 } cmdmode = 0;\n+\tenum {\n+\t\tNEXT_ALL = 1,\n+\t\tCHECK_TERM_FMT\n+\t} cmdmode = 0;\n \tint no_checkout = 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, \"check-term-format\", &cmdmode,\n+\t\t\t N_(\"check format of the term\"), CHECK_TERM_FMT),\n \t\tOPT_BOOL(0, \"no-checkout\", &no_checkout,\n \t\t\t N_(\"update BISECT_HEAD instead of checking out the current commit\")),\n \t\tOPT_END()\n@@ -29,6 +82,10 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \tswitch (cmdmode) {\n \tcase NEXT_ALL:\n \t\treturn bisect_next_all(prefix, no_checkout);\n+\tcase CHECK_TERM_FMT:\n+\t\tif (argc != 2)\n+\t\t\tdie(_(\"--check-term-format requires two arguments\"));\n+\t\treturn check_term_format(argv[0], argv[1]);\n \tdefault:\n \t\tdie(\"BUG: unknown subcommand '%d'\", cmdmode);\n \t}\ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex 5d1cb00..7d7965d 100755\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -564,38 +564,11 @@ write_terms () {\n \tthen\n \t\tdie \"$(gettext \"please use two different terms\")\"\n \tfi\n-\tcheck_term_format \"$TERM_BAD\" bad\n-\tcheck_term_format \"$TERM_GOOD\" good\n+\tgit bisect--helper --check-term-format \"$TERM_BAD\" bad || exit\n+\tgit bisect--helper --check-term-format \"$TERM_GOOD\" good || exit\n \tprintf '%s\\n%s\\n' \"$TERM_BAD\" \"$TERM_GOOD\" >\"$GIT_DIR/BISECT_TERMS\"\n }\n \n-check_term_format () {\n-\tterm=$1\n-\tgit check-ref-format refs/bisect/\"$term\" ||\n-\tdie \"$(eval_gettext \"'\\$term' is not a valid term\")\"\n-\tcase \"$term\" in\n-\thelp|start|terms|skip|next|reset|visualize|replay|log|run)\n-\t\tdie \"$(eval_gettext \"can't use the builtin command '\\$term' as a term\")\"\n-\t\t;;\n-\tbad|new)\n-\t\tif test \"$2\" != bad\n-\t\tthen\n-\t\t\t# In theory, nothing prevents swapping\n-\t\t\t# completely good and bad, but this situation\n-\t\t\t# could be confusing and hasn't been tested\n-\t\t\t# enough. Forbid it for now.\n-\t\t\tdie \"$(eval_gettext \"can't change the meaning of term '\\$term'\")\"\n-\t\tfi\n-\t\t;;\n-\tgood|old)\n-\t\tif test \"$2\" != good\n-\t\tthen\n-\t\t\tdie \"$(eval_gettext \"can't change the meaning of term '\\$term'\")\"\n-\t\tfi\n-\t\t;;\n-\tesac\n-}\n-\n check_and_set_terms () {\n \tcmd=\"$1\"\n \tcase \"$cmd\" in\n-- \n2.9.0\n\n"},{"id":"291315","messageId":"20160712223538.28508-4-pranit.bauva@gmail.com","threadId":"42831","inReplyTo":"20160712223538.28508-1-pranit.bauva@gmail.com","subject":"[PATCH 3/9] bisect--helper: `write_terms` shell function in C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-07-12T22:35:32Z","receivedAt":"2016-07-12T22:41:07Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"Reimplement the `write_terms` shell function in C and add a `write-terms`\nsubcommand to `git bisect--helper` to call it from git-bisect.sh . Also\nremove the subcommand `--check-term-format` as it can now be called from\ninside the function write_terms() C implementation.\n\nAlso `|| exit` is added when calling write-terms subcommand from\ngit-bisect.sh so as to exit whenever there is an error.\n\nUsing `--write-terms` 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 method.\n\nMentored-by: Lars Schneider <larsxschneider@gmail.com>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n---\n builtin/bisect--helper.c | 36 +++++++++++++++++++++++++++++-------\n git-bisect.sh            | 22 +++++++---------------\n 2 files changed, 36 insertions(+), 22 deletions(-)\n\ndiff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\nindex 3c748d1..bec63d6 100644\n--- a/builtin/bisect--helper.c\n+++ b/builtin/bisect--helper.c\n@@ -4,9 +4,11 @@\n #include \"bisect.h\"\n #include \"refs.h\"\n \n+static GIT_PATH_FUNC(git_path_bisect_terms, \"BISECT_TERMS\")\n+\n static const char * const git_bisect_helper_usage[] = {\n \tN_(\"git bisect--helper --next-all [--no-checkout]\"),\n-\tN_(\"git bisect--helper --check-term-format <term> <orig_term>\"),\n+\tN_(\"git bisect--helper --write-terms <bad_term> <good_term>\"),\n \tNULL\n };\n \n@@ -56,18 +58,38 @@ static int check_term_format(const char *term, const char *orig_term)\n \treturn 0;\n }\n \n+static int write_terms(const char *bad, const char *good)\n+{\n+\tFILE *fp;\n+\tint res;\n+\n+\tif (!strcmp(bad, good))\n+\t\treturn error(_(\"please use two different terms\"));\n+\n+\tif (check_term_format(bad, \"bad\") || check_term_format(good, \"good\"))\n+\t\treturn -1;\n+\n+\tfp = fopen(git_path_bisect_terms(), \"w\");\n+\tif (!fp)\n+\t\treturn error_errno(_(\"could not open the file BISECT_TERMS\"));\n+\n+\tres = fprintf(fp, \"%s\\n%s\\n\", bad, good);\n+\tfclose(fp);\n+\treturn (res < 0) ? -1 : 0;\n+}\n+\n int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n {\n \tenum {\n \t\tNEXT_ALL = 1,\n-\t\tCHECK_TERM_FMT\n+\t\tWRITE_TERMS\n \t} cmdmode = 0;\n \tint no_checkout = 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, \"check-term-format\", &cmdmode,\n-\t\t\t N_(\"check format of the term\"), CHECK_TERM_FMT),\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_BOOL(0, \"no-checkout\", &no_checkout,\n \t\t\t N_(\"update BISECT_HEAD instead of checking out the current commit\")),\n \t\tOPT_END()\n@@ -82,10 +104,10 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \tswitch (cmdmode) {\n \tcase NEXT_ALL:\n \t\treturn bisect_next_all(prefix, no_checkout);\n-\tcase CHECK_TERM_FMT:\n+\tcase WRITE_TERMS:\n \t\tif (argc != 2)\n-\t\t\tdie(_(\"--check-term-format requires two arguments\"));\n-\t\treturn check_term_format(argv[0], argv[1]);\n+\t\t\tdie(_(\"--write-terms requires two arguments\"));\n+\t\treturn write_terms(argv[0], argv[1]);\n \tdefault:\n \t\tdie(\"BUG: unknown subcommand '%d'\", cmdmode);\n \t}\ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex 7d7965d..cd39bd0 100755\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -210,7 +210,7 @@ bisect_start() {\n \teval \"$eval true\" &&\n \tif test $must_write_terms -eq 1\n \tthen\n-\t\twrite_terms \"$TERM_BAD\" \"$TERM_GOOD\"\n+\t\tgit bisect--helper --write-terms \"$TERM_BAD\" \"$TERM_GOOD\"\n \tfi &&\n \techo \"git bisect start$orig_args\" >>\"$GIT_DIR/BISECT_LOG\" || exit\n \t#\n@@ -557,18 +557,6 @@ get_terms () {\n \tfi\n }\n \n-write_terms () {\n-\tTERM_BAD=$1\n-\tTERM_GOOD=$2\n-\tif test \"$TERM_BAD\" = \"$TERM_GOOD\"\n-\tthen\n-\t\tdie \"$(gettext \"please use two different terms\")\"\n-\tfi\n-\tgit bisect--helper --check-term-format \"$TERM_BAD\" bad || exit\n-\tgit bisect--helper --check-term-format \"$TERM_GOOD\" good || exit\n-\tprintf '%s\\n%s\\n' \"$TERM_BAD\" \"$TERM_GOOD\" >\"$GIT_DIR/BISECT_TERMS\"\n-}\n-\n check_and_set_terms () {\n \tcmd=\"$1\"\n \tcase \"$cmd\" in\n@@ -582,13 +570,17 @@ check_and_set_terms () {\n \t\tbad|good)\n \t\t\tif ! test -s \"$GIT_DIR/BISECT_TERMS\"\n \t\t\tthen\n-\t\t\t\twrite_terms bad good\n+\t\t\t\tTERM_BAD=bad\n+\t\t\t\tTERM_GOOD=good\n+\t\t\t\tgit bisect--helper --write-terms \"$TERM_BAD\" \"$TERM_GOOD\" || exit\n \t\t\tfi\n \t\t\t;;\n \t\tnew|old)\n \t\t\tif ! test -s \"$GIT_DIR/BISECT_TERMS\"\n \t\t\tthen\n-\t\t\t\twrite_terms new old\n+\t\t\t\tTERM_BAD=new\n+\t\t\t\tTERM_GOOD=old\n+\t\t\t\tgit bisect--helper --write-terms \"$TERM_BAD\" \"$TERM_GOOD\" || exit\n \t\t\tfi\n \t\t\t;;\n \t\tesac ;;\n-- \n2.9.0\n\n"},{"id":"291316","messageId":"20160712223538.28508-2-pranit.bauva@gmail.com","threadId":"42831","inReplyTo":"20160712223538.28508-1-pranit.bauva@gmail.com","subject":"[PATCH 1/9] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-07-12T22:35:30Z","receivedAt":"2016-07-12T22:41:08Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"`--next-all` is meant to be used as a subcommand to support multiple\n\"operation mode\" though the current implementation does not contain any\nother subcommand along side with `--next-all` but further commits will\ninclude some more subcommands.\n\nHelped-by: Johannes Schindelin <Johannes.Schindelin@gmx.de>\nMentored-by: Lars Schneider <larsxschneider@gmail.com>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n---\n builtin/bisect--helper.c | 17 +++++++++++------\n 1 file changed, 11 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\nindex 3324229..8111c91 100644\n--- a/builtin/bisect--helper.c\n+++ b/builtin/bisect--helper.c\n@@ -10,11 +10,11 @@ static const char * const git_bisect_helper_usage[] = {\n \n int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n {\n-\tint next_all = 0;\n+\tenum { NEXT_ALL = 1 } cmdmode = 0;\n \tint no_checkout = 0;\n \tstruct option options[] = {\n-\t\tOPT_BOOL(0, \"next-all\", &next_all,\n-\t\t\t N_(\"perform 'git bisect next'\")),\n+\t\tOPT_CMDMODE(0, \"next-all\", &cmdmode,\n+\t\t\t N_(\"perform 'git bisect next'\"), NEXT_ALL),\n \t\tOPT_BOOL(0, \"no-checkout\", &no_checkout,\n \t\t\t N_(\"update BISECT_HEAD instead of checking out the current commit\")),\n \t\tOPT_END()\n@@ -23,9 +23,14 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \targc = parse_options(argc, argv, prefix, options,\n \t\t\t     git_bisect_helper_usage, 0);\n \n-\tif (!next_all)\n+\tif (!cmdmode)\n \t\tusage_with_options(git_bisect_helper_usage, options);\n \n-\t/* next-all */\n-\treturn bisect_next_all(prefix, no_checkout);\n+\tswitch (cmdmode) {\n+\tcase NEXT_ALL:\n+\t\treturn bisect_next_all(prefix, no_checkout);\n+\tdefault:\n+\t\tdie(\"BUG: unknown subcommand '%d'\", cmdmode);\n+\t}\n+\treturn 0;\n }\n-- \n2.9.0\n\n"},{"id":"291317","messageId":"20160712223538.28508-7-pranit.bauva@gmail.com","threadId":"42831","inReplyTo":"20160712223538.28508-1-pranit.bauva@gmail.com","subject":"[PATCH 6/9] wrapper: move is_empty_file() and rename it as is_empty_or_missing_file()","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-07-12T22:35:35Z","receivedAt":"2016-07-12T22:41:09Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"is_empty_file() can help to refactor a lot of code. This will be very\nhelpful in porting \"git bisect\" to C.\n\nSuggested-by: Torsten Bögershausen <tboegi@web.de>\nMentored-by: Lars Schneider <larsxschneider@gmail.com>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n---\n builtin/am.c | 20 ++------------------\n cache.h      |  3 +++\n wrapper.c    | 13 +++++++++++++\n 3 files changed, 18 insertions(+), 18 deletions(-)\n\ndiff --git a/builtin/am.c b/builtin/am.c\nindex 3dfe70b..6ee158f 100644\n--- a/builtin/am.c\n+++ b/builtin/am.c\n@@ -30,22 +30,6 @@\n #include \"mailinfo.h\"\n \n /**\n- * Returns 1 if the file is empty or does not exist, 0 otherwise.\n- */\n-static int is_empty_file(const char *filename)\n-{\n-\tstruct stat st;\n-\n-\tif (stat(filename, &st) < 0) {\n-\t\tif (errno == ENOENT)\n-\t\t\treturn 1;\n-\t\tdie_errno(_(\"could not stat %s\"), filename);\n-\t}\n-\n-\treturn !st.st_size;\n-}\n-\n-/**\n  * Returns the length of the first line of msg.\n  */\n static int linelen(const char *msg)\n@@ -1323,7 +1307,7 @@ static int parse_mail(struct am_state *state, const char *mail)\n \t\tgoto finish;\n \t}\n \n-\tif (is_empty_file(am_path(state, \"patch\"))) {\n+\tif (is_empty_or_missing_file(am_path(state, \"patch\"))) {\n \t\tprintf_ln(_(\"Patch is empty. Was it split wrong?\"));\n \t\tdie_user_resolve(state);\n \t}\n@@ -1911,7 +1895,7 @@ next:\n \t\tresume = 0;\n \t}\n \n-\tif (!is_empty_file(am_path(state, \"rewritten\"))) {\n+\tif (!is_empty_or_missing_file(am_path(state, \"rewritten\"))) {\n \t\tassert(state->rebasing);\n \t\tcopy_notes_for_rebase(state);\n \t\trun_post_rewrite_hook(state);\ndiff --git a/cache.h b/cache.h\nindex 6049f86..91e2f81 100644\n--- a/cache.h\n+++ b/cache.h\n@@ -1870,4 +1870,7 @@ void sleep_millisec(int millisec);\n  */\n void safe_create_dir(const char *dir, int share);\n \n+/* Return 1 if the file is empty or does not exists, 0 otherwise. */\n+extern int is_empty_or_missing_file(const char *filename);\n+\n #endif /* CACHE_H */\ndiff --git a/wrapper.c b/wrapper.c\nindex 5dc4e15..e70e4d1 100644\n--- a/wrapper.c\n+++ b/wrapper.c\n@@ -696,3 +696,16 @@ void sleep_millisec(int millisec)\n {\n \tpoll(NULL, 0, millisec);\n }\n+\n+int is_empty_or_missing_file(const char *filename)\n+{\n+\tstruct stat st;\n+\n+\tif (stat(filename, &st) < 0) {\n+\t\tif (errno == ENOENT)\n+\t\t\treturn 1;\n+\t\tdie_errno(_(\"could not stat %s\"), filename);\n+\t}\n+\n+\treturn !st.st_size;\n+}\n-- \n2.9.0\n\n"},{"id":"291318","messageId":"20160712223538.28508-5-pranit.bauva@gmail.com","threadId":"42831","inReplyTo":"20160712223538.28508-1-pranit.bauva@gmail.com","subject":"[PATCH 4/9] bisect--helper: `bisect_clean_state` shell function in C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-07-12T22:35:33Z","receivedAt":"2016-07-12T22:41:10Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"Reimplement `bisect_clean_state` shell function in C and add a\n`bisect-clean-state` subcommand to `git bisect--helper` to call it from\ngit-bisect.sh .\n\nUsing `--bisect-clean-state` subcommand is a 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\nbisect_reset() and bisect_start().\n\nMentored-by: Lars Schneider <larsxschneider@gmail.com>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n---\n builtin/bisect--helper.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++-\n git-bisect.sh            | 26 +++--------------------\n 2 files changed, 57 insertions(+), 24 deletions(-)\n\ndiff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\nindex bec63d6..3089433 100644\n--- a/builtin/bisect--helper.c\n+++ b/builtin/bisect--helper.c\n@@ -3,12 +3,21 @@\n #include \"parse-options.h\"\n #include \"bisect.h\"\n #include \"refs.h\"\n+#include \"dir.h\"\n \n static GIT_PATH_FUNC(git_path_bisect_terms, \"BISECT_TERMS\")\n+static GIT_PATH_FUNC(git_path_bisect_expected_rev, \"BISECT_EXPECTED_REV\")\n+static GIT_PATH_FUNC(git_path_bisect_ancestors_ok, \"BISECT_ANCESTORS_OK\")\n+static GIT_PATH_FUNC(git_path_bisect_log, \"BISECT_LOG\")\n+static GIT_PATH_FUNC(git_path_bisect_names, \"BISECT_NAMES\")\n+static GIT_PATH_FUNC(git_path_bisect_run, \"BISECT_RUN\")\n+static GIT_PATH_FUNC(git_path_head_name, \"head-name\")\n+static GIT_PATH_FUNC(git_path_bisect_start, \"BISECT_START\")\n \n static const char * const git_bisect_helper_usage[] = {\n \tN_(\"git bisect--helper --next-all [--no-checkout]\"),\n \tN_(\"git bisect--helper --write-terms <bad_term> <good_term>\"),\n+\tN_(\"git bisect--helper --bisect-clean-state\"),\n \tNULL\n };\n \n@@ -78,11 +87,49 @@ static int write_terms(const char *bad, const char *good)\n \treturn (res < 0) ? -1 : 0;\n }\n \n+static int mark_for_removal(const char *refname, const struct object_id *oid,\n+\t\t\t    int flag, void *cb_data)\n+{\n+\tstruct string_list *refs = cb_data;\n+\tchar *ref = xstrfmt(\"refs/bisect/%s\", refname);\n+\tstring_list_append(refs, ref);\n+\treturn 0;\n+}\n+\n+static int bisect_clean_state(void)\n+{\n+\tint result = 0;\n+\n+\t/* There may be some refs packed during bisection */\n+\tstruct string_list refs_for_removal = STRING_LIST_INIT_NODUP;\n+\tfor_each_ref_in(\"refs/bisect/\", mark_for_removal, (void *) &refs_for_removal);\n+\tstring_list_append(&refs_for_removal, xstrdup(\"BISECT_HEAD\"));\n+\tresult = delete_refs(&refs_for_removal);\n+\trefs_for_removal.strdup_strings = 1;\n+\tstring_list_clear(&refs_for_removal, 0);\n+\tremove_path(git_path_bisect_expected_rev());\n+\tremove_path(git_path_bisect_ancestors_ok());\n+\tremove_path(git_path_bisect_log());\n+\tremove_path(git_path_bisect_names());\n+\tremove_path(git_path_bisect_run());\n+\tremove_path(git_path_bisect_terms());\n+\t/* Cleanup head-name if it got left by an old version of git-bisect */\n+\tremove_path(git_path_head_name());\n+\t/*\n+\t * Cleanup BISECT_START last to support the --no-checkout option\n+\t * introduced in the commit 4796e823a.\n+\t */\n+\tremove_path(git_path_bisect_start());\n+\n+\treturn result;\n+}\n+\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,\n+\t\tBISECT_CLEAN_STATE\n \t} cmdmode = 0;\n \tint no_checkout = 0;\n \tstruct option options[] = {\n@@ -90,6 +137,8 @@ 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_BOOL(0, \"no-checkout\", &no_checkout,\n \t\t\t N_(\"update BISECT_HEAD instead of checking out the current commit\")),\n \t\tOPT_END()\n@@ -108,6 +157,10 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \t\tif (argc != 2)\n \t\t\tdie(_(\"--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\tdie(_(\"--bisect-clean-state requires no arguments\"));\n+\t\treturn bisect_clean_state();\n \tdefault:\n \t\tdie(\"BUG: unknown subcommand '%d'\", cmdmode);\n \t}\ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex cd39bd0..bbc57d2 100755\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -187,7 +187,7 @@ bisect_start() {\n \t#\n \t# Get rid of any old bisect state.\n \t#\n-\tbisect_clean_state || exit\n+\tgit bisect--helper --bisect-clean-state || exit\n \n \t#\n \t# Change state.\n@@ -196,7 +196,7 @@ bisect_start() {\n \t# We have to trap this to be able to clean up using\n \t# \"bisect_clean_state\".\n \t#\n-\ttrap 'bisect_clean_state' 0\n+\ttrap 'git bisect--helper --bisect-clean-state' 0\n \ttrap 'exit 255' 1 2 3 15\n \n \t#\n@@ -430,27 +430,7 @@ bisect_reset() {\n \t\tdie \"$(eval_gettext \"Could not check out original HEAD '\\$branch'.\n Try 'git bisect reset <commit>'.\")\"\n \tfi\n-\tbisect_clean_state\n-}\n-\n-bisect_clean_state() {\n-\t# There may be some refs packed during bisection.\n-\tgit for-each-ref --format='%(refname) %(objectname)' refs/bisect/\\* |\n-\twhile read ref hash\n-\tdo\n-\t\tgit update-ref -d $ref $hash || exit\n-\tdone\n-\trm -f \"$GIT_DIR/BISECT_EXPECTED_REV\" &&\n-\trm -f \"$GIT_DIR/BISECT_ANCESTORS_OK\" &&\n-\trm -f \"$GIT_DIR/BISECT_LOG\" &&\n-\trm -f \"$GIT_DIR/BISECT_NAMES\" &&\n-\trm -f \"$GIT_DIR/BISECT_RUN\" &&\n-\trm -f \"$GIT_DIR/BISECT_TERMS\" &&\n-\t# Cleanup head-name if it got left by an old version of git-bisect\n-\trm -f \"$GIT_DIR/head-name\" &&\n-\tgit update-ref -d --no-deref BISECT_HEAD &&\n-\t# clean up BISECT_START last\n-\trm -f \"$GIT_DIR/BISECT_START\"\n+\tgit bisect--helper --bisect-clean-state || exit\n }\n \n bisect_replay () {\n-- \n2.9.0\n\n"},{"id":"291319","messageId":"20160712223538.28508-6-pranit.bauva@gmail.com","threadId":"42831","inReplyTo":"20160712223538.28508-1-pranit.bauva@gmail.com","subject":"[PATCH 5/9] t6030: explicitly test for bisection cleanup","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-07-12T22:35:34Z","receivedAt":"2016-07-12T22:41:13Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"Add test to explicitly check that 'git bisect reset' is working as\nexpected. This is already covered implicitly by the test suite.\n\nMentored-by: Lars Schneider <larsxschneider@gmail.com>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n\n---\nI faced this problem while converting `bisect_clean_state` and the tests\nwhere showing breakages but it wasn't clear as to where exactly are they\nbreaking. This will patch  will help in that. Also I tested the test\ncoverage of the test suite before this patch and it covers this (I did\nthis by purposely changing names of files in git-bisect.sh and running\nthe test suite).\n\nSigned-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n---\n t/t6030-bisect-porcelain.sh | 17 +++++++++++++++++\n 1 file changed, 17 insertions(+)\n\ndiff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh\nindex e74662b..a17f7a6 100755\n--- a/t/t6030-bisect-porcelain.sh\n+++ b/t/t6030-bisect-porcelain.sh\n@@ -894,4 +894,21 @@ test_expect_success 'bisect start takes options and revs in any order' '\n \ttest_cmp expected actual\n '\n \n+test_expect_success 'git bisect reset cleans bisection state properly' '\n+\tgit bisect reset &&\n+\tgit bisect start &&\n+\tgit bisect good $HASH1 &&\n+\tgit bisect bad $HASH4 &&\n+\tgit bisect reset &&\n+\ttest -z \"$(git for-each-ref \"refs/bisect/*\")\" &&\n+\ttest_path_is_missing \"$GIT_DIR/BISECT_EXPECTED_REV\" &&\n+\ttest_path_is_missing \"$GIT_DIR/BISECT_ANCESTORS_OK\" &&\n+\ttest_path_is_missing \"$GIT_DIR/BISECT_LOG\" &&\n+\ttest_path_is_missing \"$GIT_DIR/BISECT_RUN\" &&\n+\ttest_path_is_missing \"$GIT_DIR/BISECT_TERMS\" &&\n+\ttest_path_is_missing \"$GIT_DIR/head-name\" &&\n+\ttest_path_is_missing \"$GIT_DIR/BISECT_HEAD\" &&\n+\ttest_path_is_missing \"$GIT_DIR/BISECT_START\"\n+'\n+\n test_done\n-- \n2.9.0\n\n"},{"id":"291320","messageId":"20160712223538.28508-10-pranit.bauva@gmail.com","threadId":"42831","inReplyTo":"20160712223538.28508-1-pranit.bauva@gmail.com","subject":"[PATCH 9/9] bisect--helper: `bisect_write` shell function in C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-07-12T22:35:38Z","receivedAt":"2016-07-12T22:41:14Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"Reimplement the `bisect_write` shell function in C and add a\n`bisect-write` subcommand to `git bisect--helper` to call it from\ngit-bisect.sh\n\nUsing `--bisect-write` subcommand is a temporary measure to port shell\nfunction in 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\nNote: bisect_write() uses two variables namely TERM_GOOD and TERM_BAD\nfrom the global shell script thus we need to pass it to the subcommand\nusing the arguments. We then store them in a struct bisect_terms and\npass the memory address around functions.\n\nThis patch also introduces new methods namely bisect_state_init() and\nbisect_terms_release() for easy memory management for the struct\nbisect_terms.\n\nMentored-by: Lars Schneider <larsxschneider@gmail.com>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n---\n builtin/bisect--helper.c | 97 ++++++++++++++++++++++++++++++++++++++++++++----\n git-bisect.sh            | 25 ++-----------\n 2 files changed, 94 insertions(+), 28 deletions(-)\n\ndiff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\nindex 88b5d0a..88a1df8 100644\n--- a/builtin/bisect--helper.c\n+++ b/builtin/bisect--helper.c\n@@ -22,9 +22,27 @@ 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-clean-state\"),\n \tN_(\"git bisect--helper --bisect-reset [<commit>]\"),\n+\tN_(\"git bisect--helper --bisect-write <state> <revision> <TERM_GOOD> <TERM_BAD> [<nolog>]\"),\n \tNULL\n };\n \n+struct bisect_terms {\n+\tstruct strbuf term_good;\n+\tstruct strbuf term_bad;\n+};\n+\n+static void bisect_terms_init(struct bisect_terms *terms)\n+{\n+\tstrbuf_init(&terms->term_good, 0);\n+\tstrbuf_init(&terms->term_bad, 0);\n+}\n+\n+static void bisect_terms_release(struct bisect_terms *terms)\n+{\n+\tstrbuf_release(&terms->term_good);\n+\tstrbuf_release(&terms->term_bad);\n+}\n+\n /*\n  * Check whether the string `term` belongs to the set of strings\n  * included in the variable arguments.\n@@ -188,6 +206,52 @@ static int check_expected_revs(const char **revs, int rev_nr)\n \treturn 0;\n }\n \n+static int bisect_write(const char *state, const char *rev,\n+\t\t\tconst struct bisect_terms *terms, int nolog)\n+{\n+\tstruct strbuf tag = STRBUF_INIT;\n+\tstruct strbuf commit_name = STRBUF_INIT;\n+\tstruct object_id oid;\n+\tstruct commit *commit;\n+\tstruct pretty_print_context pp = {0};\n+\tFILE *fp;\n+\n+\tif (!strcmp(state, terms->term_bad.buf))\n+\t\tstrbuf_addf(&tag, \"refs/bisect/%s\", state);\n+\telse if(one_of(state, terms->term_good.buf, \"skip\", NULL))\n+\t\tstrbuf_addf(&tag, \"refs/bisect/%s-%s\", state, rev);\n+\telse\n+\t\treturn error(_(\"Bad bisect_write argument: %s\"), state);\n+\n+\tif (get_oid(rev, &oid)) {\n+\t\tstrbuf_release(&tag);\n+\t\treturn error(_(\"couldn't get the oid of the rev '%s'\"), rev);\n+\t}\n+\n+\tif (update_ref(NULL, tag.buf, oid.hash, NULL, 0,\n+\t\t       UPDATE_REFS_MSG_ON_ERR)) {\n+\t\tstrbuf_release(&tag);\n+\t\treturn -1;\n+\t}\n+\tstrbuf_release(&tag);\n+\n+\tfp = fopen(git_path_bisect_log(), \"a\");\n+\tif (!fp)\n+\t\treturn error_errno(_(\"couldn't open the file '%s'\"), git_path_bisect_log());\n+\n+\tcommit = lookup_commit_reference(oid.hash);\n+\tformat_commit_message(commit, \"%s\", &commit_name, &pp);\n+\tfprintf(fp, \"# %s: [%s] %s\\n\", state, sha1_to_hex(oid.hash),\n+\t\tcommit_name.buf);\n+\tstrbuf_release(&commit_name);\n+\n+\tif (!nolog)\n+\t\tfprintf(fp, \"git bisect %s %s\\n\", state, rev);\n+\n+\tfclose(fp);\n+\treturn 0;\n+}\n+\n int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n {\n \tenum {\n@@ -195,9 +259,10 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \t\tWRITE_TERMS,\n \t\tBISECT_CLEAN_STATE,\n \t\tBISECT_RESET,\n-\t\tCHECK_EXPECTED_REVS\n+\t\tCHECK_EXPECTED_REVS,\n+\t\tBISECT_WRITE\n \t} cmdmode = 0;\n-\tint no_checkout = 0;\n+\tint no_checkout = 0, res = 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@@ -209,10 +274,14 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \t\t\t N_(\"reset the bisection state\"), BISECT_RESET),\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-write\", &cmdmode,\n+\t\t\t N_(\"write out the bisection state in BISECT_LOG\"), BISECT_WRITE),\n \t\tOPT_BOOL(0, \"no-checkout\", &no_checkout,\n \t\t\t N_(\"update BISECT_HEAD instead of checking out the current commit\")),\n \t\tOPT_END()\n \t};\n+\tstruct bisect_terms terms;\n+\tbisect_terms_init(&terms);\n \n \targc = parse_options(argc, argv, prefix, options,\n \t\t\t     git_bisect_helper_usage, 0);\n@@ -221,24 +290,38 @@ 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+\tint nolog;\n \tcase NEXT_ALL:\n \t\treturn bisect_next_all(prefix, no_checkout);\n \tcase WRITE_TERMS:\n \t\tif (argc != 2)\n \t\t\tdie(_(\"--write-terms requires two arguments\"));\n-\t\treturn write_terms(argv[0], argv[1]);\n+\t\tres = write_terms(argv[0], argv[1]);\n+\t\tbreak;\n \tcase BISECT_CLEAN_STATE:\n \t\tif (argc != 0)\n \t\t\tdie(_(\"--bisect-clean-state requires no arguments\"));\n-\t\treturn bisect_clean_state();\n+\t\tres = bisect_clean_state();\n+\t\tbreak;\n \tcase BISECT_RESET:\n \t\tif (argc > 1)\n \t\t\tdie(_(\"--bisect-reset requires either zero or one arguments\"));\n-\t\treturn bisect_reset(argc ? argv[0] : NULL);\n+\t\tres = bisect_reset(argc ? argv[0] : NULL);\n+\t\tbreak;\n \tcase CHECK_EXPECTED_REVS:\n-\t\treturn check_expected_revs(argv, argc);\n+\t\tres = check_expected_revs(argv, argc);\n+\t\tbreak;\n+\tcase BISECT_WRITE:\n+\t\tif (argc != 4 && argc != 5)\n+\t\t\tdie(_(\"--bisect-write requires either 4 or 5 arguments\"));\n+\t\tnolog = (argc == 5) && !strcmp(argv[4], \"nolog\");\n+\t\tstrbuf_addstr(&terms.term_good, argv[2]);\n+\t\tstrbuf_addstr(&terms.term_bad, argv[3]);\n+\t\tres = bisect_write(argv[0], argv[1], &terms, nolog);\n+\t\tbreak;\n \tdefault:\n \t\tdie(\"BUG: unknown subcommand '%d'\", cmdmode);\n \t}\n-\treturn 0;\n+\tbisect_terms_release(&terms);\n+\treturn res;\n }\ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex 4f6545e..b9896a4 100755\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -145,7 +145,7 @@ bisect_start() {\n \t\t0) state=$TERM_BAD ; bad_seen=1 ;;\n \t\t*) state=$TERM_GOOD ;;\n \t\tesac\n-\t\teval=\"$eval bisect_write '$state' '$rev' 'nolog' &&\"\n+\t\teval=\"$eval git bisect--helper --bisect-write '$state' '$rev' '$TERM_GOOD' '$TERM_BAD' 'nolog' &&\"\n \tdone\n \t#\n \t# Verify HEAD.\n@@ -221,23 +221,6 @@ bisect_start() {\n \ttrap '-' 0\n }\n \n-bisect_write() {\n-\tstate=\"$1\"\n-\trev=\"$2\"\n-\tnolog=\"$3\"\n-\tcase \"$state\" in\n-\t\t\"$TERM_BAD\")\n-\t\t\ttag=\"$state\" ;;\n-\t\t\"$TERM_GOOD\"|skip)\n-\t\t\ttag=\"$state\"-\"$rev\" ;;\n-\t\t*)\n-\t\t\tdie \"$(eval_gettext \"Bad bisect_write argument: \\$state\")\" ;;\n-\tesac\n-\tgit update-ref \"refs/bisect/$tag\" \"$rev\" || exit\n-\techo \"# $state: $(git show-branch $rev)\" >>\"$GIT_DIR/BISECT_LOG\"\n-\ttest -n \"$nolog\" || echo \"git bisect $state $rev\" >>\"$GIT_DIR/BISECT_LOG\"\n-}\n-\n bisect_skip() {\n \tall=''\n \tfor arg in \"$@\"\n@@ -263,7 +246,7 @@ bisect_state() {\n \t1,\"$TERM_BAD\"|1,\"$TERM_GOOD\"|1,skip)\n \t\trev=$(git rev-parse --verify $(bisect_head)) ||\n \t\t\tdie \"$(gettext \"Bad rev input: $(bisect_head)\")\"\n-\t\tbisect_write \"$state\" \"$rev\"\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@@ -276,7 +259,7 @@ bisect_state() {\n \t\tdone\n \t\tfor rev in $hash_list\n \t\tdo\n-\t\t\tbisect_write \"$state\" \"$rev\"\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@@ -413,7 +396,7 @@ bisect_replay () {\n \t\t\tcmd=\"bisect_start $rev\"\n \t\t\teval \"$cmd\" ;;\n \t\t\"$TERM_GOOD\"|\"$TERM_BAD\"|skip)\n-\t\t\tbisect_write \"$command\" \"$rev\" ;;\n+\t\t\tgit bisect--helper --bisect-write \"$command\" \"$rev\" \"$TERM_GOOD\" \"$TERM_BAD\" || exit;;\n \t\tterms)\n \t\t\tbisect_terms $rev ;;\n \t\t*)\n-- \n2.9.0\n\n"},{"id":"291321","messageId":"20160712223538.28508-8-pranit.bauva@gmail.com","threadId":"42831","inReplyTo":"20160712223538.28508-1-pranit.bauva@gmail.com","subject":"[PATCH 7/9] bisect--helper: `bisect_reset` shell function in C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-07-12T22:35:36Z","receivedAt":"2016-07-12T22:41:16Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"Reimplement `bisect_reset` shell function in C and add a `--bisect-reset`\nsubcommand to `git bisect--helper` to call it from git-bisect.sh .\n\nUsing `bisect_reset` subcommand is a temporary measure to port shell\nfunctions to C so as to use the existing test suite. As more functions\nare ported, this subcommand would be retired and will be called by some\nother method.\n\nNote: --bisect-clean-state subcommand has not been retired as there are\nstill a function namely `bisect_start()` which still uses this\nsubcommand.\n\nMentored-by: Lars Schneider <larsxschneider@gmail.com>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n---\n builtin/bisect--helper.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++-\n git-bisect.sh            | 28 ++--------------------------\n 2 files changed, 48 insertions(+), 27 deletions(-)\n\ndiff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\nindex 3089433..636044a 100644\n--- a/builtin/bisect--helper.c\n+++ b/builtin/bisect--helper.c\n@@ -4,6 +4,8 @@\n #include \"bisect.h\"\n #include \"refs.h\"\n #include \"dir.h\"\n+#include \"argv-array.h\"\n+#include \"run-command.h\"\n \n static GIT_PATH_FUNC(git_path_bisect_terms, \"BISECT_TERMS\")\n static GIT_PATH_FUNC(git_path_bisect_expected_rev, \"BISECT_EXPECTED_REV\")\n@@ -13,11 +15,13 @@ static GIT_PATH_FUNC(git_path_bisect_names, \"BISECT_NAMES\")\n static GIT_PATH_FUNC(git_path_bisect_run, \"BISECT_RUN\")\n static GIT_PATH_FUNC(git_path_head_name, \"head-name\")\n static GIT_PATH_FUNC(git_path_bisect_start, \"BISECT_START\")\n+static GIT_PATH_FUNC(git_path_bisect_head, \"BISECT_HEAD\")\n \n static const char * const git_bisect_helper_usage[] = {\n \tN_(\"git bisect--helper --next-all [--no-checkout]\"),\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 \tNULL\n };\n \n@@ -124,12 +128,47 @@ static int bisect_clean_state(void)\n \treturn result;\n }\n \n+static int bisect_reset(const char *commit)\n+{\n+\tstruct strbuf branch = STRBUF_INIT;\n+\n+\tif (!commit) {\n+\t\tif (strbuf_read_file(&branch, git_path_bisect_start(), 0) < 1) {\n+\t\t\tprintf(\"We are not bisecting.\\n\");\n+\t\t\treturn 0;\n+\t\t}\n+\t\tstrbuf_rtrim(&branch);\n+\t} else {\n+\t\tstruct object_id oid;\n+\t\tif (get_oid(commit, &oid))\n+\t\t\treturn error(_(\"'%s' is not a valid commit\"), commit);\n+\t\tstrbuf_addstr(&branch, commit);\n+\t}\n+\n+\tif (!file_exists(git_path_bisect_head())) {\n+\t\tstruct argv_array argv = ARGV_ARRAY_INIT;\n+\t\targv_array_pushl(&argv, \"checkout\", branch.buf, \"--\", NULL);\n+\t\tif (run_command_v_opt(argv.argv, RUN_GIT_CMD)) {\n+\t\t\terror(_(\"Could not check out original HEAD '%s'. Try\"\n+\t\t\t\t\"'git bisect reset <commit>'.\"), branch.buf);\n+\t\t\tstrbuf_release(&branch);\n+\t\t\targv_array_clear(&argv);\n+\t\t\treturn -1;\n+\t\t}\n+\t\targv_array_clear(&argv);\n+\t}\n+\n+\tstrbuf_release(&branch);\n+\treturn bisect_clean_state();\n+}\n+\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\tBISECT_CLEAN_STATE\n+\t\tBISECT_CLEAN_STATE,\n+\t\tBISECT_RESET\n \t} cmdmode = 0;\n \tint no_checkout = 0;\n \tstruct option options[] = {\n@@ -139,6 +178,8 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\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, \"bisect-reset\", &cmdmode,\n+\t\t\t N_(\"reset the bisection state\"), BISECT_RESET),\n \t\tOPT_BOOL(0, \"no-checkout\", &no_checkout,\n \t\t\t N_(\"update BISECT_HEAD instead of checking out the current commit\")),\n \t\tOPT_END()\n@@ -161,6 +202,10 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \t\tif (argc != 0)\n \t\t\tdie(_(\"--bisect-clean-state requires no arguments\"));\n \t\treturn bisect_clean_state();\n+\tcase BISECT_RESET:\n+\t\tif (argc > 1)\n+\t\t\tdie(_(\"--bisect-reset requires either zero or one arguments\"));\n+\t\treturn bisect_reset(argc ? argv[0] : NULL);\n \tdefault:\n \t\tdie(\"BUG: unknown subcommand '%d'\", cmdmode);\n \t}\ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex bbc57d2..18580b7 100755\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -409,35 +409,11 @@ bisect_visualize() {\n \teval '\"$@\"' --bisect -- $(cat \"$GIT_DIR/BISECT_NAMES\")\n }\n \n-bisect_reset() {\n-\ttest -s \"$GIT_DIR/BISECT_START\" || {\n-\t\tgettextln \"We are not bisecting.\"\n-\t\treturn\n-\t}\n-\tcase \"$#\" in\n-\t0) branch=$(cat \"$GIT_DIR/BISECT_START\") ;;\n-\t1) git rev-parse --quiet --verify \"$1^{commit}\" >/dev/null || {\n-\t\t\tinvalid=\"$1\"\n-\t\t\tdie \"$(eval_gettext \"'\\$invalid' is not a valid commit\")\"\n-\t\t}\n-\t\tbranch=\"$1\" ;;\n-\t*)\n-\t\tusage ;;\n-\tesac\n-\n-\tif ! test -f \"$GIT_DIR/BISECT_HEAD\" && ! git checkout \"$branch\" --\n-\tthen\n-\t\tdie \"$(eval_gettext \"Could not check out original HEAD '\\$branch'.\n-Try 'git bisect reset <commit>'.\")\"\n-\tfi\n-\tgit bisect--helper --bisect-clean-state || exit\n-}\n-\n bisect_replay () {\n \tfile=\"$1\"\n \ttest \"$#\" -eq 1 || die \"$(gettext \"No logfile given\")\"\n \ttest -r \"$file\" || die \"$(eval_gettext \"cannot read \\$file for replaying\")\"\n-\tbisect_reset\n+\tgit bisect--helper --bisect-reset || exit\n \twhile read git bisect command rev\n \tdo\n \t\ttest \"$git $bisect\" = \"git bisect\" || test \"$git\" = \"git-bisect\" || continue\n@@ -627,7 +603,7 @@ case \"$#\" in\n \tvisualize|view)\n \t\tbisect_visualize \"$@\" ;;\n \treset)\n-\t\tbisect_reset \"$@\" ;;\n+\t\tgit bisect--helper --bisect-reset \"$@\" ;;\n \treplay)\n \t\tbisect_replay \"$@\" ;;\n \tlog)\n-- \n2.9.0\n\n"},{"id":"291322","messageId":"20160712223538.28508-9-pranit.bauva@gmail.com","threadId":"42831","inReplyTo":"20160712223538.28508-1-pranit.bauva@gmail.com","subject":"[PATCH 8/9] bisect--helper: `is_expected_rev` & `check_expected_revs` shell function in C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-07-12T22:35:37Z","receivedAt":"2016-07-12T22:41:17Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"Reimplement `is_expected_rev` & `check_expected_revs` shell function in\nC and add a `--check-expected-revs` subcommand to `git bisect--helper` to\ncall it from git-bisect.sh .\n\nUsing `--check-expected-revs` subcommand is a temporary measure to port\nshell functions to C so as to use the existing test suite. As more\nfunctions are ported, this subcommand would be retired and will be\ncalled by some other method.\n\nHelped-by: Eric Sunshine <sunshine@sunshineco.com>\nMentored-by: Lars Schneider <larsxschneider@gmail.com>\nMentored-by: Christian Couder <chriscool@tuxfamily.org>\nSigned-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n---\n builtin/bisect--helper.c | 33 ++++++++++++++++++++++++++++++++-\n git-bisect.sh            | 20 ++------------------\n 2 files changed, 34 insertions(+), 19 deletions(-)\n\ndiff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\nindex 636044a..88b5d0a 100644\n--- a/builtin/bisect--helper.c\n+++ b/builtin/bisect--helper.c\n@@ -162,13 +162,40 @@ static int bisect_reset(const char *commit)\n \treturn bisect_clean_state();\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) >= 0) {\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 int 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\tremove_path(git_path_bisect_ancestors_ok());\n+\t\t\tremove_path(git_path_bisect_expected_rev());\n+\t\t\treturn 0;\n+\t\t}\n+\t}\n+\treturn 0;\n+}\n+\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\tBISECT_CLEAN_STATE,\n-\t\tBISECT_RESET\n+\t\tBISECT_RESET,\n+\t\tCHECK_EXPECTED_REVS\n \t} cmdmode = 0;\n \tint no_checkout = 0;\n \tstruct option options[] = {\n@@ -180,6 +207,8 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \t\t\t N_(\"cleanup the bisection state\"), BISECT_CLEAN_STATE),\n \t\tOPT_CMDMODE(0, \"bisect-reset\", &cmdmode,\n \t\t\t N_(\"reset the bisection state\"), BISECT_RESET),\n+\t\tOPT_CMDMODE(0, \"check-expected-revs\", &cmdmode,\n+\t\t\t N_(\"check for expected revs\"), CHECK_EXPECTED_REVS),\n \t\tOPT_BOOL(0, \"no-checkout\", &no_checkout,\n \t\t\t N_(\"update BISECT_HEAD instead of checking out the current commit\")),\n \t\tOPT_END()\n@@ -206,6 +235,8 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \t\tif (argc > 1)\n \t\t\tdie(_(\"--bisect-reset requires either zero or one arguments\"));\n \t\treturn bisect_reset(argc ? argv[0] : NULL);\n+\tcase CHECK_EXPECTED_REVS:\n+\t\treturn check_expected_revs(argv, argc);\n \tdefault:\n \t\tdie(\"BUG: unknown subcommand '%d'\", cmdmode);\n \t}\ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex 18580b7..4f6545e 100755\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -238,22 +238,6 @@ bisect_write() {\n \ttest -n \"$nolog\" || echo \"git bisect $state $rev\" >>\"$GIT_DIR/BISECT_LOG\"\n }\n \n-is_expected_rev() {\n-\ttest -f \"$GIT_DIR/BISECT_EXPECTED_REV\" &&\n-\ttest \"$1\" = $(cat \"$GIT_DIR/BISECT_EXPECTED_REV\")\n-}\n-\n-check_expected_revs() {\n-\tfor _rev in \"$@\"; do\n-\t\tif ! is_expected_rev \"$_rev\"\n-\t\tthen\n-\t\t\trm -f \"$GIT_DIR/BISECT_ANCESTORS_OK\"\n-\t\t\trm -f \"$GIT_DIR/BISECT_EXPECTED_REV\"\n-\t\t\treturn\n-\t\tfi\n-\tdone\n-}\n-\n bisect_skip() {\n \tall=''\n \tfor arg in \"$@\"\n@@ -280,7 +264,7 @@ bisect_state() {\n \t\trev=$(git rev-parse --verify $(bisect_head)) ||\n \t\t\tdie \"$(gettext \"Bad rev input: $(bisect_head)\")\"\n \t\tbisect_write \"$state\" \"$rev\"\n-\t\tcheck_expected_revs \"$rev\" ;;\n+\t\tgit bisect--helper --check-expected-revs \"$rev\" ;;\n \t2,\"$TERM_BAD\"|*,\"$TERM_GOOD\"|*,skip)\n \t\tshift\n \t\thash_list=''\n@@ -294,7 +278,7 @@ bisect_state() {\n \t\tdo\n \t\t\tbisect_write \"$state\" \"$rev\"\n \t\tdone\n-\t\tcheck_expected_revs $hash_list ;;\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-- \n2.9.0\n\n"},{"id":"291330","messageId":"CAP8UFD0T3+BEq2JO_zA8-n1322VP=EUxOfmP3U5i-4jQJ6WtUA@mail.gmail.com","threadId":"42831","inReplyTo":"20160712223538.28508-1-pranit.bauva@gmail.com","subject":"Re: [PATCH 0/9] Resend of gitster/pb/bisect","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-07-13T07:47:20Z","receivedAt":"2016-07-13T07:48:01Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Hi Pranit,\n\nOn Wed, Jul 13, 2016 at 12:35 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n> Hey Junio,\n>\n> A small mistake got unnoticed by me which Lars recently pointed out.\n> The naming convention is \"git_path_<name_of_file>\" and underscore\n> instead of spaces.\n\nIt's a good thing to resend when you find mistakes, but please use a\nversion number for your patch series (like \"PATCH v3\" or something).\n\nThanks,\nChristian.\n"},{"id":"291827","messageId":"CAFZEwPMLSW59qUjDXCe6BEz=_e7F79GbPNp0v7nDM2e3q_Kkug@mail.gmail.com","threadId":"42831","inReplyTo":"20160712223538.28508-1-pranit.bauva@gmail.com","subject":"Re: [PATCH 0/9] Resend of gitster/pb/bisect","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-07-20T16:00:13Z","receivedAt":"2016-07-20T16:00:20Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"On Wed, Jul 13, 2016 at 4:05 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n> Hey Junio,\n>\n> A small mistake got unnoticed by me which Lars recently pointed out.\n> The naming convention is \"git_path_<name_of_file>\" and underscore\n> instead of spaces.\n>\n> Thanks!\n>\n> The interdiff is:\n> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\n> index c2f3cee..88a1df8 100644\n> --- a/builtin/bisect--helper.c\n> +++ b/builtin/bisect--helper.c\n> @@ -7,7 +7,7 @@\n>  #include \"argv-array.h\"\n>  #include \"run-command.h\"\n>\n> -static GIT_PATH_FUNC(git_path_bisect_write_terms, \"BISECT_TERMS\")\n> +static GIT_PATH_FUNC(git_path_bisect_terms, \"BISECT_TERMS\")\n>  static GIT_PATH_FUNC(git_path_bisect_expected_rev, \"BISECT_EXPECTED_REV\")\n>  static GIT_PATH_FUNC(git_path_bisect_ancestors_ok, \"BISECT_ANCESTORS_OK\")\n>  static GIT_PATH_FUNC(git_path_bisect_log, \"BISECT_LOG\")\n> @@ -100,7 +100,7 @@ static int write_terms(const char *bad, const char *good)\n>         if (check_term_format(bad, \"bad\") || check_term_format(good, \"good\"))\n>                 return -1;\n>\n> -       fp = fopen(git_path_bisect_write_terms(), \"w\");\n> +       fp = fopen(git_path_bisect_terms(), \"w\");\n>         if (!fp)\n>                 return error_errno(_(\"could not open the file BISECT_TERMS\"));\n>\n> @@ -134,7 +134,7 @@ static int bisect_clean_state(void)\n>         remove_path(git_path_bisect_log());\n>         remove_path(git_path_bisect_names());\n>         remove_path(git_path_bisect_run());\n> -       remove_path(git_path_bisect_write_terms());\n> +       remove_path(git_path_bisect_terms());\n>         /* Cleanup head-name if it got left by an old version of git-bisect */\n>         remove_path(git_path_head_name());\n>         /*\n>\n>\n> Pranit Bauva (9):\n>   bisect--helper: use OPT_CMDMODE instead of OPT_BOOL\n>   bisect: rewrite `check_term_format` shell function in C\n>   bisect--helper: `write_terms` shell function in C\n>   bisect--helper: `bisect_clean_state` shell function in C\n>   t6030: explicitly test for bisection cleanup\n>   wrapper: move is_empty_file() and rename it as\n>     is_empty_or_missing_file()\n>   bisect--helper: `bisect_reset` shell function in C\n>   bisect--helper: `is_expected_rev` & `check_expected_revs` shell\n>     function in C\n>   bisect--helper: `bisect_write` shell function in C\n>\n>  builtin/am.c                |  20 +--\n>  builtin/bisect--helper.c    | 310 +++++++++++++++++++++++++++++++++++++++++++-\n>  cache.h                     |   3 +\n>  git-bisect.sh               | 146 +++------------------\n>  t/t6030-bisect-porcelain.sh |  17 +++\n>  wrapper.c                   |  13 ++\n>  6 files changed, 355 insertions(+), 154 deletions(-)\n\nCould someone please look into this series and review so that Junio\ncan merge this into next which is a vital part of my GSoC project?\n\nRegards,\nPranit Bauva\n"}]}