{"thread":{"id":"41774","subject":"[PATCH] bisect--helper: convert a function in shell to C","startedAt":"2016-03-21T19:00:56Z","lastAt":"2016-06-17T12:48:53Z","messageCount":110,"participants":["Pranit Bauva","Stefan Beller","Christian Couder","Johannes Schindelin","Junio C Hamano","Eric Sunshine","Lars Schneider"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"281400","messageId":"010201539a8d2b8a-9f168d7a-d4c6-4c23-a61f-1ef6ee22f774-000000@eu-west-1.amazonses.com","threadId":"41774","inReplyTo":null,"subject":"[PATCH] bisect--helper: convert a function in shell to C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-03-21T19:00:56Z","receivedAt":"2016-03-21T19:00:56Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"Convert the code literally without changing its design even though it\nseems that its obscure as to the use of comparing revision to different bisect\narguments which seems like a problem in shell because of the way\nfunction arguments are handled.\n\nSigned-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n---\n builtin/bisect--helper.c | 23 +++++++++++++++++++++++\n 1 file changed, 23 insertions(+)\n\ndiff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\nindex 3324229..61abe68 100644\n--- a/builtin/bisect--helper.c\n+++ b/builtin/bisect--helper.c\n@@ -2,12 +2,35 @@\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 \tNULL\n };\n \n+static int check_term_format(const char *term, const char *revision, int flag) {\n+\tif (check_refname_format(term, flag))\n+\t\tdie(\"'%s' is not a valid term\", term);\n+\n+\tif (!strcmp(term, \"help\") || !strcmp(term, \"start\") ||\n+\t\t!strcmp(term, \"skip\") || !strcmp(term, \"next\") ||\n+\t\t!strcmp(term, \"reset\") || !strcmp(term, \"visualize\") ||\n+\t\t!strcmp(term, \"replay\") || !strcmp(term, \"log\") ||\n+\t\t!strcmp(term, \"run\"))\n+\t\tdie(\"can't use the builtin command '%s' as a term\", term);\n+\n+\tif (!strcmp(term, \"bad\") || !strcmp(term, \"new\"))\n+\t\tif(strcmp(revision, \"bad\"))\n+\t\t\tdie(\"can't change the meaning of term '%s'\", term);\n+\n+\tif (!strcmp(term, \"good\") || !strcmp(term, \"old\"))\n+\t\tif (strcmp(revision, \"good\"))\n+\t\t\tdie(\"can't change the meaning of term '%s'\", term);\n+\n+\treturn 1;\n+}\n+\n int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n {\n \tint next_all = 0;\n\n--\nhttps://github.com/git/git/pull/216\n"},{"id":"281401","messageId":"CAGZ79kZveu07h_vERFpJekp4ayJwytwoNVG0LbhiaCnt4u-jRw@mail.gmail.com","threadId":"41774","inReplyTo":"010201539a8d2b8a-9f168d7a-d4c6-4c23-a61f-1ef6ee22f774-000000@eu-west-1.amazonses.com","subject":"Re: [PATCH] bisect--helper: convert a function in shell to C","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2016-03-22T00:28:56Z","receivedAt":"2016-03-22T00:28:56Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Mon, Mar 21, 2016 at 12:00 PM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n> Convert the code literally without changing its design even though it\n> seems that its obscure as to the use of comparing revision to different bisect\n> arguments which seems like a problem in shell because of the way\n> function arguments are handled.\n\nHow would I use the C version instead of the shell version now?\nI'd imagine you'd want to change calls in git-bisect.sh from\n    check_term_format <term> <bad/new>\nto be:\n    git bisect--helper check_term_format <term> <bad/new>\nand \"git bisect--helper\" would then call the new static method?\nOnce you have the C version working (do we need additional tests\nor can we rely on the test suite being enough for now?),\nyou can also delete the shell version.\n\nThanks,\nStefan\n\n>\n> Signed-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n> ---\n>  builtin/bisect--helper.c | 23 +++++++++++++++++++++++\n>  1 file changed, 23 insertions(+)\n>\n> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\n> index 3324229..61abe68 100644\n> --- a/builtin/bisect--helper.c\n> +++ b/builtin/bisect--helper.c\n> @@ -2,12 +2,35 @@\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>         N_(\"git bisect--helper --next-all [--no-checkout]\"),\n>         NULL\n>  };\n>\n> +static int check_term_format(const char *term, const char *revision, int flag) {\n> +       if (check_refname_format(term, flag))\n> +               die(\"'%s' is not a valid term\", term);\n> +\n> +       if (!strcmp(term, \"help\") || !strcmp(term, \"start\") ||\n> +               !strcmp(term, \"skip\") || !strcmp(term, \"next\") ||\n> +               !strcmp(term, \"reset\") || !strcmp(term, \"visualize\") ||\n> +               !strcmp(term, \"replay\") || !strcmp(term, \"log\") ||\n> +               !strcmp(term, \"run\"))\n> +               die(\"can't use the builtin command '%s' as a term\", term);\n\n\"terms\" is missing?\n\neval_gettext would translate into C as\n    die (_(\"translatable message\"));\n\n\n> +\n> +       if (!strcmp(term, \"bad\") || !strcmp(term, \"new\"))\n> +               if(strcmp(revision, \"bad\"))\n> +                       die(\"can't change the meaning of term '%s'\", term);\n> +\n> +       if (!strcmp(term, \"good\") || !strcmp(term, \"old\"))\n> +               if (strcmp(revision, \"good\"))\n> +                       die(\"can't change the meaning of term '%s'\", term);\n> +\n> +       return 1;\n\nWhy 1? Usually we use 0 for success in C. die(...) returns with non zero,\nso having 0 here would help us in the shell code to see if the C version\ndied (or not).\n\n> +}\n> +\n>  int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>  {\n>         int next_all = 0;\n>\n> --\n> https://github.com/git/git/pull/216\n> --\n> To unsubscribe from this list: send the line \"unsubscribe git\" in\n> the body of a message to majordomo@vger.kernel.org\n> More majordomo info at  http://vger.kernel.org/majordomo-info.html\n"},{"id":"281411","messageId":"CAP8UFD0tSffjJJ-kDdN6aWC6bTP3LJWjtAAFP-1s0qVH_wVx1g@mail.gmail.com","threadId":"41774","inReplyTo":"CAGZ79kZveu07h_vERFpJekp4ayJwytwoNVG0LbhiaCnt4u-jRw@mail.gmail.com","subject":"Re: [PATCH] bisect--helper: convert a function in shell to C","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-03-22T06:10:37Z","receivedAt":"2016-03-22T06:10:37Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Tue, Mar 22, 2016 at 1:28 AM, Stefan Beller <sbeller@google.com> wrote:\n> On Mon, Mar 21, 2016 at 12:00 PM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>> Convert the code literally without changing its design even though it\n>> seems that its obscure as to the use of comparing revision to different bisect\n>> arguments which seems like a problem in shell because of the way\n>> function arguments are handled.\n>\n> How would I use the C version instead of the shell version now?\n\nHint: one can look at how other functions in builtin/bisect--helper.c are used.\n\n> I'd imagine you'd want to change calls in git-bisect.sh from\n>     check_term_format <term> <bad/new>\n> to be:\n>     git bisect--helper check_term_format <term> <bad/new>\n\nHint: to get a good idea of how the call should be, one can look at\nthe way \"git-bisect.sh\" already calls \"git bisect--helper\".\n\n> and \"git bisect--helper\" would then call the new static method?\n> Once you have the C version working (do we need additional tests\n> or can we rely on the test suite being enough for now?),\n> you can also delete the shell version.\n"},{"id":"281412","messageId":"CAFZEwPOx-ixKn63Mt9tuF3XWhgY2aztVRESrDJOQK8Q5jGG2CQ@mail.gmail.com","threadId":"41774","inReplyTo":"CAGZ79kZveu07h_vERFpJekp4ayJwytwoNVG0LbhiaCnt4u-jRw@mail.gmail.com","subject":"Re: [PATCH] bisect--helper: convert a function in shell to C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-03-22T06:13:10Z","receivedAt":"2016-03-22T06:13:10Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"On Tue, Mar 22, 2016 at 5:58 AM, Stefan Beller <sbeller@google.com> wrote:\n> On Mon, Mar 21, 2016 at 12:00 PM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>> Convert the code literally without changing its design even though it\n>> seems that its obscure as to the use of comparing revision to different bisect\n>> arguments which seems like a problem in shell because of the way\n>> function arguments are handled.\n>\n> How would I use the C version instead of the shell version now?\n> I'd imagine you'd want to change calls in git-bisect.sh from\n>     check_term_format <term> <bad/new>\n> to be:\n>     git bisect--helper check_term_format <term> <bad/new>\n> and \"git bisect--helper\" would then call the new static method?\n> Once you have the C version working (do we need additional tests\n> or can we rely on the test suite being enough for now?),\n> you can also delete the shell version.\n\nI have to yet think about this. Currently, I just called this function\nfrom cmd_bisect__helper().\n\n> Thanks,\n> Stefan\n>\n>>\n>> Signed-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n>> ---\n>>  builtin/bisect--helper.c | 23 +++++++++++++++++++++++\n>>  1 file changed, 23 insertions(+)\n>>\n>> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\n>> index 3324229..61abe68 100644\n>> --- a/builtin/bisect--helper.c\n>> +++ b/builtin/bisect--helper.c\n>> @@ -2,12 +2,35 @@\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>>         N_(\"git bisect--helper --next-all [--no-checkout]\"),\n>>         NULL\n>>  };\n>>\n>> +static int check_term_format(const char *term, const char *revision, int flag) {\n>> +       if (check_refname_format(term, flag))\n>> +               die(\"'%s' is not a valid term\", term);\n>> +\n>> +       if (!strcmp(term, \"help\") || !strcmp(term, \"start\") ||\n>> +               !strcmp(term, \"skip\") || !strcmp(term, \"next\") ||\n>> +               !strcmp(term, \"reset\") || !strcmp(term, \"visualize\") ||\n>> +               !strcmp(term, \"replay\") || !strcmp(term, \"log\") ||\n>> +               !strcmp(term, \"run\"))\n>> +               die(\"can't use the builtin command '%s' as a term\", term);\n>\n> \"terms\" is missing?\n>\n> eval_gettext would translate into C as\n>     die (_(\"translatable message\"));\n>\n>\n>> +\n>> +       if (!strcmp(term, \"bad\") || !strcmp(term, \"new\"))\n>> +               if(strcmp(revision, \"bad\"))\n>> +                       die(\"can't change the meaning of term '%s'\", term);\n>> +\n>> +       if (!strcmp(term, \"good\") || !strcmp(term, \"old\"))\n>> +               if (strcmp(revision, \"good\"))\n>> +                       die(\"can't change the meaning of term '%s'\", term);\n>> +\n>> +       return 1;\n>\n> Why 1? Usually we use 0 for success in C. die(...) returns with non zero,\n> so having 0 here would help us in the shell code to see if the C version\n> died (or not).\n\nSorry I forgot to change the value. I had initially kept it to 0 but\nthen to do some tweaks, I changed it to 1. I had to do manual tweaks\nas I am still scared to use gdb for big projects. I am trying to get\nmore comfortable with it. Also reading the patch again, I seem to have\nforgotten the function declaration statement also.\n\n[1] : http://thread.gmane.org/gmane.comp.version-control.git/289299/focus=289364\n"},{"id":"281413","messageId":"CAFZEwPPh4tru85Lr=8tSZALqPjUrrNsyQvquMhcHjjAsE7REZQ@mail.gmail.com","threadId":"41774","inReplyTo":"CAP8UFD0tSffjJJ-kDdN6aWC6bTP3LJWjtAAFP-1s0qVH_wVx1g@mail.gmail.com","subject":"Re: [PATCH] bisect--helper: convert a function in shell to C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-03-22T06:13:43Z","receivedAt":"2016-03-22T06:13:43Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"On Tue, Mar 22, 2016 at 11:40 AM, Christian Couder\n<christian.couder@gmail.com> wrote:\n> On Tue, Mar 22, 2016 at 1:28 AM, Stefan Beller <sbeller@google.com> wrote:\n>> On Mon, Mar 21, 2016 at 12:00 PM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>>> Convert the code literally without changing its design even though it\n>>> seems that its obscure as to the use of comparing revision to different bisect\n>>> arguments which seems like a problem in shell because of the way\n>>> function arguments are handled.\n>>\n>> How would I use the C version instead of the shell version now?\n>\n> Hint: one can look at how other functions in builtin/bisect--helper.c are used.\n>\n>> I'd imagine you'd want to change calls in git-bisect.sh from\n>>     check_term_format <term> <bad/new>\n>> to be:\n>>     git bisect--helper check_term_format <term> <bad/new>\n>\n> Hint: to get a good idea of how the call should be, one can look at\n> the way \"git-bisect.sh\" already calls \"git bisect--helper\".\n>\n>> and \"git bisect--helper\" would then call the new static method?\n>> Once you have the C version working (do we need additional tests\n>> or can we rely on the test suite being enough for now?),\n>> you can also delete the shell version.\n\nThanks a lot! I will dig more into this.\n"},{"id":"281417","messageId":"010201539d57ae98-ce4860a6-f7b6-4e06-b556-3c1340cd7749-000000@eu-west-1.amazonses.com","threadId":"41774","inReplyTo":"010201539a8d2b8a-9f168d7a-d4c6-4c23-a61f-1ef6ee22f774-000000@eu-west-1.amazonses.com","subject":"[PATCH v2] bisect--helper: convert a function in shell to C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-03-22T08:01:22Z","receivedAt":"2016-03-22T08:01:22Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"Convert the code literally without changing its design even though it\nseems that its obscure as to the use of comparing revision to different\nbisect arguments which seems like a problem in shell because of the way\nfunction arguments are handled.\n\nThe argument handling is kind of hard coded right now because it is not\nreally be meant to be used like this and this is just for testing\npurposes whether this new method is as functional as its counter part.\nThe shell counter part of the method has been retained for historical\npurposes.\n\nSigned-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n---\n builtin/bisect--helper.c | 37 +++++++++++++++++++++++++++++++++++++\n git-bisect.sh            |  4 ++--\n 2 files changed, 39 insertions(+), 2 deletions(-)\n\ndiff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\nindex 3324229..6cdae82 100644\n--- a/builtin/bisect--helper.c\n+++ b/builtin/bisect--helper.c\n@@ -2,27 +2,64 @@\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> <revision>\"),\n \tNULL\n };\n \n+static int check_term_format(const char *term, const char *revision, int flags);\n+\n+static int check_term_format(const char *term, const char *revision, int flag) {\n+\tif (check_refname_format(term, flag))\n+\t\tdie(\"'%s' is not a valid term\", term);\n+\n+\tif (!strcmp(term, \"help\") || !strcmp(term, \"start\") ||\n+\t\t!strcmp(term, \"skip\") || !strcmp(term, \"next\") ||\n+\t\t!strcmp(term, \"reset\") || !strcmp(term, \"visualize\") ||\n+\t\t!strcmp(term, \"replay\") || !strcmp(term, \"log\") ||\n+\t\t!strcmp(term, \"run\"))\n+\t\tdie(\"can't use the builtin command '%s' as a term\", term);\n+\n+\tif (!strcmp(term, \"bad\") || !strcmp(term, \"new\"))\n+\t\tif(strcmp(revision, \"bad\"))\n+\t\t\tdie(\"can't change the meaning of term '%s'\", term);\n+\n+\tif (!strcmp(term, \"good\") || !strcmp(term, \"old\"))\n+\t\tif (strcmp(revision, \"good\"))\n+\t\t\tdie(\"can't change the meaning of term '%s'\", term);\n+\n+\treturn 0;\n+}\n+\n int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n {\n \tint next_all = 0;\n \tint no_checkout = 0;\n+\tconst char *term;\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_BOOL(0, \"no-checkout\", &no_checkout,\n \t\t\t N_(\"update BISECT_HEAD instead of checking out the current commit\")),\n+\t\tOPT_STRING(0, \"check-term-format\", &term, N_(\"term\"),\n+\t\t\t N_(\"check the format of the ref\")),\n \t\tOPT_END()\n \t};\n \n \targc = parse_options(argc, argv, prefix, options,\n \t\t\t     git_bisect_helper_usage, 0);\n \n+\n+\tif (term != NULL) {\n+\t\tif (argc > 0)\n+\t\t\treturn check_term_format(term, argv[0], 0);\n+\t\telse\n+\t\t\tdie(\"no revision provided with check_for_term\");\n+\t}\n+\n \tif (!next_all)\n \t\tusage_with_options(git_bisect_helper_usage, options);\n \ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex 5d1cb00..ea237be 100755\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -564,8 +564,8 @@ 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\n+\tgit bisect--helper --check-term-format=\"$TERM_GOOD\" good\n \tprintf '%s\\n%s\\n' \"$TERM_BAD\" \"$TERM_GOOD\" >\"$GIT_DIR/BISECT_TERMS\"\n }\n \n\n--\nhttps://github.com/git/git/pull/216\n"},{"id":"281431","messageId":"alpine.DEB.2.20.1603221552100.4690@virtualbox","threadId":"41774","inReplyTo":"010201539d57ae98-ce4860a6-f7b6-4e06-b556-3c1340cd7749-000000@eu-west-1.amazonses.com","subject":"Re: [PATCH v2] bisect--helper: convert a function in shell to C","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-03-22T15:09:56Z","receivedAt":"2016-03-22T15:09:56Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Tue, 22 Mar 2016, Pranit Bauva wrote:\n\n> Convert the code literally without changing its design even though it\n> seems that its obscure as to the use of comparing revision to different\n\ns/its/it is/\n\n> bisect arguments which seems like a problem in shell because of the way\n> function arguments are handled.\n\nI agree that it is obscure. That is why I would suggest to fix it during\nthe conversion. Using 'new_term' and 'orig_term' (or something similar)\nwould make much more sense.\n\nAnother good idea would be to include the shell code, or at least to\nprovide a link such as:\n\n\thttps://github.com/git/git/blob/v2.8.0-rc4/git-bisect.sh#L572-L597\n\n> The argument handling is kind of hard coded right now because it is not\n> really be meant to be used like this and this is just for testing\n> purposes whether this new method is as functional as its counter part.\n> The shell counter part of the method has been retained for historical\n> purposes.\n\nStill, it would make more sense (both in terms of readability and in terms\nof code safety) to introduce and use a function like\n\nstatic int one_of(const char *term, ...)\n{\n\tva_list matches;\n\tconst char *match;\n\n\tva_start(matches, term);\n\twhile ((match = va_arg(matches, const char *)))\n\t\tif (!strcmp(term, match))\n\t\t\treturn 1;\n\tva_end(matches);\n\n\treturn 0;\n}\n\n> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\n> index 3324229..6cdae82 100644\n> --- a/builtin/bisect--helper.c\n> +++ b/builtin/bisect--helper.c\n> @@ -2,27 +2,64 @@\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> <revision>\"),\n\nGood. This imitates the existing code.\n\n>  \tNULL\n>  };\n>  \n> +static int check_term_format(const char *term, const char *revision, int flags);\n> +\n> +static int check_term_format(const char *term, const char *revision, int flag) {\n\nSince you define the check_term_format() function here, the declaration\nabove is unnecessary. Let's just delete it.\n\n> +\tif (check_refname_format(term, flag))\n> +\t\tdie(\"'%s' is not a valid term\", term);\n> +\n> +\tif (!strcmp(term, \"help\") || !strcmp(term, \"start\") ||\n> +\t\t!strcmp(term, \"skip\") || !strcmp(term, \"next\") ||\n> +\t\t!strcmp(term, \"reset\") || !strcmp(term, \"visualize\") ||\n> +\t\t!strcmp(term, \"replay\") || !strcmp(term, \"log\") ||\n> +\t\t!strcmp(term, \"run\"))\n> +\t\tdie(\"can't use the builtin command '%s' as a term\", term);\n\nThis would look so much nicer using the one_of() function above.\n\nPlease also note that our coding convention (as can be seen from the\nexisting code in builtin/*.c) is to indent the condition differently than\nthe block, either using an extra tab, or by using 4 spaces instead of the\ntab.\n\n> +\tif (!strcmp(term, \"bad\") || !strcmp(term, \"new\"))\n> +\t\tif(strcmp(revision, \"bad\"))\n> +\t\t\tdie(\"can't change the meaning of term '%s'\", term);\n> +\n> +\tif (!strcmp(term, \"good\") || !strcmp(term, \"old\"))\n> +\t\tif (strcmp(revision, \"good\"))\n> +\t\t\tdie(\"can't change the meaning of term '%s'\", term);\n\nThese two can be combined. Actually, these *four* can easily be combined:\n\n\tif ((one_of(term, \"bad\", \"new\", NULL) && strcmp(orig, \"bad\")) ||\n\t    (one_of(term, \"good\", \"old\", NULL) && strcmp(orig, \"good\")))\n\t\tdie(\"can't change the meaning of term '%s'\", term);\n\n>  int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>  {\n>  \tint next_all = 0;\n>  \tint no_checkout = 0;\n> +\tconst char *term;\n\nBetter use the existing convention:\n\n\tint check_term_format = 0;\n\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_BOOL(0, \"no-checkout\", &no_checkout,\n>  \t\t\t N_(\"update BISECT_HEAD instead of checking out the current commit\")),\n> +\t\tOPT_STRING(0, \"check-term-format\", &term, N_(\"term\"),\n> +\t\t\t N_(\"check the format of the ref\")),\n\nHmm. The existing code suggests to use OPT_BOOL instead.\n\n>  \t\tOPT_END()\n>  \t};\n>  \n>  \targc = parse_options(argc, argv, prefix, options,\n>  \t\t\t     git_bisect_helper_usage, 0);\n>  \n> +\n> +\tif (term != NULL) {\n> +\t\tif (argc > 0)\n\nHere you need to test for a precise argc, not for a range.\n\n> +\t\t\treturn check_term_format(term, argv[0], 0);\n> +\t\telse\n> +\t\t\tdie(\"no revision provided with check_for_term\");\n> +\t}\n> +\n>  \tif (!next_all)\n>  \t\tusage_with_options(git_bisect_helper_usage, options);\n>  \n> diff --git a/git-bisect.sh b/git-bisect.sh\n> index 5d1cb00..ea237be 100755\n> --- a/git-bisect.sh\n> +++ b/git-bisect.sh\n> @@ -564,8 +564,8 @@ 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\n> +\tgit bisect--helper --check-term-format=\"$TERM_GOOD\" good\n\nThe existing convention is to make the first argument *not* a value of the\n\"option\", i.e. `--check-term-format \"$TERM_BAD\"` without an equal sign.\n\nDid you also run the test suite after compiling, to verify that the\ndocumented expectations are still met after the conversion?\n\nCiao,\nJohannes\n"},{"id":"281432","messageId":"alpine.DEB.2.20.1603221610370.4690@virtualbox","threadId":"41774","inReplyTo":"alpine.DEB.2.20.1603221552100.4690@virtualbox","subject":"Re: [PATCH v2] bisect--helper: convert a function in shell to C","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-03-22T15:11:33Z","receivedAt":"2016-03-22T15:11:33Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Tue, 22 Mar 2016, Johannes Schindelin wrote:\n\n> On Tue, 22 Mar 2016, Pranit Bauva wrote:\n> \n> > +\tif (!strcmp(term, \"bad\") || !strcmp(term, \"new\"))\n> > +\t\tif(strcmp(revision, \"bad\"))\n> > +\t\t\tdie(\"can't change the meaning of term '%s'\", term);\n> > +\n> > +\tif (!strcmp(term, \"good\") || !strcmp(term, \"old\"))\n> > +\t\tif (strcmp(revision, \"good\"))\n> > +\t\t\tdie(\"can't change the meaning of term '%s'\", term);\n> \n> These two can be combined. Actually, these *four* can easily be combined:\n> \n> \tif ((one_of(term, \"bad\", \"new\", NULL) && strcmp(orig, \"bad\")) ||\n> \t    (one_of(term, \"good\", \"old\", NULL) && strcmp(orig, \"good\")))\n> \t\tdie(\"can't change the meaning of term '%s'\", term);\n\nCompletely forgot to mention: This conversion skipped the comment\n\n\t# In theory, nothing prevents swapping\n\t# completely good and bad, but this situation\n\t# could be confusing and hasn't been tested\n\t# enough. Forbid it for now.\n\nLet's port that comment over, too?\n\nCiao,\nJohannes\n"},{"id":"281435","messageId":"xmqqh9fyjy9w.fsf@gitster.mtv.corp.google.com","threadId":"41774","inReplyTo":"alpine.DEB.2.20.1603221552100.4690@virtualbox","subject":"Re: [PATCH v2] bisect--helper: convert a function in shell to C","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-03-22T16:03:07Z","receivedAt":"2016-03-22T16:03:07Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> static int one_of(const char *term, ...)\n> {\n> \tva_list matches;\n> \tconst char *match;\n>\n> \tva_start(matches, term);\n> \twhile ((match = va_arg(matches, const char *)))\n> \t\tif (!strcmp(term, match))\n> \t\t\treturn 1;\n> \tva_end(matches);\n>\n> \treturn 0;\n> }\n\nThis is a very good suggestion.  We tend to avoid explicit\ncomparison to NULL and zero, but we avoid assignment in condition\npart of if/while statements even more, so\n\n \twhile ((match = va_arg(matches, const char *)) != NULL)\n\nwould be the best compromise to make it clear and readable.\n\n>> +\tif (!strcmp(term, \"help\") || !strcmp(term, \"start\") ||\n>> +\t\t!strcmp(term, \"skip\") || !strcmp(term, \"next\") ||\n>> +\t\t!strcmp(term, \"reset\") || !strcmp(term, \"visualize\") ||\n>> +\t\t!strcmp(term, \"replay\") || !strcmp(term, \"log\") ||\n>> +\t\t!strcmp(term, \"run\"))\n>> +\t\tdie(\"can't use the builtin command '%s' as a term\", term);\n>\n> This would look so much nicer using the one_of() function above.\n>\n> Please also note that our coding convention (as can be seen from the\n> existing code in builtin/*.c) is to indent the condition differently than\n> the block, either using an extra tab, or by using 4 spaces instead of the\n> tab.\n\nIn general, \"or by using 4 spaces\" is better spelled as \"or by\nindenting so that the line aligns with the beginning of the inside\nof the opening parenthesis on the above line\"; \"if (\" happens to\ntake 4 display spaces and that is where \"4\" comes from and it would\nbe different for \"while (\" condition ;-).\n\nBut with one_of(...) this part would change a lot, I imagine.\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_BOOL(0, \"no-checkout\", &no_checkout,\n>>  \t\t\t N_(\"update BISECT_HEAD instead of checking out the current commit\")),\n>> +\t\tOPT_STRING(0, \"check-term-format\", &term, N_(\"term\"),\n>> +\t\t\t N_(\"check the format of the ref\")),\n>\n> Hmm. The existing code suggests to use OPT_BOOL instead.\n> ...\n> The existing convention is to make the first argument *not* a value of the\n> \"option\", i.e. `--check-term-format \"$TERM_BAD\"` without an equal sign.\n\nI think it is preferrable to keep using OPT_BOOL() for this new one\nif we are incrementally building on top of existing code.\n\nBut if the convention is that the option is to specify what opration\nis invoked, using OPT_CMDMODE() to implement all of them would be a\nworthwhile cleanup to consider at some point.\n\nI agree with all the points you raised in your review.  Just wanted\nto add some clarification myself.\n\nThanks.\n"},{"id":"281439","messageId":"alpine.DEB.2.20.1603221748360.4690@virtualbox","threadId":"41774","inReplyTo":"xmqqh9fyjy9w.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v2] bisect--helper: convert a function in shell to C","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-03-22T16:49:18Z","receivedAt":"2016-03-22T16:49:18Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Junio,\n\nOn Tue, 22 Mar 2016, Junio C Hamano wrote:\n\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n> \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_BOOL(0, \"no-checkout\", &no_checkout,\n> >>  \t\t\t N_(\"update BISECT_HEAD instead of checking out the current commit\")),\n> >> +\t\tOPT_STRING(0, \"check-term-format\", &term, N_(\"term\"),\n> >> +\t\t\t N_(\"check the format of the ref\")),\n> >\n> > Hmm. The existing code suggests to use OPT_BOOL instead.\n> > ...\n> > The existing convention is to make the first argument *not* a value of the\n> > \"option\", i.e. `--check-term-format \"$TERM_BAD\"` without an equal sign.\n> \n> I think it is preferrable to keep using OPT_BOOL() for this new one\n> if we are incrementally building on top of existing code.\n> \n> But if the convention is that the option is to specify what opration\n> is invoked, using OPT_CMDMODE() to implement all of them would be a\n> worthwhile cleanup to consider at some point.\n\nGood point, I keep forgetting that OPT_CMDMODE() was introduced\nspecifically for subcommands.\n\nCiao,\nDscho\n"},{"id":"281452","messageId":"CAFZEwPNg8-X5dsBbMfg5ni1XpOVekRd13y-zgwYJpX0fCwg3Ug@mail.gmail.com","threadId":"41774","inReplyTo":"alpine.DEB.2.20.1603221552100.4690@virtualbox","subject":"Re: [PATCH v2] bisect--helper: convert a function in shell to C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-03-22T17:45:40Z","receivedAt":"2016-03-22T17:45:40Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"On Tue, Mar 22, 2016 at 8:39 PM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> Hi,\n>\n> On Tue, 22 Mar 2016, Pranit Bauva wrote:\n>\n>> Convert the code literally without changing its design even though it\n>> seems that its obscure as to the use of comparing revision to different\n>\n> s/its/it is/\n\nSure! A typo.\n\n>> bisect arguments which seems like a problem in shell because of the way\n>> function arguments are handled.\n>\n> I agree that it is obscure. That is why I would suggest to fix it during\n> the conversion. Using 'new_term' and 'orig_term' (or something similar)\n> would make much more sense.\n>\n> Another good idea would be to include the shell code, or at least to\n> provide a link such as:\n>\n>         https://github.com/git/git/blob/v2.8.0-rc4/git-bisect.sh#L572-L597\n>\n\nI will take care about this henceforth.\n\n>> The argument handling is kind of hard coded right now because it is not\n>> really be meant to be used like this and this is just for testing\n>> purposes whether this new method is as functional as its counter part.\n>> The shell counter part of the method has been retained for historical\n>> purposes.\n>\n> Still, it would make more sense (both in terms of readability and in terms\n> of code safety) to introduce and use a function like\n>\n> static int one_of(const char *term, ...)\n> {\n>         va_list matches;\n>         const char *match;\n>\n>         va_start(matches, term);\n>         while ((match = va_arg(matches, const char *)))\n>                 if (!strcmp(term, match))\n>                         return 1;\n>         va_end(matches);\n>\n>         return 0;\n> }\n>\n\n>> +static int check_term_format(const char *term, const char *revision, int flags);\n>> +\n>> +static int check_term_format(const char *term, const char *revision, int flag) {\n>\n> Since you define the check_term_format() function here, the declaration\n> above is unnecessary. Let's just delete it.\n\nYes. We could just add functions below this so that it would not\ncreate a problem.\n\n>\n>> +     if (check_refname_format(term, flag))\n>> +             die(\"'%s' is not a valid term\", term);\n>> +\n>> +     if (!strcmp(term, \"help\") || !strcmp(term, \"start\") ||\n>> +             !strcmp(term, \"skip\") || !strcmp(term, \"next\") ||\n>> +             !strcmp(term, \"reset\") || !strcmp(term, \"visualize\") ||\n>> +             !strcmp(term, \"replay\") || !strcmp(term, \"log\") ||\n>> +             !strcmp(term, \"run\"))\n>> +             die(\"can't use the builtin command '%s' as a term\", term);\n>\n> This would look so much nicer using the one_of() function above.\n\none_of() will definitely make it clean.\n\n> Please also note that our coding convention (as can be seen from the\n> existing code in builtin/*.c) is to indent the condition differently than\n> the block, either using an extra tab, or by using 4 spaces instead of the\n> tab.\n>\n\nI\n>> +     if (!strcmp(term, \"bad\") || !strcmp(term, \"new\"))\n>> +             if(strcmp(revision, \"bad\"))\n>> +                     die(\"can't change the meaning of term '%s'\", term);\n>> +\n>> +     if (!strcmp(term, \"good\") || !strcmp(term, \"old\"))\n>> +             if (strcmp(revision, \"good\"))\n>> +                     die(\"can't change the meaning of term '%s'\", term);\n>\n> These two can be combined. Actually, these *four* can easily be combined:\n>\n>         if ((one_of(term, \"bad\", \"new\", NULL) && strcmp(orig, \"bad\")) ||\n>             (one_of(term, \"good\", \"old\", NULL) && strcmp(orig, \"good\")))\n>                 die(\"can't change the meaning of term '%s'\", term);\n>\n>>  int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>>  {\n>>       int next_all = 0;\n>>       int no_checkout = 0;\n>> +     const char *term;\n>\n> Better use the existing convention:\n>\n>         int check_term_format = 0;\n>\n>>       struct option options[] = {\n>>               OPT_BOOL(0, \"next-all\", &next_all,\n>>                        N_(\"perform 'git bisect next'\")),\n>>               OPT_BOOL(0, \"no-checkout\", &no_checkout,\n>>                        N_(\"update BISECT_HEAD instead of checking out the current commit\")),\n>> +             OPT_STRING(0, \"check-term-format\", &term, N_(\"term\"),\n>> +                      N_(\"check the format of the ref\")),\n>\n> Hmm. The existing code suggests to use OPT_BOOL instead.\n>\n>>               OPT_END()\n>>       };\n>>\n>>       argc = parse_options(argc, argv, prefix, options,\n>>                            git_bisect_helper_usage, 0);\n>>\n>> +\n>> +     if (term != NULL) {\n>> +             if (argc > 0)\n>\n> Here you need to test for a precise argc, not for a range.\n\nTrue.\n\n>> +                     return check_term_format(term, argv[0], 0);\n>> +             else\n>> +                     die(\"no revision provided with check_for_term\");\n>> +     }\n>> +\n>>       if (!next_all)\n>>               usage_with_options(git_bisect_helper_usage, options);\n>>\n>> diff --git a/git-bisect.sh b/git-bisect.sh\n>> index 5d1cb00..ea237be 100755\n>> --- a/git-bisect.sh\n>> +++ b/git-bisect.sh\n>> @@ -564,8 +564,8 @@ write_terms () {\n>>       then\n>>               die \"$(gettext \"please use two different terms\")\"\n>>       fi\n>> -     check_term_format \"$TERM_BAD\" bad\n>> -     check_term_format \"$TERM_GOOD\" good\n>> +     git bisect--helper --check-term-format=\"$TERM_BAD\" bad\n>> +     git bisect--helper --check-term-format=\"$TERM_GOOD\" good\n>\n> The existing convention is to make the first argument *not* a value of the\n> \"option\", i.e. `--check-term-format \"$TERM_BAD\"` without an equal sign.\n\nWill change this.\n\n> Did you also run the test suite after compiling, to verify that the\n> documented expectations are still met after the conversion?\n\nYes I did run the tests. They produce the same results as they did before.\nTo ease review I will next time include these the output of the tests\nin the commented section.\n\nt6002-rev-list-bisect.sh : http://paste.ubuntu.com/15473728/\nt6030-bisect-porcelain.sh : http://paste.ubuntu.com/15473734/\nt6041-bisect-submodule.sh : http://paste.ubuntu.com/15473743/\n\nIs there any other test I would need to run?\n\nRegards,\nPranit Bauva\n"},{"id":"281454","messageId":"CAFZEwPOV1oE=5uyyooM1kYKxbuY0Jn=ccxYwsc5sxi0e9cgS6A@mail.gmail.com","threadId":"41774","inReplyTo":"alpine.DEB.2.20.1603221610370.4690@virtualbox","subject":"Re: [PATCH v2] bisect--helper: convert a function in shell to C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-03-22T17:46:46Z","receivedAt":"2016-03-22T17:46:46Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"On Tue, Mar 22, 2016 at 8:41 PM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> Hi,\n>\n> On Tue, 22 Mar 2016, Johannes Schindelin wrote:\n>\n>> On Tue, 22 Mar 2016, Pranit Bauva wrote:\n>>\n>> > +   if (!strcmp(term, \"bad\") || !strcmp(term, \"new\"))\n>> > +           if(strcmp(revision, \"bad\"))\n>> > +                   die(\"can't change the meaning of term '%s'\", term);\n>> > +\n>> > +   if (!strcmp(term, \"good\") || !strcmp(term, \"old\"))\n>> > +           if (strcmp(revision, \"good\"))\n>> > +                   die(\"can't change the meaning of term '%s'\", term);\n>>\n>> These two can be combined. Actually, these *four* can easily be combined:\n>>\n>>       if ((one_of(term, \"bad\", \"new\", NULL) && strcmp(orig, \"bad\")) ||\n>>           (one_of(term, \"good\", \"old\", NULL) && strcmp(orig, \"good\")))\n>>               die(\"can't change the meaning of term '%s'\", term);\n>\n> Completely forgot to mention: This conversion skipped the comment\n>\n>         # In theory, nothing prevents swapping\n>         # completely good and bad, but this situation\n>         # could be confusing and hasn't been tested\n>         # enough. Forbid it for now.\n>\n> Let's port that comment over, too?\n\nSure! Adding a comment won't harm anyone. We can remove it when its\nthoroughly tested.\n>\n> Ciao,\n> Johannes\n"},{"id":"281456","messageId":"CAFZEwPOMdozVafJzRYJmhhAAAAVfLJ74dSGVbsHreFFKD1Vobg@mail.gmail.com","threadId":"41774","inReplyTo":"xmqqh9fyjy9w.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v2] bisect--helper: convert a function in shell to C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-03-22T17:52:13Z","receivedAt":"2016-03-22T17:52:13Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"On Tue, Mar 22, 2016 at 9:33 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n>\n>> static int one_of(const char *term, ...)\n>> {\n>>       va_list matches;\n>>       const char *match;\n>>\n>>       va_start(matches, term);\n>>       while ((match = va_arg(matches, const char *)))\n>>               if (!strcmp(term, match))\n>>                       return 1;\n>>       va_end(matches);\n>>\n>>       return 0;\n>> }\n>\n> This is a very good suggestion.  We tend to avoid explicit\n> comparison to NULL and zero, but we avoid assignment in condition\n> part of if/while statements even more, so\n>\n>         while ((match = va_arg(matches, const char *)) != NULL)\n>\n> would be the best compromise to make it clear and readable.\n>\n>>> +    if (!strcmp(term, \"help\") || !strcmp(term, \"start\") ||\n>>> +            !strcmp(term, \"skip\") || !strcmp(term, \"next\") ||\n>>> +            !strcmp(term, \"reset\") || !strcmp(term, \"visualize\") ||\n>>> +            !strcmp(term, \"replay\") || !strcmp(term, \"log\") ||\n>>> +            !strcmp(term, \"run\"))\n>>> +            die(\"can't use the builtin command '%s' as a term\", term);\n>>\n>> This would look so much nicer using the one_of() function above.\n>>\n>> Please also note that our coding convention (as can be seen from the\n>> existing code in builtin/*.c) is to indent the condition differently than\n>> the block, either using an extra tab, or by using 4 spaces instead of the\n>> tab.\n>\n> In general, \"or by using 4 spaces\" is better spelled as \"or by\n> indenting so that the line aligns with the beginning of the inside\n> of the opening parenthesis on the above line\"; \"if (\" happens to\n> take 4 display spaces and that is where \"4\" comes from and it would\n> be different for \"while (\" condition ;-).\n\nI will definitely keep this in mind henceforth.\n>\n> But with one_of(...) this part would change a lot, I imagine.\n>>>      struct option options[] = {\n>>>              OPT_BOOL(0, \"next-all\", &next_all,\n>>>                       N_(\"perform 'git bisect next'\")),\n>>>              OPT_BOOL(0, \"no-checkout\", &no_checkout,\n>>>                       N_(\"update BISECT_HEAD instead of checking out the current commit\")),\n>>> +            OPT_STRING(0, \"check-term-format\", &term, N_(\"term\"),\n>>> +                     N_(\"check the format of the ref\")),\n>>\n>> Hmm. The existing code suggests to use OPT_BOOL instead.\n>> ...\n>> The existing convention is to make the first argument *not* a value of the\n>> \"option\", i.e. `--check-term-format \"$TERM_BAD\"` without an equal sign.\n>\n> I think it is preferrable to keep using OPT_BOOL() for this new one\n> if we are incrementally building on top of existing code.\n>\n> But if the convention is that the option is to specify what opration\n> is invoked, using OPT_CMDMODE() to implement all of them would be a\n> worthwhile cleanup to consider at some point.\n\nOPT_CMDMODE() is actually a better option. I also noticed that it\nisn't mentioned in Documentation/technical/api-parse-options.txt .\nShould I send a patch to include it there just to make it easier for\nsomeone who is new and isn't aware of the changes ?\n\n> I agree with all the points you raised in your review.  Just wanted\n> to add some clarification myself.\n>\n> Thanks.\n"},{"id":"281458","messageId":"CAGZ79kZvi+qJKPkgzHP5LgoyTJd2btJZ6zCc4hkSKAhjoOiYFg@mail.gmail.com","threadId":"41774","inReplyTo":"CAFZEwPOMdozVafJzRYJmhhAAAAVfLJ74dSGVbsHreFFKD1Vobg@mail.gmail.com","subject":"Re: [PATCH v2] bisect--helper: convert a function in shell to C","fromName":"Stefan Beller","fromEmail":"sbeller@google.com","sentAt":"2016-03-22T17:59:10Z","receivedAt":"2016-03-22T17:59:10Z","isPatch":true,"sender":{"key":"stefanbeller@gmail.com","avatar":"https://avatars.githubusercontent.com/u/455868?v=4"},"body":"On Tue, Mar 22, 2016 at 10:52 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n> OPT_CMDMODE() is actually a better option. I also noticed that it\n> isn't mentioned in Documentation/technical/api-parse-options.txt .\n> Should I send a patch to include it there just to make it easier for\n> someone who is new and isn't aware of the changes ?\n\nPatches to outdated documentation are most awesome. ;)\n"},{"id":"281523","messageId":"01020153a254974b-68f7d16a-66d7-4dc1-805d-2185ff1b3ebf-000000@eu-west-1.amazonses.com","threadId":"41774","inReplyTo":"010201539d57ae98-ce4860a6-f7b6-4e06-b556-3c1340cd7749-000000@eu-west-1.amazonses.com","subject":"[PATCH v3] bisect--helper: convert a function in shell to C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-03-23T07:16:06Z","receivedAt":"2016-03-23T07:16:06Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"Convert the code literally without changing its design even though it\nseems that it is obscure as to the use of comparing revision to different\nbisect arguments which seems like a problem in shell because of the way\nfunction arguments are handled.\n\nThe argument handling is kind of hard coded right now because it is not\nreally be meant to be used like this and this is just for testing\npurposes whether this new method is as functional as its counter part.\nThe shell counter part of the method has been retained for historical\npurposes.\n\nAlso using OPT_CMDMODE() to handle check-term-format and next-all\nbecause these sub commands are independent and error should be shown if used\ntogether and should be handled independently.\n\nThis commit reduces the number of failed tests in\nt6030-bisect-porcelain.sh and t6041-bisect-submodule.sh\n\nThe corresponding shell function is :\nhttps://github.com/git/git/blob/v2.8.0-rc4/git-bisect.sh#L572-L597\n\nSigned-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n\n---\nChanges wrt v1:\n - Remove the function declaration\n - Introduce another method one_of() to reduce the clutter in if\n - Add the documentation as to which part should remain untouched\n - Use OPT_CMDMODE() for --check-term-format and --next-all\n - Remove the '=' in git-bisect.sh\n - Respect the coding convention to indent when a line is spread across\n   many lines\n - s/its/it is/g\n - Output of tests:\n   - t6002 : http://paste.ubuntu.com/15477883/\n   - t6030 : http://paste.ubuntu.com/15477887/\n   - t6041 : http://paste.ubuntu.com/15477897/\n - Add the comment that a part shouldn't be touched\n---\n builtin/bisect--helper.c | 73 ++++++++++++++++++++++++++++++++++++++++++++----\n git-bisect.sh            |  4 +--\n 2 files changed, 70 insertions(+), 7 deletions(-)\n\ndiff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\nindex 3324229..ab3891c 100644\n--- a/builtin/bisect--helper.c\n+++ b/builtin/bisect--helper.c\n@@ -2,30 +2,93 @@\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> <revision>\"),\n \tNULL\n };\n \n+static int one_of(const char *term, ...) {\n+\tva_list matches;\n+\tconst char *match;\n+\n+\tva_start(matches, term);\n+\twhile ((match = va_arg(matches, const char *)) != NULL)\n+\t\tif (!strcmp(term, match))\n+\t\t\treturn 1;\n+\n+\tva_end(matches);\n+\n+\treturn 0;\n+}\n+\n+static int check_term_format(const char *term, const char *revision, int flag) {\n+\tif (check_refname_format(term, flag))\n+\t\tdie(\"'%s' is not a valid term\", term);\n+\n+\tif (one_of(term, \"help\", \"start\", \"skip\", \"next\", \"reset\", \"visualize\",\n+\t    \"replay\", \"log\", \"run\", NULL))\n+\t\tdie(\"can't use the builtin command '%s' as a term\", term);\n+\n+\t/* In theory, nothing prevents swapping\n+\t * completely good and bad, but this situation\n+\t * could be confusing and hasn't been tested\n+\t * enough. Forbid it for now.\n+\t */\n+\n+\tif (!strcmp(term, \"bad\") || !strcmp(term, \"new\"))\n+\t\tif (strcmp(revision, \"bad\"))\n+\t\t\tdie(\"can't change the meaning of term '%s'\", term);\n+\n+\tif(!strcmp(term, \"good\") || !strcmp(term, \"old\"))\n+\t\tif (strcmp(revision, \"good\"))\n+\t\t\tdie(\"can't change the meaning of term '%s'\", term);\n+\n+\treturn 0;\n+}\n+\n int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n {\n-\tint next_all = 0;\n+\tint sub_command = 0;\n \tint no_checkout = 0;\n+\n+\tenum sub_commands {\n+\t\tNEXT_ALL,\n+\t\tCHECK_TERM_FMT\n+\t};\n+\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\", &sub_command,\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_CMDMODE(0, \"check-term-format\", &sub_command,\n+\t\t\t N_(\"check the format of the ref\"), CHECK_TERM_FMT),\n \t\tOPT_END()\n \t};\n \n \targc = parse_options(argc, argv, prefix, options,\n \t\t\t     git_bisect_helper_usage, 0);\n \n-\tif (!next_all)\n+\tif (sub_command == CHECK_TERM_FMT) {\n+\t\tif (argc == 2) {\n+\t\t\tif (argv[0] != NULL && argv[1] != NULL)\n+\t\t\t\treturn check_term_format(argv[0], argv[1], 0);\n+\t\t\telse\n+\t\t\t\tdie(\"no revision or term provided with check_for_term\");\n+\t\t}\n+\t\telse\n+\t\t\tdie(\"--check-term-format expects 2 arguments\");\n+\t}\n+\n+\tif (sub_command != NEXT_ALL && sub_command != CHECK_TERM_FMT)\n \t\tusage_with_options(git_bisect_helper_usage, options);\n \n \t/* next-all */\n-\treturn bisect_next_all(prefix, no_checkout);\n+\tif (sub_command == NEXT_ALL)\n+\t\treturn bisect_next_all(prefix, no_checkout);\n+\n+\treturn 1;\n }\ndiff --git a/git-bisect.sh b/git-bisect.sh\nindex 5d1cb00..f63b83e 100755\n--- a/git-bisect.sh\n+++ b/git-bisect.sh\n@@ -564,8 +564,8 @@ 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\n+\tgit bisect--helper --check-term-format \"$TERM_GOOD\" good\n \tprintf '%s\\n%s\\n' \"$TERM_BAD\" \"$TERM_GOOD\" >\"$GIT_DIR/BISECT_TERMS\"\n }\n \n\n--\nhttps://github.com/git/git/pull/216\n"},{"id":"281574","messageId":"alpine.DEB.2.20.1603231220560.4690@virtualbox","threadId":"41774","inReplyTo":"CAFZEwPNg8-X5dsBbMfg5ni1XpOVekRd13y-zgwYJpX0fCwg3Ug@mail.gmail.com","subject":"Re: [PATCH v2] bisect--helper: convert a function in shell to C","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-03-23T11:22:21Z","receivedAt":"2016-03-23T11:22:21Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Pranit,\n\nOn Tue, 22 Mar 2016, Pranit Bauva wrote:\n\n> I did run the tests. They produce the same results as they did before.\n> To ease review I will next time include these the output of the tests\n> in the commented section.\n> \n> t6002-rev-list-bisect.sh : http://paste.ubuntu.com/15473728/\n> t6030-bisect-porcelain.sh : http://paste.ubuntu.com/15473734/\n> t6041-bisect-submodule.sh : http://paste.ubuntu.com/15473743/\n> \n> Is there any other test I would need to run?\n\nOh, I just meant to point out that you need to make sure that the entire\ntest suite passes after your patch series (and ideally, after every patch,\nthat is at least what I frequently test before sending out patch series).\n\nThere is not really a need to mention that you ran the test suite. There\nis only a need to run it ;-)\n\nCiao,\nJohannes\n"},{"id":"281575","messageId":"alpine.DEB.2.20.1603231223090.4690@virtualbox","threadId":"41774","inReplyTo":"CAFZEwPOV1oE=5uyyooM1kYKxbuY0Jn=ccxYwsc5sxi0e9cgS6A@mail.gmail.com","subject":"Re: [PATCH v2] bisect--helper: convert a function in shell to C","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-03-23T11:23:38Z","receivedAt":"2016-03-23T11:23:38Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Pranit,\n\nOn Tue, 22 Mar 2016, Pranit Bauva wrote:\n\n> On Tue, Mar 22, 2016 at 8:41 PM, Johannes Schindelin\n> <Johannes.Schindelin@gmx.de> wrote:\n> >\n> > On Tue, 22 Mar 2016, Johannes Schindelin wrote:\n> >\n> >> On Tue, 22 Mar 2016, Pranit Bauva wrote:\n> >>\n> >> > +   if (!strcmp(term, \"bad\") || !strcmp(term, \"new\"))\n> >> > +           if(strcmp(revision, \"bad\"))\n> >> > +                   die(\"can't change the meaning of term '%s'\", term);\n> >> > +\n> >> > +   if (!strcmp(term, \"good\") || !strcmp(term, \"old\"))\n> >> > +           if (strcmp(revision, \"good\"))\n> >> > +                   die(\"can't change the meaning of term '%s'\", term);\n> >>\n> >> These two can be combined. Actually, these *four* can easily be combined:\n> >>\n> >>       if ((one_of(term, \"bad\", \"new\", NULL) && strcmp(orig, \"bad\")) ||\n> >>           (one_of(term, \"good\", \"old\", NULL) && strcmp(orig, \"good\")))\n> >>               die(\"can't change the meaning of term '%s'\", term);\n> >\n> > Completely forgot to mention: This conversion skipped the comment\n> >\n> >         # In theory, nothing prevents swapping\n> >         # completely good and bad, but this situation\n> >         # could be confusing and hasn't been tested\n> >         # enough. Forbid it for now.\n> >\n> > Let's port that comment over, too?\n> \n> Sure! Adding a comment won't harm anyone. We can remove it when its\n> thoroughly tested.\n\nI am actually not so eager to remove the comment...\n\nCiao,\nJohannes\n"},{"id":"281576","messageId":"alpine.DEB.2.20.1603231223520.4690@virtualbox","threadId":"41774","inReplyTo":"CAGZ79kZvi+qJKPkgzHP5LgoyTJd2btJZ6zCc4hkSKAhjoOiYFg@mail.gmail.com","subject":"Re: [PATCH v2] bisect--helper: convert a function in shell to C","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-03-23T11:24:05Z","receivedAt":"2016-03-23T11:24:05Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Tue, 22 Mar 2016, Stefan Beller wrote:\n\n> On Tue, Mar 22, 2016 at 10:52 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n> > OPT_CMDMODE() is actually a better option. I also noticed that it\n> > isn't mentioned in Documentation/technical/api-parse-options.txt .\n> > Should I send a patch to include it there just to make it easier for\n> > someone who is new and isn't aware of the changes ?\n> \n> Patches to outdated documentation are most awesome. ;)\n\nYes!\n\nThanks,\nJohannes\n"},{"id":"281577","messageId":"alpine.DEB.2.20.1603231238180.4690@virtualbox","threadId":"41774","inReplyTo":"01020153a254974b-68f7d16a-66d7-4dc1-805d-2185ff1b3ebf-000000@eu-west-1.amazonses.com","subject":"Re: [PATCH v3] bisect--helper: convert a function in shell to C","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-03-23T11:57:17Z","receivedAt":"2016-03-23T11:57:17Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Pranit,\n\nOn Wed, 23 Mar 2016, Pranit Bauva wrote:\n\n> Convert the code literally without changing its design even though it\n> seems that it is obscure as to the use of comparing revision to different\n> bisect arguments which seems like a problem in shell because of the way\n> function arguments are handled.\n\nI still believe that it would make for an improvement to replace\n\"revision\" by \"orig_term\".\n\n> The argument handling is kind of hard coded right now because it is not\n> really be meant to be used like this and this is just for testing\n> purposes whether this new method is as functional as its counter part.\n> The shell counter part of the method has been retained for historical\n> purposes.\n\nWell, maybe the argument handling is really meant to be used like this in\nthe end? Just skip that paragraph.\n\n> Also using OPT_CMDMODE() to handle check-term-format and next-all\n> because these sub commands are independent and error should be shown if\n> used together and should be handled independently.\n\nAs is often the case, after some discussion a single patch becomes more\nthan just one change. This is what we see here, too: OPT_CMDMODE() is a\nchange that needs preparation of the existing code in\nbuiltin/bisect--helper.c, and I would highly suggest to split that change\nout into its own patch. It makes for a nicer story, and it is *much*\neasier to review.\n\n> This commit reduces the number of failed tests in\n> t6030-bisect-porcelain.sh and t6041-bisect-submodule.sh\n\nOh? Which tests are supposed to fail? I do not see any failing tests\nhere...\n\n> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\n> index 3324229..ab3891c 100644\n> --- a/builtin/bisect--helper.c\n> +++ b/builtin/bisect--helper.c\n> [...]\n> +static int check_term_format(const char *term, const char *revision, int flag) {\n> +\tif (check_refname_format(term, flag))\n> +\t\tdie(\"'%s' is not a valid term\", term);\n> +\n> +\tif (one_of(term, \"help\", \"start\", \"skip\", \"next\", \"reset\", \"visualize\",\n> +\t    \"replay\", \"log\", \"run\", NULL))\n\nIf I understood Junio correctly, he meant to line up the second line with\nthe corresponding level. In this case, as \"replay\" is a parameter of the\none_of() function, the indentation would look like this instead:\n\n\tif (one_of(term, \"help\", \"start\", \"skip\", \"next\", \"reset\", \"visualize\",\n\t\t   \"replay\", \"log\", \"run\", NULL))\n\n> +\t\tdie(\"can't use the builtin command '%s' as a term\", term);\n> +\n> +\t/* In theory, nothing prevents swapping\n> +\t * completely good and bad, but this situation\n> +\t * could be confusing and hasn't been tested\n> +\t * enough. Forbid it for now.\n> +\t */\n\nI see quite a few comments that put the closing \"*/\" on its own line, but\ndo not award the same pleasure to the opening \"/*\". Personally, I much\nprefer the opening \"/*\" to have an entire line to itself, too, but I guess\nthat there is enough precendence in Git's source code to accept both\nforms.\n\n> +\tif (!strcmp(term, \"bad\") || !strcmp(term, \"new\"))\n> +\t\tif (strcmp(revision, \"bad\"))\n> +\t\t\tdie(\"can't change the meaning of term '%s'\", term);\n> +\n> +\tif(!strcmp(term, \"good\") || !strcmp(term, \"old\"))\n> +\t\tif (strcmp(revision, \"good\"))\n> +\t\t\tdie(\"can't change the meaning of term '%s'\", term);\n\nI am still convinced that\n\n\tif ((one_of(term, \"bad\", \"new\", NULL) && strcmp(orig_term, \"bad\")) ||\n\t    (one_of(term, \"good\", \"old\", NULL) && strcmp(orig_term, \"good\")))\n\t\tdie(\"can't change the meaning of term '%s'\", term);\n\nlooks so much nicer.\n\n>  int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>  {\n> -\tint next_all = 0;\n> +\tint sub_command = 0;\n>  \tint no_checkout = 0;\n> +\n> +\tenum sub_commands {\n> +\t\tNEXT_ALL,\n> +\t\tCHECK_TERM_FMT\n> +\t};\n\nInteresting. I did not think that Git's source code declares enums inside\nfunctions, but builtin/remote.c's config_read_branches() does, so this\ncode is fine.\n\nStill, the patch would be easier to review (corollary: bugs would have a\nharder time to hide) if the change from OPT_BOOL to OPT_CMDMODE was done\nin a separate, preparatory patch.\n\n>  \targc = parse_options(argc, argv, prefix, options,\n>  \t\t\t     git_bisect_helper_usage, 0);\n>  \n> -\tif (!next_all)\n> +\tif (sub_command == CHECK_TERM_FMT) {\n> +\t\tif (argc == 2) {\n> +\t\t\tif (argv[0] != NULL && argv[1] != NULL)\n> +\t\t\t\treturn check_term_format(argv[0], argv[1], 0);\n> +\t\t\telse\n> +\t\t\t\tdie(\"no revision or term provided with check_for_term\");\n> +\t\t}\n> +\t\telse\n> +\t\t\tdie(\"--check-term-format expects 2 arguments\");\n> +\t}\n> +\n> +\tif (sub_command != NEXT_ALL && sub_command != CHECK_TERM_FMT)\n>  \t\tusage_with_options(git_bisect_helper_usage, options);\n\nPersonally, I would prefer\n\n- the usage_with_options() code to come before any sub_command processing,\n\n- the sub_command enum to be initialized with -1, or alternatively\n  hardcoding NEXT_ALL to 1,\n\n- to avoid else clauses after an if () clause whose block returns or\n  die()s,\n\n- to order the clauses of an if/else in ascending size, i.e.\n\n\tif (argc != 2)\n\t\tdie(...);\n\tif ...\n\n- to avoid checking argv[i] for NULL when i < argc (it is the contract\n  that argv[0..argc-1] are all non-NULL, so checking for it is unnecessary\n  churn),\n\n- use a switch() on sub_command instead of unrolled if () statements, and\n\n- wrap the code at 80 columns/row (interpreting tabs as \"up to 8 spaces\").\n\nThe rest of the patch looks good.\n\nCiao,\nJohannes\n"},{"id":"281578","messageId":"CAFZEwPPDhK1biRLuXtYeBX5fsQGw==fUOLxSOXVaZPghbJQYGg@mail.gmail.com","threadId":"41774","inReplyTo":"alpine.DEB.2.20.1603231238180.4690@virtualbox","subject":"Re: [PATCH v3] bisect--helper: convert a function in shell to C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-03-23T13:16:37Z","receivedAt":"2016-03-23T13:16:37Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"On Wed, Mar 23, 2016 at 5:27 PM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> Hi Pranit,\n>\n> On Wed, 23 Mar 2016, Pranit Bauva wrote:\n>\n>> Convert the code literally without changing its design even though it\n>> seems that it is obscure as to the use of comparing revision to different\n>> bisect arguments which seems like a problem in shell because of the way\n>> function arguments are handled.\n>\n> I still believe that it would make for an improvement to replace\n> \"revision\" by \"orig_term\".\n\nI missed this. Will do it.\n\n>> The argument handling is kind of hard coded right now because it is not\n>> really be meant to be used like this and this is just for testing\n>> purposes whether this new method is as functional as its counter part.\n>> The shell counter part of the method has been retained for historical\n>> purposes.\n>\n> Well, maybe the argument handling is really meant to be used like this in\n> the end? Just skip that paragraph.\n\nSure.\n\n>> Also using OPT_CMDMODE() to handle check-term-format and next-all\n>> because these sub commands are independent and error should be shown if\n>> used together and should be handled independently.\n>\n> As is often the case, after some discussion a single patch becomes more\n> than just one change. This is what we see here, too: OPT_CMDMODE() is a\n> change that needs preparation of the existing code in\n> builtin/bisect--helper.c, and I would highly suggest to split that change\n> out into its own patch. It makes for a nicer story, and it is *much*\n> easier to review.\n>\n>> This commit reduces the number of failed tests in\n>> t6030-bisect-porcelain.sh and t6041-bisect-submodule.sh\n>\n> Oh? Which tests are supposed to fail? I do not see any failing tests\n> here...\n\nWhat I meant by this is that before there were 55 out of 70 tests\nwhich failed. After this patch, there are 3 tests out of 70 which\nfailed.\n\n>> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\n>> index 3324229..ab3891c 100644\n>> --- a/builtin/bisect--helper.c\n>> +++ b/builtin/bisect--helper.c\n>> [...]\n>> +static int check_term_format(const char *term, const char *revision, int flag) {\n>> +     if (check_refname_format(term, flag))\n>> +             die(\"'%s' is not a valid term\", term);\n>> +\n>> +     if (one_of(term, \"help\", \"start\", \"skip\", \"next\", \"reset\", \"visualize\",\n>> +         \"replay\", \"log\", \"run\", NULL))\n>\n> If I understood Junio correctly, he meant to line up the second line with\n> the corresponding level. In this case, as \"replay\" is a parameter of the\n> one_of() function, the indentation would look like this instead:\n\nI misunderstood his point.\n\n>         if (one_of(term, \"help\", \"start\", \"skip\", \"next\", \"reset\", \"visualize\",\n>                    \"replay\", \"log\", \"run\", NULL))\n>\n>> +             die(\"can't use the builtin command '%s' as a term\", term);\n>> +\n>> +     /* In theory, nothing prevents swapping\n>> +      * completely good and bad, but this situation\n>> +      * could be confusing and hasn't been tested\n>> +      * enough. Forbid it for now.\n>> +      */\n>\n> I see quite a few comments that put the closing \"*/\" on its own line, but\n> do not award the same pleasure to the opening \"/*\". Personally, I much\n> prefer the opening \"/*\" to have an entire line to itself, too, but I guess\n> that there is enough precendence in Git's source code to accept both\n> forms.\n>\n>> +     if (!strcmp(term, \"bad\") || !strcmp(term, \"new\"))\n>> +             if (strcmp(revision, \"bad\"))\n>> +                     die(\"can't change the meaning of term '%s'\", term);\n>> +\n>> +     if(!strcmp(term, \"good\") || !strcmp(term, \"old\"))\n>> +             if (strcmp(revision, \"good\"))\n>> +                     die(\"can't change the meaning of term '%s'\", term);\n>\n> I am still convinced that\n>\n>         if ((one_of(term, \"bad\", \"new\", NULL) && strcmp(orig_term, \"bad\")) ||\n>             (one_of(term, \"good\", \"old\", NULL) && strcmp(orig_term, \"good\")))\n>                 die(\"can't change the meaning of term '%s'\", term);\n>\n> looks so much nicer.\n\nTrue. I missed this point.\n\n>>  int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>>  {\n>> -     int next_all = 0;\n>> +     int sub_command = 0;\n>>       int no_checkout = 0;\n>> +\n>> +     enum sub_commands {\n>> +             NEXT_ALL,\n>> +             CHECK_TERM_FMT\n>> +     };\n>\n> Interesting. I did not think that Git's source code declares enums inside\n> functions, but builtin/remote.c's config_read_branches() does, so this\n> code is fine.\n\nI didn't notice this before. Since git has the convention of declaring\nenums outside function, it will be better to follow the trend rather\nthan allowing another trend to spread.\n\n> Still, the patch would be easier to review (corollary: bugs would have a\n> harder time to hide) if the change from OPT_BOOL to OPT_CMDMODE was done\n> in a separate, preparatory patch.\n\nI was confused about this. Now that u mention it, I will make the change.\n\n>>       argc = parse_options(argc, argv, prefix, options,\n>>                            git_bisect_helper_usage, 0);\n>>\n>> -     if (!next_all)\n>> +     if (sub_command == CHECK_TERM_FMT) {\n>> +             if (argc == 2) {\n>> +                     if (argv[0] != NULL && argv[1] != NULL)\n>> +                             return check_term_format(argv[0], argv[1], 0);\n>> +                     else\n>> +                             die(\"no revision or term provided with check_for_term\");\n>> +             }\n>> +             else\n>> +                     die(\"--check-term-format expects 2 arguments\");\n>> +     }\n>> +\n>> +     if (sub_command != NEXT_ALL && sub_command != CHECK_TERM_FMT)\n>>               usage_with_options(git_bisect_helper_usage, options);\n>\n> Personally, I would prefer\n>\n> - the usage_with_options() code to come before any sub_command processing,\n>\n> - the sub_command enum to be initialized with -1, or alternatively\n>   hardcoding NEXT_ALL to 1,\n\nOh! I now understand that initializing with 0 can be problematic.\n\n> - to avoid else clauses after an if () clause whose block returns or\n>   die()s,\n\nSure\n\n> - to order the clauses of an if/else in ascending size, i.e.\n>\n>         if (argc != 2)\n>                 die(...);\n>         if ...\n>\n> - to avoid checking argv[i] for NULL when i < argc (it is the contract\n>   that argv[0..argc-1] are all non-NULL, so checking for it is unnecessary\n>   churn),\n\nI wasn't aware of this.\n\n> - use a switch() on sub_command instead of unrolled if () statements, and\nI just browsed through some other parts and found that subcommands are\nput in switch case\n\n> - wrap the code at 80 columns/row (interpreting tabs as \"up to 8 spaces\").\n\n\n> The rest of the patch looks good.\n>\n> Ciao,\n> Johannes\n\nThanks!\n"},{"id":"281580","messageId":"CAFZEwPM1Ye34GJOfck89TX78BHKoiAVf-e=_TZasDV9u60VXGQ@mail.gmail.com","threadId":"41774","inReplyTo":"alpine.DEB.2.20.1603231220560.4690@virtualbox","subject":"Re: [PATCH v2] bisect--helper: convert a function in shell to C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-03-23T13:53:03Z","receivedAt":"2016-03-23T13:53:03Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"On Wed, Mar 23, 2016 at 4:52 PM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> Hi Pranit,\n>\n> On Tue, 22 Mar 2016, Pranit Bauva wrote:\n>\n>> I did run the tests. They produce the same results as they did before.\n>> To ease review I will next time include these the output of the tests\n>> in the commented section.\n>>\n>> t6002-rev-list-bisect.sh : http://paste.ubuntu.com/15473728/\n>> t6030-bisect-porcelain.sh : http://paste.ubuntu.com/15473734/\n>> t6041-bisect-submodule.sh : http://paste.ubuntu.com/15473743/\n>>\n>> Is there any other test I would need to run?\n>\n> Oh, I just meant to point out that you need to make sure that the entire\n> test suite passes after your patch series (and ideally, after every patch,\n> that is at least what I frequently test before sending out patch series).\n\nUp to now, I used to only run the tests of the concerned area of the\npatch. Though from next time, I will take care to run the complete\ntest suite.\n"},{"id":"281588","messageId":"xmqqy499cgrb.fsf@gitster.mtv.corp.google.com","threadId":"41774","inReplyTo":"alpine.DEB.2.20.1603231238180.4690@virtualbox","subject":"Re: [PATCH v3] bisect--helper: convert a function in shell to C","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-03-23T16:15:36Z","receivedAt":"2016-03-23T16:15:36Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n>> +\tif (one_of(term, \"help\", \"start\", \"skip\", \"next\", \"reset\", \"visualize\",\n>> +\t    \"replay\", \"log\", \"run\", NULL))\n>\n> If I understood Junio correctly, he meant to line up the second line with\n> the corresponding level. In this case, as \"replay\" is a parameter of the\n> one_of() function, the indentation would look like this instead:\n>\n> \tif (one_of(term, \"help\", \"start\", \"skip\", \"next\", \"reset\", \"visualize\",\n> \t\t   \"replay\", \"log\", \"run\", NULL))\n\nThanks for clarification.  It may also make sense to wrap the first\nline one word earlier.\n\n>> +\t\tdie(\"can't use the builtin command '%s' as a term\", term);\n>> +\n>> +\t/* In theory, nothing prevents swapping\n>> +\t * completely good and bad, but this situation\n>> +\t * could be confusing and hasn't been tested\n>> +\t * enough. Forbid it for now.\n>> +\t */\n>\n> I see quite a few comments that put the closing \"*/\" on its own line, but\n> do not award the same pleasure to the opening \"/*\". Personally, I much\n> prefer the opening \"/*\" to have an entire line to itself, too, but I guess\n> that there is enough precendence in Git's source code to accept both\n> forms.\n\nWe do want to see \"/*\" and \"*/\" on their own lines, and new code\nshould definitely do so.\n\n>> +\tif (!strcmp(term, \"bad\") || !strcmp(term, \"new\"))\n>> +\t\tif (strcmp(revision, \"bad\"))\n>> +\t\t\tdie(\"can't change the meaning of term '%s'\", term);\n>> +\n>> +\tif(!strcmp(term, \"good\") || !strcmp(term, \"old\"))\n>> +\t\tif (strcmp(revision, \"good\"))\n>> +\t\t\tdie(\"can't change the meaning of term '%s'\", term);\n>\n> I am still convinced that\n>\n> \tif ((one_of(term, \"bad\", \"new\", NULL) && strcmp(orig_term, \"bad\")) ||\n> \t    (one_of(term, \"good\", \"old\", NULL) && strcmp(orig_term, \"good\")))\n> \t\tdie(\"can't change the meaning of term '%s'\", term);\n>\n> looks so much nicer.\n\n... and more importantly, easier to understand what is going on.\n\nThanks.\n"},{"id":"281590","messageId":"xmqqtwjxcgbr.fsf@gitster.mtv.corp.google.com","threadId":"41774","inReplyTo":"CAFZEwPPDhK1biRLuXtYeBX5fsQGw==fUOLxSOXVaZPghbJQYGg@mail.gmail.com","subject":"Re: [PATCH v3] bisect--helper: convert a function in shell to C","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-03-23T16:24:56Z","receivedAt":"2016-03-23T16:24:56Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Pranit Bauva <pranit.bauva@gmail.com> writes:\n\n> On Wed, Mar 23, 2016 at 5:27 PM, Johannes Schindelin\n> <Johannes.Schindelin@gmx.de> wrote:\n>> Hi Pranit,\n>>\n>> On Wed, 23 Mar 2016, Pranit Bauva wrote:\n>>\n>>> Convert the code literally without changing its design even though it\n>>> seems that it is obscure as to the use of comparing revision to different\n>>> bisect arguments which seems like a problem in shell because of the way\n>>> function arguments are handled.\n\nAre you talking about the need to do one_of(\"help\", \"start\", ...)?\n\nI do not see how that is \"problem in shell\" or \"they way function\narguments are handled\".\n\n    git bisect bad\n    git bisect good\n\nare the ways how you mark the current commit as bad or good, and\nrecent change that introduced the \"term\" thingy allows you to\nreplace these \"bad\" and \"good\" with your own words, but\n\n    git bisect start\n    git bisect help\n\netc. have their own meaning, so you cannot say \"I call bad state\n'start' and good state 'help'\" without confusing yourself.  You'd\nnever be able to start or get help if you did so, and that does not\nhave anything to do with \"shell\" or \"function argument\" which are\nimplementation detail.\n\nYou cannot fundamentally allow replacing bad/good with these\nblacklisted words unless you are going to adopt different command\nline syntax (e.g. instead of accepting \"git bisect $bad\" with a word\nchosen by the end user, use \"git bisect mark $bad\", and $bad can be\nany word including \"start\", \"visualize\", etc.).\n"},{"id":"281598","messageId":"CAFZEwPMEFJ=hPj_P_=f4KYBtit0cA9kfACToF1QrE6ZCNTU+3w@mail.gmail.com","threadId":"41774","inReplyTo":"xmqqtwjxcgbr.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v3] bisect--helper: convert a function in shell to C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-03-23T18:38:12Z","receivedAt":"2016-03-23T18:38:12Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"On Wed, Mar 23, 2016 at 9:54 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Pranit Bauva <pranit.bauva@gmail.com> writes:\n>\n>> On Wed, Mar 23, 2016 at 5:27 PM, Johannes Schindelin\n>> <Johannes.Schindelin@gmx.de> wrote:\n>>> Hi Pranit,\n>>>\n>>> On Wed, 23 Mar 2016, Pranit Bauva wrote:\n>>>\n>>>> Convert the code literally without changing its design even though it\n>>>> seems that it is obscure as to the use of comparing revision to different\n>>>> bisect arguments which seems like a problem in shell because of the way\n>>>> function arguments are handled.\n>\n> Are you talking about the need to do one_of(\"help\", \"start\", ...)?\n>\n> I do not see how that is \"problem in shell\" or \"they way function\n> arguments are handled\".\n>\n>     git bisect bad\n>     git bisect good\n>\n> are the ways how you mark the current commit as bad or good, and\n> recent change that introduced the \"term\" thingy allows you to\n> replace these \"bad\" and \"good\" with your own words, but\n>\n>     git bisect start\n>     git bisect help\n>\n> etc. have their own meaning, so you cannot say \"I call bad state\n> 'start' and good state 'help'\" without confusing yourself.  You'd\n> never be able to start or get help if you did so, and that does not\n> have anything to do with \"shell\" or \"function argument\" which are\n> implementation detail.\n>\n> You cannot fundamentally allow replacing bad/good with these\n> blacklisted words unless you are going to adopt different command\n> line syntax (e.g. instead of accepting \"git bisect $bad\" with a word\n> chosen by the end user, use \"git bisect mark $bad\", and $bad can be\n> any word including \"start\", \"visualize\", etc.).\n\nSeems like I got confused. Thanks for the clarification. :)\n"},{"id":"281599","messageId":"CAFZEwPP7DFH=Te3pSdPjNEnVPJ2gVQgtMozQ1W8wdzWDtWi9iQ@mail.gmail.com","threadId":"41774","inReplyTo":"xmqqy499cgrb.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v3] bisect--helper: convert a function in shell to C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-03-23T18:46:24Z","receivedAt":"2016-03-23T18:46:24Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"On Wed, Mar 23, 2016 at 9:45 PM, Junio C Hamano <gitster@pobox.com> wrote:\n> Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n>\n>>> +    if (one_of(term, \"help\", \"start\", \"skip\", \"next\", \"reset\", \"visualize\",\n>>> +        \"replay\", \"log\", \"run\", NULL))\n>>\n>> If I understood Junio correctly, he meant to line up the second line with\n>> the corresponding level. In this case, as \"replay\" is a parameter of the\n>> one_of() function, the indentation would look like this instead:\n>>\n>>       if (one_of(term, \"help\", \"start\", \"skip\", \"next\", \"reset\", \"visualize\",\n>>                  \"replay\", \"log\", \"run\", NULL))\n>\n> Thanks for clarification.  It may also make sense to wrap the first\n> line one word earlier.\n>\n>>> +            die(\"can't use the builtin command '%s' as a term\", term);\n>>> +\n>>> +    /* In theory, nothing prevents swapping\n>>> +     * completely good and bad, but this situation\n>>> +     * could be confusing and hasn't been tested\n>>> +     * enough. Forbid it for now.\n>>> +     */\n>>\n>> I see quite a few comments that put the closing \"*/\" on its own line, but\n>> do not award the same pleasure to the opening \"/*\". Personally, I much\n>> prefer the opening \"/*\" to have an entire line to itself, too, but I guess\n>> that there is enough precendence in Git's source code to accept both\n>> forms.\n>\n> We do want to see \"/*\" and \"*/\" on their own lines, and new code\n> should definitely do so.\n\nI also think it is better to promote one format and try and reduce the\nother one.\n\n>>> +    if (!strcmp(term, \"bad\") || !strcmp(term, \"new\"))\n>>> +            if (strcmp(revision, \"bad\"))\n>>> +                    die(\"can't change the meaning of term '%s'\", term);\n>>> +\n>>> +    if(!strcmp(term, \"good\") || !strcmp(term, \"old\"))\n>>> +            if (strcmp(revision, \"good\"))\n>>> +                    die(\"can't change the meaning of term '%s'\", term);\n>>\n>> I am still convinced that\n>>\n>>       if ((one_of(term, \"bad\", \"new\", NULL) && strcmp(orig_term, \"bad\")) ||\n>>           (one_of(term, \"good\", \"old\", NULL) && strcmp(orig_term, \"good\")))\n>>               die(\"can't change the meaning of term '%s'\", term);\n>>\n>> looks so much nicer.\n>\n> ... and more importantly, easier to understand what is going on.\n\nI will take care about this next time.\n"},{"id":"285410","messageId":"1462338472-3581-1-git-send-email-pranit.bauva@gmail.com","threadId":"41774","inReplyTo":"01020153a254974b-68f7d16a-66d7-4dc1-805d-2185ff1b3ebf-000000@eu-west-1.amazonses.com","subject":"[PATCH 0/2] bisect--helper: rewrite of check_term_format()","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-04T05:07:50Z","receivedAt":"2016-05-04T05:07:50Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"Important Changes:\n\n * The previous patch is split into two patches for a better and logical\n   commit history.\n\n * As previously absent, strbuf is used for string manipulation.\n\n * This passes the complete test suite unlike the previous patches.\n\n * Proper use of error handling (die() and error() are used at appropriate\n   places).\n\n * Remove the shell code which is then redundant.\n\n * Improve according to the minor nits given by Johannes Schindelin.\n\nPranit Bauva (2):\n  bisect--helper: use OPT_CMDMODE instead of OPT_BOOL\n  bisect: rewrite `check_term_format` shell function in C\n\n builtin/bisect--helper.c | 77 ++++++++++++++++++++++++++++++++++++++++++++----\n git-bisect.sh            | 31 ++-----------------\n 2 files changed, 73 insertions(+), 35 deletions(-)\n\n-- \n2.8.1\n"},{"id":"285409","messageId":"1462338472-3581-2-git-send-email-pranit.bauva@gmail.com","threadId":"41774","inReplyTo":"1462338472-3581-1-git-send-email-pranit.bauva@gmail.com","subject":"[PATCH 1/2] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-04T05:07:51Z","receivedAt":"2016-05-04T05:07:51Z","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 sub command to support multiple\n\"operation mode\" though the current implementation does not contain any\nother sub command along side with `--next-all` but further commits will\ninclude some more subcommands.\n\nMentored-by: Lars Schneider <larsxschneider@gmail.com>\nMentored-by: Christain Couder <chriscool@tuxfamily.org>\nSigned-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n---\n builtin/bisect--helper.c | 21 +++++++++++++++------\n 1 file changed, 15 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\nindex 3324229..5f6ef8c 100644\n--- a/builtin/bisect--helper.c\n+++ b/builtin/bisect--helper.c\n@@ -8,13 +8,17 @@ static const char * const git_bisect_helper_usage[] = {\n \tNULL\n };\n \n+enum sub_commands {\n+\tNEXT_ALL = 1\n+};\n+\n int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n {\n-\tint next_all = 0;\n+\tint sub_command = 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\", &sub_command,\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 +27,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 (!sub_command)\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 (sub_command) {\n+\tcase NEXT_ALL:\n+\t\treturn bisect_next_all(prefix, no_checkout);\n+\tdefault:\n+\t\tdie(_(\"bug: unknown subcommand '%d'\"), sub_command);\n+\t}\n+\treturn 0;\n }\n-- \n2.8.1\n"},{"id":"285411","messageId":"1462338472-3581-3-git-send-email-pranit.bauva@gmail.com","threadId":"41774","inReplyTo":"1462338472-3581-1-git-send-email-pranit.bauva@gmail.com","subject":"[PATCH 2/2] bisect: rewrite `check_term_format` shell function in C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-04T05:07:52Z","receivedAt":"2016-05-04T05:07:52Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"This reimplements the `check_term_format` shell function in C and adds\na `--check-term-format` subcommand to `git bisect--helper` to call it\nfrom git-bisect.sh\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 | 58 +++++++++++++++++++++++++++++++++++++++++++++++-\n git-bisect.sh            | 31 ++------------------------\n 2 files changed, 59 insertions(+), 30 deletions(-)\n\ndiff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\nindex 5f6ef8c..228920f 100644\n--- a/builtin/bisect--helper.c\n+++ b/builtin/bisect--helper.c\n@@ -2,16 +2,66 @@\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 enum sub_commands {\n-\tNEXT_ALL = 1\n+\tNEXT_ALL = 1,\n+\tCHECK_TERM_FMT\n };\n \n+/*\n+ * To check whether the string `term` belongs to the set of strings\n+ * included in the variable arguments so as to make the code look\n+ * clean and avoid having long lines in the `if` statement.\n+ */\n+static int one_of(const char *term, ...)\n+{\n+\tva_list matches;\n+\tconst char *match;\n+\n+\tva_start(matches, term);\n+\twhile ((match = va_arg(matches, const char *)) != NULL)\n+\t\tif (!strcmp(term, match))\n+\t\t\treturn 1;\n+\n+\tva_end(matches);\n+\n+\treturn 0;\n+}\n+\n+static int check_term_format(const char *term, const char *orig_term,\n+\t\t\t     int flag)\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, flag))\n+\t\tdie(_(\"'%s' is not a valid term\\n\"), term);\n+\n+\telse if (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\\n\", term);\n+\n+\t/*\n+\t * In theory, nothing prevents swapping\n+\t * completely good and bad, but this situation\n+\t * could be confusing and hasn't been tested\n+\t * enough. Forbid it for now.\n+\t */\n+\n+\telse if ((one_of(term, \"bad\", \"new\", NULL) && strcmp(orig_term, \"bad\")) ||\n+\t\t (one_of(term, \"good\", \"old\", NULL) && strcmp(orig_term, \"good\")))\n+\t\treturn error(\"can't change the meaning of the term '%s'\\n\", term);\n+\n+\treturn 0;\n+}\n+\n int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n {\n \tint sub_command = 0;\n@@ -19,6 +69,8 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \tstruct option options[] = {\n \t\tOPT_CMDMODE(0, \"next-all\", &sub_command,\n \t\t\t N_(\"perform 'git bisect next'\"), NEXT_ALL),\n+\t\tOPT_CMDMODE(0, \"check-term-format\", &sub_command,\n+\t\t\t N_(\"check format of the ref\"), 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@@ -33,6 +85,10 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \tswitch (sub_command) {\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 should be followed by exactly 2 arguments.\"));\n+\t\treturn check_term_format(argv[0], argv[1], 0);\n \tdefault:\n \t\tdie(_(\"bug: unknown subcommand '%d'\"), sub_command);\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.8.1\n"},{"id":"285412","messageId":"CAP8UFD1k4N_qeVYrbJhetKX75ynLSSvQogccR9=nQSR6XwTRVQ@mail.gmail.com","threadId":"41774","inReplyTo":"1462338472-3581-1-git-send-email-pranit.bauva@gmail.com","subject":"Re: [PATCH 0/2] bisect--helper: rewrite of check_term_format()","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-04T05:22:06Z","receivedAt":"2016-05-04T05:22:06Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Pranit,\n\nMy gmail address is \"christian.couder@gmail.com\", not\n\"christain.couder@gmail.com\". ('i' and 'a' are in the wrong oder in my\nfirst name).\n\nThanks,\nChristian.\n"},{"id":"285413","messageId":"CAFZEwPMGaUfVJXn2Wdzy+R=YfYfP_1_O5ixbnLdkyQjFg9E-3g@mail.gmail.com","threadId":"41774","inReplyTo":"CAP8UFD1k4N_qeVYrbJhetKX75ynLSSvQogccR9=nQSR6XwTRVQ@mail.gmail.com","subject":"Re: [PATCH 0/2] bisect--helper: rewrite of check_term_format()","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-04T05:25:41Z","receivedAt":"2016-05-04T05:25:41Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"On Wed, May 4, 2016 at 10:52 AM, Christian Couder\n<christian.couder@gmail.com> wrote:\n> Pranit,\n>\n> My gmail address is \"christian.couder@gmail.com\", not\n> \"christain.couder@gmail.com\". ('i' and 'a' are in the wrong oder in my\n> first name).\n>\n> Thanks,\n> Christian.\n\nSorry. It was a typo.\n"},{"id":"285414","messageId":"CAFZEwPOfLvbu+QD9kV4i5_LQnv1N_NEz1wjsRSmb=YDFpy7=Nw@mail.gmail.com","threadId":"41774","inReplyTo":"1462338472-3581-2-git-send-email-pranit.bauva@gmail.com","subject":"Re: [PATCH 1/2] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-04T05:34:57Z","receivedAt":"2016-05-04T05:34:57Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"On Wed, May 4, 2016 at 10:37 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n> `--next-all` is meant to be used as a sub command to support multiple\n> \"operation mode\" though the current implementation does not contain any\n> other sub command along side with `--next-all` but further commits will\n> include some more subcommands.\n>\n> Mentored-by: Lars Schneider <larsxschneider@gmail.com>\n> Mentored-by: Christain Couder <chriscool@tuxfamily.org>\n> Signed-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n> ---\n\nThis is also a typo. s/Christain/Christian/g\n\n>  builtin/bisect--helper.c | 21 +++++++++++++++------\n>  1 file changed, 15 insertions(+), 6 deletions(-)\n>\n> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\n> index 3324229..5f6ef8c 100644\n> --- a/builtin/bisect--helper.c\n> +++ b/builtin/bisect--helper.c\n> @@ -8,13 +8,17 @@ static const char * const git_bisect_helper_usage[] = {\n>         NULL\n>  };\n>\n> +enum sub_commands {\n> +       NEXT_ALL = 1\n> +};\n> +\n>  int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>  {\n> -       int next_all = 0;\n> +       int sub_command = 0;\n>         int no_checkout = 0;\n>         struct option options[] = {\n> -               OPT_BOOL(0, \"next-all\", &next_all,\n> -                        N_(\"perform 'git bisect next'\")),\n> +               OPT_CMDMODE(0, \"next-all\", &sub_command,\n> +                        N_(\"perform 'git bisect next'\"), NEXT_ALL),\n>                 OPT_BOOL(0, \"no-checkout\", &no_checkout,\n>                          N_(\"update BISECT_HEAD instead of checking out the current commit\")),\n>                 OPT_END()\n> @@ -23,9 +27,14 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>         argc = parse_options(argc, argv, prefix, options,\n>                              git_bisect_helper_usage, 0);\n>\n> -       if (!next_all)\n> +       if (!sub_command)\n>                 usage_with_options(git_bisect_helper_usage, options);\n>\n> -       /* next-all */\n> -       return bisect_next_all(prefix, no_checkout);\n> +       switch (sub_command) {\n> +       case NEXT_ALL:\n> +               return bisect_next_all(prefix, no_checkout);\n> +       default:\n> +               die(_(\"bug: unknown subcommand '%d'\"), sub_command);\n> +       }\n> +       return 0;\n>  }\n> --\n> 2.8.1\n>\n"},{"id":"285416","messageId":"CAPig+cQxpZXKqykFoa2kzCZSC2YqpPXnGocs2YttcJ+rCxmzgQ@mail.gmail.com","threadId":"41774","inReplyTo":"1462338472-3581-2-git-send-email-pranit.bauva@gmail.com","subject":"Re: [PATCH 1/2] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2016-05-04T06:07:50Z","receivedAt":"2016-05-04T06:07:50Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, May 4, 2016 at 1:07 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n> bisect--helper: use OPT_CMDMODE instead of OPT_BOOL\n\nThis subject is too low-level, talking about implementation details,\nwhereas it should be giving a high-level summary of the change.\n\n> `--next-all` is meant to be used as a sub command to support multiple\n> \"operation mode\" though the current implementation does not contain any\n> other sub command along side with `--next-all` but further commits will\n> include some more subcommands.\n\nYou've spelled this as both \"sub command\" and \"subcommand\". Choose one\nand stick with it. (\"subcommand\" is probably more common.)\n\n> Signed-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n> ---\n> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\n> @@ -8,13 +8,17 @@ static const char * const git_bisect_helper_usage[] = {\n>         NULL\n>  };\n>\n> +enum sub_commands {\n\nHow about calling this 'enum subcommand' (no underscore, non-plural)?\n\n> +       NEXT_ALL = 1\n> +};\n> +\n>  int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>  {\n> -       int next_all = 0;\n> +       int sub_command = 0;\n\ns/sub_command/subcommand/\n\n>         struct option options[] = {\n> -               OPT_BOOL(0, \"next-all\", &next_all,\n> -                        N_(\"perform 'git bisect next'\")),\n> +               OPT_CMDMODE(0, \"next-all\", &sub_command,\n> +                        N_(\"perform 'git bisect next'\"), NEXT_ALL),\n> @@ -23,9 +27,14 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>         argc = parse_options(argc, argv, prefix, options,\n>                              git_bisect_helper_usage, 0);\n>\n> -       if (!next_all)\n> +       if (!sub_command)\n>                 usage_with_options(git_bisect_helper_usage, options);\n>\n> -       /* next-all */\n> -       return bisect_next_all(prefix, no_checkout);\n> +       switch (sub_command) {\n> +       case NEXT_ALL:\n> +               return bisect_next_all(prefix, no_checkout);\n> +       default:\n> +               die(_(\"bug: unknown subcommand '%d'\"), sub_command);\n\ns/bug/BUG/\n\nAlso, as this is a programmer error rather than an end-user error, it\ndoes not need to be localized, thus drop the _(...).\n\n> +       }\n> +       return 0;\n>  }\n"},{"id":"285422","messageId":"CAP8UFD1+kEwFhAoveOTYt8NEOK=98W-00nNF+Yoe6kQAYJa6SQ@mail.gmail.com","threadId":"41774","inReplyTo":"CAPig+cQxpZXKqykFoa2kzCZSC2YqpPXnGocs2YttcJ+rCxmzgQ@mail.gmail.com","subject":"Re: [PATCH 1/2] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-04T06:50:56Z","receivedAt":"2016-05-04T06:50:56Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Wed, May 4, 2016 at 8:07 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> On Wed, May 4, 2016 at 1:07 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>> bisect--helper: use OPT_CMDMODE instead of OPT_BOOL\n>\n> This subject is too low-level, talking about implementation details,\n> whereas it should be giving a high-level summary of the change.\n\nWhen a patch is all about a low level detail, I think it is good to\ntalk about the detail in the subject.\n\nHere I think something like \"bisect--helper: parse options using\nOPT_CMDMODE instead of OPT_BOOL\" would be ok for example.\n\n>> `--next-all` is meant to be used as a sub command to support multiple\n>> \"operation mode\" though the current implementation does not contain any\n>> other sub command along side with `--next-all` but further commits will\n>> include some more subcommands.\n>\n> You've spelled this as both \"sub command\" and \"subcommand\". Choose one\n> and stick with it. (\"subcommand\" is probably more common.)\n\nI agree with that and the other suggestions, thanks.\n"},{"id":"285423","messageId":"CAPig+cRL7QkQHpSmeKEYECd9JQO8B29OOJoGx2AQORPfmW7QQQ@mail.gmail.com","threadId":"41774","inReplyTo":"1462338472-3581-3-git-send-email-pranit.bauva@gmail.com","subject":"Re: [PATCH 2/2] bisect: rewrite `check_term_format` shell function in C","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2016-05-04T06:52:09Z","receivedAt":"2016-05-04T06:52:09Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, May 4, 2016 at 1:07 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n> This reimplements the `check_term_format` shell function in C and adds\n\ns/This reimplements/Reimplement/\ns/adds/add/\n\n> a `--check-term-format` subcommand to `git bisect--helper` to call it\n> from git-bisect.sh\n\ns/$/./\n\nOkay, I'll bite: Why is this a good idea? What does it buy you?\n\nIt's not as if the rewrite is especially faster or more easily\nexpressed in C; quite the contrary, the shell code is more concise and\nprobably about equally as fast (not that execution speed matters in\nthis case).\n\nI could understand this functionality being ported to C in the form of\na static function as a minor part of porting \"git bisect terms\" in its\nentirety to C, but I'm not imaginative enough to see why this\nfunctionality is useful as a standalone git-bisect--helper subcommand,\nand the commit message doesn't enlighten. Consequently, it seems like\nunnecessary complexity.\n\n> Signed-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n> ---\n> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\n> @@ -2,16 +2,66 @@\n>  static const char * const git_bisect_helper_usage[] = {\n>         N_(\"git bisect--helper --next-all [--no-checkout]\"),\n> +       N_(\"git bisect--helper --check-term-format <term> <orig_term>\"),\n\nCould this be shortened to --check-term or would that be undesirable?\n\n>         NULL\n>  };\n>\n>  enum sub_commands {\n> -       NEXT_ALL = 1\n> +       NEXT_ALL = 1,\n> +       CHECK_TERM_FMT\n>  };\n>\n> +/*\n> + * To check whether the string `term` belongs to the set of strings\n> + * included in the variable arguments so as to make the code look\n> + * clean and avoid having long lines in the `if` statement.\n> + */\n\nIs this a (long) sentence fragment? Code cleanliness is an obviously\ndesirable trait, thus talking about it in the comment adds no value;\nit's just noise.\n\n> +static int one_of(const char *term, ...)\n> +{\n> +       va_list matches;\n> +       const char *match;\n> +\n> +       va_start(matches, term);\n> +       while ((match = va_arg(matches, const char *)) != NULL)\n> +               if (!strcmp(term, match))\n> +                       return 1;\n\nIs it wise to return here without invoking va_end()?\n\n> +       va_end(matches);\n> +\n> +       return 0;\n> +}\n> +\n> +static int check_term_format(const char *term, const char *orig_term,\n> +                            int flag)\n\nWhat is 'flag' for? The single caller only ever passes 0, so why is this needed?\n\n> +{\n> +       struct strbuf new_term = STRBUF_INIT;\n\n'new_term' is being leaked at every 'return' statement in this function.\n\n> +       strbuf_addf(&new_term, \"refs/bisect/%s\", term);\n> +\n> +       if (check_refname_format(new_term.buf, flag))\n> +               die(_(\"'%s' is not a valid term\\n\"), term);\n\nWhy does this die() while the other \"invalid\" cases merely return\nerror()? What makes this special?\n\nAlso, drop \"\\n\" from the error string.\n\n> +       else if (one_of(term, \"help\", \"start\", \"skip\", \"next\", \"reset\",\n\ns/else //\n\n> +                       \"visualize\", \"replay\", \"log\", \"run\", NULL))\n> +               return error(\"can't use the builtin command '%s' as a term\\n\", term);\n\nThis should be wrapped in _(...). Also, drop the \"\\n\".\n\n> +       /*\n> +        * In theory, nothing prevents swapping\n> +        * completely good and bad, but this situation\n> +        * could be confusing and hasn't been tested\n> +        * enough. Forbid it for now.\n> +        */\n\nThis would be a bit easier to read if re-wrapped to fit within 80\ncolumns rather than 53 or so.\n\n> +       else if ((one_of(term, \"bad\", \"new\", NULL) && strcmp(orig_term, \"bad\")) ||\n\ns/else //\n\n> +                (one_of(term, \"good\", \"old\", NULL) && strcmp(orig_term, \"good\")))\n\nThis can be more efficient by doing the strcmp() before the expensive one_of():\n\n    if ((strcmp(...) && one_of(...)) ||\n        strcmp(...) && one_of(...)))\n\n> +               return error(\"can't change the meaning of the term '%s'\\n\", term);\n\nThis should be wrapped in _(...). Also, drop the \"\\n\".\n\n> +       return 0;\n> +}\n> +\n>  int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>  {\n>         int sub_command = 0;\n> @@ -19,6 +69,8 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>         struct option options[] = {\n>                 OPT_CMDMODE(0, \"next-all\", &sub_command,\n>                          N_(\"perform 'git bisect next'\"), NEXT_ALL),\n> +               OPT_CMDMODE(0, \"check-term-format\", &sub_command,\n> +                        N_(\"check format of the ref\"), CHECK_TERM_FMT),\n\nWhat \"ref\"?\n\n>                 OPT_BOOL(0, \"no-checkout\", &no_checkout,\n>                          N_(\"update BISECT_HEAD instead of checking out the current commit\")),\n>                 OPT_END()\n> @@ -33,6 +85,10 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>         switch (sub_command) {\n>         case NEXT_ALL:\n>                 return bisect_next_all(prefix, no_checkout);\n> +       case CHECK_TERM_FMT:\n> +               if (argc != 2)\n> +                       die(_(\"--check-term-format should be followed by exactly 2 arguments.\"));\n\nDrop the period. Possible reword:\n\n    --check-term-format requires two arguments\n\n> +               return check_term_format(argv[0], argv[1], 0);\n>         default:\n>                 die(_(\"bug: unknown subcommand '%d'\"), sub_command);\n>         }\n"},{"id":"285426","messageId":"xmqqbn4mjn8q.fsf@gitster.mtv.corp.google.com","threadId":"41774","inReplyTo":"CAPig+cQxpZXKqykFoa2kzCZSC2YqpPXnGocs2YttcJ+rCxmzgQ@mail.gmail.com","subject":"Re: [PATCH 1/2] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-05-04T07:28:21Z","receivedAt":"2016-05-04T07:28:21Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Eric Sunshine <sunshine@sunshineco.com> writes:\n\n>> +enum sub_commands {\n>\n> How about calling this 'enum subcommand' (no underscore, non-plural)?\n>\n>> +       NEXT_ALL = 1\n>> +};\n>> +\n>>  int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>>  {\n>> -       int next_all = 0;\n>> +       int sub_command = 0;\n>\n> s/sub_command/subcommand/\n\nNon-plural is a good suggestion, but remember that you are using\nOPT_CMDMODE to parse out that thing.  There is already a name for\nthat concept: \"command name\".  Why not name these after that phrase,\njust like merge-base, replace, and tag already do?\n"},{"id":"285428","messageId":"CAFZEwPNKug1pvGC1fTvZzVPBGKy71fw6S3qcx_fx98nYZasR3w@mail.gmail.com","threadId":"41774","inReplyTo":"CAPig+cRL7QkQHpSmeKEYECd9JQO8B29OOJoGx2AQORPfmW7QQQ@mail.gmail.com","subject":"Re: [PATCH 2/2] bisect: rewrite `check_term_format` shell function in C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-04T07:36:37Z","receivedAt":"2016-05-04T07:36:37Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"On Wed, May 4, 2016 at 12:22 PM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> On Wed, May 4, 2016 at 1:07 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>> This reimplements the `check_term_format` shell function in C and adds\n>\n> s/This reimplements/Reimplement/\n> s/adds/add/\n>\n>> a `--check-term-format` subcommand to `git bisect--helper` to call it\n>> from git-bisect.sh\n>\n> s/$/./\n\nSure.\n\n> Okay, I'll bite: Why is this a good idea? What does it buy you?\n>\n> It's not as if the rewrite is especially faster or more easily\n> expressed in C; quite the contrary, the shell code is more concise and\n> probably about equally as fast (not that execution speed matters in\n> this case).\n>\n> I could understand this functionality being ported to C in the form of\n> a static function as a minor part of porting \"git bisect terms\" in its\n> entirety to C, but I'm not imaginative enough to see why this\n> functionality is useful as a standalone git-bisect--helper subcommand,\n> and the commit message doesn't enlighten. Consequently, it seems like\n> unnecessary complexity.\n\nIt is important to understand that the subcommand is just a\n**temporary** measure.\nYes, I agree that making it a subcommand increases unnecessary\ncomplexity. As a part of complete rewrite of git-bisect.sh, I am\nconverting one function individually to C. The functionality of\nsubcommand is useful so that I can use the existing test suite to\nverify whether I have done the conversion properly. As more functions\nget ported (which I intend to finish this summers), previously\nexisting subcommands will be removed. For eg. After this patch, I will\nnow convert the function write_terms(). So in that patch, I will\nremove the subcommand for check-term-format and instead use the\ncheck_term_format() method and then introduce a new subcommand for\nwrite_terms(). Verifying the function conversion was suggested by\nStefan Beller[1] and Christian Couder[2] gave a hint of how to go\nabout with using the existing test suite. As for the current\nsituation, git-bisect.sh calls `--next-all` in a similar way which was\nthe hint for me of how to go about with this project.\n\n>> Signed-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n>> ---\n>> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\n>> @@ -2,16 +2,66 @@\n>>  static const char * const git_bisect_helper_usage[] = {\n>>         N_(\"git bisect--helper --next-all [--no-checkout]\"),\n>> +       N_(\"git bisect--helper --check-term-format <term> <orig_term>\"),\n>\n> Could this be shortened to --check-term or would that be undesirable?\n\nI guess --check-term-format would be more appropriate and as this is\ntemporary, it wouldn't matter afterwards.\n\n>>         NULL\n>>  };\n>>\n>>  enum sub_commands {\n>> -       NEXT_ALL = 1\n>> +       NEXT_ALL = 1,\n>> +       CHECK_TERM_FMT\n>>  };\n>>\n>> +/*\n>> + * To check whether the string `term` belongs to the set of strings\n>> + * included in the variable arguments so as to make the code look\n>> + * clean and avoid having long lines in the `if` statement.\n>> + */\n>\n> Is this a (long) sentence fragment? Code cleanliness is an obviously\n> desirable trait, thus talking about it in the comment adds no value;\n> it's just noise.\n\nI will keep the initial part of the comment.\n\n>> +static int one_of(const char *term, ...)\n>> +{\n>> +       va_list matches;\n>> +       const char *match;\n>> +\n>> +       va_start(matches, term);\n>> +       while ((match = va_arg(matches, const char *)) != NULL)\n>> +               if (!strcmp(term, match))\n>> +                       return 1;\n>\n> Is it wise to return here without invoking va_end()?\n\nI guess since it already checks for NULL, invoking va_end() will make\nit redundant[3].\n\n>> +       va_end(matches);\n>> +\n>> +       return 0;\n>> +}\n>> +\n>> +static int check_term_format(const char *term, const char *orig_term,\n>> +                            int flag)\n>\n> What is 'flag' for? The single caller only ever passes 0, so why is this needed?\n\nWell, currently the subcommand does not use this flag but this flag is\npresent in the method check_refname_format() so it would be better to\nuse it. This flag might be useful in further parts of conversion since\nas I previously mentioned check-term-format isn't a permanent\nsolution.\n\n>> +{\n>> +       struct strbuf new_term = STRBUF_INIT;\n>\n> 'new_term' is being leaked at every 'return' statement in this function.\n\nI will have to free this memory.\n\n>\n>> +       strbuf_addf(&new_term, \"refs/bisect/%s\", term);\n>> +\n>> +       if (check_refname_format(new_term.buf, flag))\n>> +               die(_(\"'%s' is not a valid term\\n\"), term);\n>\n> Why does this die() while the other \"invalid\" cases merely return\n> error()? What makes this special?\n\nThis is because I felt that if check_refname_format() fails then its a\nfatal error while in other cases, it is not as fatal.\n\n> Also, drop \"\\n\" from the error string.\n\nSure!\n\n>> +       else if (one_of(term, \"help\", \"start\", \"skip\", \"next\", \"reset\",\n>\n> s/else //\n\nAgree since it would be a part of the switch which is not included\nwith the check_refname_format().\n\n>> +                       \"visualize\", \"replay\", \"log\", \"run\", NULL))\n>> +               return error(\"can't use the builtin command '%s' as a term\\n\", term);\n>\n> This should be wrapped in _(...). Also, drop the \"\\n\".\n>\n>> +       /*\n>> +        * In theory, nothing prevents swapping\n>> +        * completely good and bad, but this situation\n>> +        * could be confusing and hasn't been tested\n>> +        * enough. Forbid it for now.\n>> +        */\n>\n> This would be a bit easier to read if re-wrapped to fit within 80\n> columns rather than 53 or so.\n>\n>> +       else if ((one_of(term, \"bad\", \"new\", NULL) && strcmp(orig_term, \"bad\")) ||\n>\n> s/else //\n\nIn the shell script a switch was used, thus `else if` would be a more\nappropriate choice over `if`. Also if the first if statement fails\nthen it is unnecessary to go further.\n\n>\n>> +                (one_of(term, \"good\", \"old\", NULL) && strcmp(orig_term, \"good\")))\n>\n> This can be more efficient by doing the strcmp() before the expensive one_of():\n>\n>     if ((strcmp(...) && one_of(...)) ||\n>         strcmp(...) && one_of(...)))\n\nNice. Will include this.\n\n>> +               return error(\"can't change the meaning of the term '%s'\\n\", term);\n>\n> This should be wrapped in _(...). Also, drop the \"\\n\".\n\nSure\n\n>\n>> +       return 0;\n>> +}\n>> +\n>>  int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>>  {\n>>         int sub_command = 0;\n>> @@ -19,6 +69,8 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>>         struct option options[] = {\n>>                 OPT_CMDMODE(0, \"next-all\", &sub_command,\n>>                          N_(\"perform 'git bisect next'\"), NEXT_ALL),\n>> +               OPT_CMDMODE(0, \"check-term-format\", &sub_command,\n>> +                        N_(\"check format of the ref\"), CHECK_TERM_FMT),\n>\n> What \"ref\"?\n\nThe ref here means that ref (like HEAD).\n\n\n>>                 OPT_BOOL(0, \"no-checkout\", &no_checkout,\n>>                          N_(\"update BISECT_HEAD instead of checking out the current commit\")),\n>>                 OPT_END()\n>> @@ -33,6 +85,10 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>>         switch (sub_command) {\n>>         case NEXT_ALL:\n>>                 return bisect_next_all(prefix, no_checkout);\n>> +       case CHECK_TERM_FMT:\n>> +               if (argc != 2)\n>> +                       die(_(\"--check-term-format should be followed by exactly 2 arguments.\"));\n>\n> Drop the period. Possible reword:\n>\n>     --check-term-format requires two arguments\n\nSeems better\n\n>> +               return check_term_format(argv[0], argv[1], 0);\n>>         default:\n>>                 die(_(\"bug: unknown subcommand '%d'\"), sub_command);\n>>         }\n\n[1]: http://article.gmane.org/gmane.comp.version-control.git/293489\n\n[2]: http://article.gmane.org/gmane.comp.version-control.git/293489\n\n[3]: http://article.gmane.org/gmane.comp.version-control.git/293489\n"},{"id":"285429","messageId":"CAFZEwPOU_CNPMxTwuXf64rMrjApm7dfsjEr7i4xE=M3Ak9xdrw@mail.gmail.com","threadId":"41774","inReplyTo":"CAFZEwPNKug1pvGC1fTvZzVPBGKy71fw6S3qcx_fx98nYZasR3w@mail.gmail.com","subject":"Re: [PATCH 2/2] bisect: rewrite `check_term_format` shell function in C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-04T07:40:21Z","receivedAt":"2016-05-04T07:40:21Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"On Wed, May 4, 2016 at 1:06 PM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n\n>\n> [1]: http://article.gmane.org/gmane.comp.version-control.git/293489\n>\n> [2]: http://article.gmane.org/gmane.comp.version-control.git/293489\n>\n> [3]: http://article.gmane.org/gmane.comp.version-control.git/293489\n\nThese are incorrect links.\n\nThe correct ones are:\n[1]: http://article.gmane.org/gmane.comp.version-control.git/289477\n\n[2]: http://article.gmane.org/gmane.comp.version-control.git/289487\n\n[3]: http://article.gmane.org/gmane.comp.version-control.git/289511\n"},{"id":"285439","messageId":"CAPig+cQn4iRCqquUE-g4879mTS7UJkHr7ANvH9HB2+087qCV7A@mail.gmail.com","threadId":"41774","inReplyTo":"CAFZEwPNKug1pvGC1fTvZzVPBGKy71fw6S3qcx_fx98nYZasR3w@mail.gmail.com","subject":"Re: [PATCH 2/2] bisect: rewrite `check_term_format` shell function in C","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2016-05-04T08:28:42Z","receivedAt":"2016-05-04T08:28:42Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, May 4, 2016 at 3:36 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n> On Wed, May 4, 2016 at 12:22 PM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n>> On Wed, May 4, 2016 at 1:07 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>> Okay, I'll bite: Why is this a good idea? What does it buy you?\n>>\n>> It's not as if the rewrite is especially faster or more easily\n>> expressed in C; quite the contrary, the shell code is more concise and\n>> probably about equally as fast (not that execution speed matters in\n>> this case).\n>>\n>> I could understand this functionality being ported to C in the form of\n>> a static function as a minor part of porting \"git bisect terms\" in its\n>> entirety to C, but I'm not imaginative enough to see why this\n>> functionality is useful as a standalone git-bisect--helper subcommand,\n>> and the commit message doesn't enlighten. Consequently, it seems like\n>> unnecessary complexity.\n>\n> It is important to understand that the subcommand is just a\n> **temporary** measure.\n\nThe commit message seems to be lacking this information and any other rationale.\n\n> Yes, I agree that making it a subcommand increases unnecessary\n> complexity. As a part of complete rewrite of git-bisect.sh, I am\n> converting one function individually to C. The functionality of\n> subcommand is useful so that I can use the existing test suite to\n> verify whether I have done the conversion properly. As more functions\n> get ported (which I intend to finish this summers), previously\n> existing subcommands will be removed. For eg. After this patch, I will\n> now convert the function write_terms(). So in that patch, I will\n> remove the subcommand for check-term-format and instead use the\n> check_term_format() method and then introduce a new subcommand for\n> write_terms(). Verifying the function conversion was suggested by\n> Stefan Beller[1] and Christian Couder[2] gave a hint of how to go\n> about with using the existing test suite. As for the current\n> situation, git-bisect.sh calls `--next-all` in a similar way which was\n> the hint for me of how to go about with this project.\n\nYou're taking an inverted bottom-up approach which repeatedly adds and\nremoves unnecessary complexity rather than a more straight-forward\ntop-down approach. For instance, with a top-down approach, as a first\nstep, you could instead add a skeleton, do-nothing \"git-bisect--helper\nset-terms\" and flesh it out in subsequent patches until fully\nimplemented, at which point drop all the \"terms\" code from\ngit-bisect.sh and have it invoke the helper instead. You get the same\nbenefit of being able to use the existing test suite without the\nunnecessary complexity.\n\nIn fact, git-bisect.sh could start invoking \"git-bisect--helper\"\nbefore it's fully fleshed out. For instance, a partially fleshed out C\nwrite_terms(), might just verify that the two terms are not the same\nand then write them out to BISECT_TERMS, and the shell script would\ninvoke its own check_term_format() before calling the helper.\n\n>>> +static int one_of(const char *term, ...)\n>>> +{\n>>> +       va_list matches;\n>>> +       const char *match;\n>>> +\n>>> +       va_start(matches, term);\n>>> +       while ((match = va_arg(matches, const char *)) != NULL)\n>>> +               if (!strcmp(term, match))\n>>> +                       return 1;\n>>\n>> Is it wise to return here without invoking va_end()?\n>\n> I guess since it already checks for NULL, invoking va_end() will make\n> it redundant[3].\n\nSorry, your response does not compute. Each va_start() *must* be\nbalanced with a va_end(). (While it's true that you may encounters\nplatforms/compilers for which a missing va_end() does no harm, such\ncode is not portable.)\n\n>>> +       va_end(matches);\n>>> +\n>>> +       return 0;\n>>> +}\n>>> +\n>>> +static int check_term_format(const char *term, const char *orig_term,\n>>> +                            int flag)\n>>\n>> What is 'flag' for? The single caller only ever passes 0, so why is this needed?\n>\n> Well, currently the subcommand does not use this flag but this flag is\n> present in the method check_refname_format() so it would be better to\n> use it. This flag might be useful in further parts of conversion since\n> as I previously mentioned check-term-format isn't a permanent\n> solution.\n\nSorry, again this does not compute. Certainly, you must pass *some*\nflags argument to check_refname_format() as 'flags' is part of its\nsignature, but that doesn't explain why check_term_format() accepts a\n'flag' argument. Moreover, check_term_format() is not a general\npurpose function like check_refname_format(), so this sort of\n*apparent* flexibility adds complexity with no obvious benefit.\n\n>>> +       strbuf_addf(&new_term, \"refs/bisect/%s\", term);\n>>> +\n>>> +       if (check_refname_format(new_term.buf, flag))\n>>> +               die(_(\"'%s' is not a valid term\\n\"), term);\n>>\n>> Why does this die() while the other \"invalid\" cases merely return\n>> error()? What makes this special?\n>\n> This is because I felt that if check_refname_format() fails then its a\n> fatal error while in other cases, it is not as fatal.\n\nThe name of the command is \"check-term-format\" and that is precisely\nits purpose so, from the perspective of the caller, *all* problems\nwith the term are fatal. It's black-and-white, there is no grey:\neither a term is acceptable, or it isn't; that's all the caller wants\nto know. Consequently, all problems detected by this function should\nbe reported the same way (preferably via 'return error()').\n\n>>> +       else if (one_of(term, \"help\", \"start\", \"skip\", \"next\", \"reset\",\n>>\n>> s/else //\n>\n> Agree since it would be a part of the switch which is not included\n> with the check_refname_format().\n>\n>>> +       else if ((one_of(term, \"bad\", \"new\", NULL) && strcmp(orig_term, \"bad\")) ||\n>>\n>> s/else //\n>\n> In the shell script a switch was used, thus `else if` would be a more\n> appropriate choice over `if`. Also if the first if statement fails\n> then it is unnecessary to go further.\n\nWhether this was a 'switch' statement in the shell script is\nimmaterial. The body of each of these 'if' statements exits the\nfunction, so no following code will be executed anyhow when the\ncondition is true. This makes the 'else' pure noise which is why\n's/else //' is suggested and good style. The less the reader's brain\nhas to process, the easier the code is to comprehend.\n\n>>> +               OPT_CMDMODE(0, \"check-term-format\", &sub_command,\n>>> +                        N_(\"check format of the ref\"), CHECK_TERM_FMT),\n>>\n>> What \"ref\"?\n>\n> The ref here means that ref (like HEAD).\n\nSorry, does not compute. To what HEAD or other ref are you referring?\nThis command is about checking the name of a bisection term. Where\ndoes 'ref' come into it (other than as an implementation detail)?\n"},{"id":"285447","messageId":"CAP8UFD38MJNrx8fAbAXU7H0XxJmvF9SwS1mxYyESCJfQ-hK09g@mail.gmail.com","threadId":"41774","inReplyTo":"CAPig+cQn4iRCqquUE-g4879mTS7UJkHr7ANvH9HB2+087qCV7A@mail.gmail.com","subject":"Re: [PATCH 2/2] bisect: rewrite `check_term_format` shell function in C","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-04T08:54:20Z","receivedAt":"2016-05-04T08:54:20Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Wed, May 4, 2016 at 10:28 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> On Wed, May 4, 2016 at 3:36 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>> On Wed, May 4, 2016 at 12:22 PM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n>>> On Wed, May 4, 2016 at 1:07 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>>> Okay, I'll bite: Why is this a good idea? What does it buy you?\n>>>\n>>> It's not as if the rewrite is especially faster or more easily\n>>> expressed in C; quite the contrary, the shell code is more concise and\n>>> probably about equally as fast (not that execution speed matters in\n>>> this case).\n>>>\n>>> I could understand this functionality being ported to C in the form of\n>>> a static function as a minor part of porting \"git bisect terms\" in its\n>>> entirety to C, but I'm not imaginative enough to see why this\n>>> functionality is useful as a standalone git-bisect--helper subcommand,\n>>> and the commit message doesn't enlighten. Consequently, it seems like\n>>> unnecessary complexity.\n>>\n>> It is important to understand that the subcommand is just a\n>> **temporary** measure.\n>\n> The commit message seems to be lacking this information and any other rationale.\n\nYeah, I agree it could be improved in this regard.\n\n>> Yes, I agree that making it a subcommand increases unnecessary\n>> complexity. As a part of complete rewrite of git-bisect.sh, I am\n>> converting one function individually to C. The functionality of\n>> subcommand is useful so that I can use the existing test suite to\n>> verify whether I have done the conversion properly. As more functions\n>> get ported (which I intend to finish this summers), previously\n>> existing subcommands will be removed. For eg. After this patch, I will\n>> now convert the function write_terms(). So in that patch, I will\n>> remove the subcommand for check-term-format and instead use the\n>> check_term_format() method and then introduce a new subcommand for\n>> write_terms(). Verifying the function conversion was suggested by\n>> Stefan Beller[1] and Christian Couder[2] gave a hint of how to go\n>> about with using the existing test suite. As for the current\n>> situation, git-bisect.sh calls `--next-all` in a similar way which was\n>> the hint for me of how to go about with this project.\n>\n> You're taking an inverted bottom-up approach which repeatedly adds and\n> removes unnecessary complexity rather than a more straight-forward\n> top-down approach. For instance, with a top-down approach, as a first\n> step, you could instead add a skeleton, do-nothing \"git-bisect--helper\n> set-terms\" and flesh it out in subsequent patches until fully\n> implemented,\n\nI am not sure this is the best approach. If for some reason the GSoC\nproject is not finished, we will end up with a badly named\n\"git-bisect--helper --set-terms\" command and a badly named\nwrite_term() shell functions. They will be badly named because they\nwill not do all what the name suggests.\n\n> at which point drop all the \"terms\" code from\n> git-bisect.sh and have it invoke the helper instead. You get the same\n> benefit of being able to use the existing test suite without the\n> unnecessary complexity.\n>\n> In fact, git-bisect.sh could start invoking \"git-bisect--helper\"\n> before it's fully fleshed out. For instance, a partially fleshed out C\n> write_terms(), might just verify that the two terms are not the same\n> and then write them out to BISECT_TERMS, and the shell script would\n> invoke its own check_term_format() before calling the helper.\n>\n>>>> +static int one_of(const char *term, ...)\n>>>> +{\n>>>> +       va_list matches;\n>>>> +       const char *match;\n>>>> +\n>>>> +       va_start(matches, term);\n>>>> +       while ((match = va_arg(matches, const char *)) != NULL)\n>>>> +               if (!strcmp(term, match))\n>>>> +                       return 1;\n>>>\n>>> Is it wise to return here without invoking va_end()?\n>>\n>> I guess since it already checks for NULL, invoking va_end() will make\n>> it redundant[3].\n>\n> Sorry, your response does not compute. Each va_start() *must* be\n> balanced with a va_end(). (While it's true that you may encounters\n> platforms/compilers for which a missing va_end() does no harm, such\n> code is not portable.)\n\nYeah, I agree with that and the rest of your comments. Thanks.\n"},{"id":"285453","messageId":"alpine.DEB.2.20.1605041259180.9313@virtualbox","threadId":"41774","inReplyTo":"1462338472-3581-2-git-send-email-pranit.bauva@gmail.com","subject":"Re: [PATCH 1/2] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-05-04T11:02:49Z","receivedAt":"2016-05-04T11:02:49Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Pranit,\n\nOn Wed, 4 May 2016, Pranit Bauva wrote:\n\n> `--next-all` is meant to be used as a sub command to support multiple\n> \"operation mode\" though the current implementation does not contain any\n> other sub command along side with `--next-all` but further commits will\n> include some more subcommands.\n\nThat is a good explanation.\n\n> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\n> index 3324229..5f6ef8c 100644\n> --- a/builtin/bisect--helper.c\n> +++ b/builtin/bisect--helper.c\n> @@ -8,13 +8,17 @@ static const char * const git_bisect_helper_usage[] = {\n>  \tNULL\n>  };\n>  \n> +enum sub_commands {\n\nInstead of \"sub_commands\" and ...\n\n> +\tNEXT_ALL = 1\n> +};\n> +\n>  int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>  {\n> -\tint next_all = 0;\n> +\tint sub_command = 0;\n\n... sub_command, seeing as you convert things into ...\n\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\", &sub_command,\n> +\t\t\t N_(\"perform 'git bisect next'\"), NEXT_ALL),\n\n... using CMDMODE, how about using `enum mode` and `int mode`? And\nactually `enum mode mode` instead of `int mode`. Or...\n\nActually, it could be even more concise by writing\n\n\tenum { NEXT_ALL = 1 } mode = 0;\n\nThere is not really a need for that enum to be in a different scope than\ncmd_bisect__helper(), and neither does it need to be named...\n\nCiao,\nDscho\n"},{"id":"285454","messageId":"alpine.DEB.2.20.1605041304050.9313@virtualbox","threadId":"41774","inReplyTo":"CAP8UFD1+kEwFhAoveOTYt8NEOK=98W-00nNF+Yoe6kQAYJa6SQ@mail.gmail.com","subject":"Re: [PATCH 1/2] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-05-04T11:05:37Z","receivedAt":"2016-05-04T11:05:37Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Christian,\n\nOn Wed, 4 May 2016, Christian Couder wrote:\n\n> On Wed, May 4, 2016 at 8:07 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> > On Wed, May 4, 2016 at 1:07 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n> >> bisect--helper: use OPT_CMDMODE instead of OPT_BOOL\n> >\n> > This subject is too low-level, talking about implementation details,\n> > whereas it should be giving a high-level summary of the change.\n> \n> When a patch is all about a low level detail, I think it is good to\n> talk about the detail in the subject.\n\nWell, this is not the case here. The intent of this commit is to prepare\nfor other command modes.\n\nSo... why not just say \"bisect--helper: prepare for modes other than\n'next-all'\"?\n\nCiao,\nDscho\n"},{"id":"285455","messageId":"alpine.DEB.2.20.1605041309430.9313@virtualbox","threadId":"41774","inReplyTo":"CAFZEwPNKug1pvGC1fTvZzVPBGKy71fw6S3qcx_fx98nYZasR3w@mail.gmail.com","subject":"Re: [PATCH 2/2] bisect: rewrite `check_term_format` shell function in C","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-05-04T11:13:18Z","receivedAt":"2016-05-04T11:13:18Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Pranit,\n\nOn Wed, 4 May 2016, Pranit Bauva wrote:\n\n> On Wed, May 4, 2016 at 12:22 PM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> > On Wed, May 4, 2016 at 1:07 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n> >\n> >> +static int one_of(const char *term, ...)\n> >> +{\n> >> +       va_list matches;\n> >> +       const char *match;\n> >> +\n> >> +       va_start(matches, term);\n> >> +       while ((match = va_arg(matches, const char *)) != NULL)\n> >> +               if (!strcmp(term, match))\n> >> +                       return 1;\n> >\n> > Is it wise to return here without invoking va_end()?\n> \n> I guess since it already checks for NULL, invoking va_end() will make\n> it redundant[3].\n\nActually, this is my fault (I suggested that form of the one_of()\nfunction). The man page for va_end() clearly states that every call to\nva_start() needs to be paired with a corresponding va_end(), so it is\nincorrect to return without a call to va_end().\n\nMaybe something like instead?\n\n\tstatic int one_of(const char *term, ...)\n\t{\n\t\tint res = 0;\n\t\tva_list matches;\n\t\tconst char *match;\n\n\t\tva_start(matches, term);\n\t\twhile (!res && (match = va_arg(matches, const char *)))\n\t\t\tres = !strcmp(term, match);\n\t\tva_end(matches);\n\n\t\treturn res;\n\t}\nCiao,\nDscho\n"},{"id":"285463","messageId":"CAFZEwPNdmJdt=4Hg7KpfGS51sDeKyAPWgApESf564kt_eaP3Rg@mail.gmail.com","threadId":"41774","inReplyTo":"CAPig+cQn4iRCqquUE-g4879mTS7UJkHr7ANvH9HB2+087qCV7A@mail.gmail.com","subject":"Re: [PATCH 2/2] bisect: rewrite `check_term_format` shell function in C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-04T11:58:28Z","receivedAt":"2016-05-04T11:58:28Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"On Wed, May 4, 2016 at 1:58 PM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> On Wed, May 4, 2016 at 3:36 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>> On Wed, May 4, 2016 at 12:22 PM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n>>> On Wed, May 4, 2016 at 1:07 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>>> Okay, I'll bite: Why is this a good idea? What does it buy you?\n>>>\n>>> It's not as if the rewrite is especially faster or more easily\n>>> expressed in C; quite the contrary, the shell code is more concise and\n>>> probably about equally as fast (not that execution speed matters in\n>>> this case).\n>>>\n>>> I could understand this functionality being ported to C in the form of\n>>> a static function as a minor part of porting \"git bisect terms\" in its\n>>> entirety to C, but I'm not imaginative enough to see why this\n>>> functionality is useful as a standalone git-bisect--helper subcommand,\n>>> and the commit message doesn't enlighten. Consequently, it seems like\n>>> unnecessary complexity.\n>>\n>> It is important to understand that the subcommand is just a\n>> **temporary** measure.\n>\n> The commit message seems to be lacking this information and any other rationale.\n\nI will modify the commit message in order to reflect this.\n\n>>>> +static int one_of(const char *term, ...)\n>>>> +{\n>>>> +       va_list matches;\n>>>> +       const char *match;\n>>>> +\n>>>> +       va_start(matches, term);\n>>>> +       while ((match = va_arg(matches, const char *)) != NULL)\n>>>> +               if (!strcmp(term, match))\n>>>> +                       return 1;\n>>>\n>>> Is it wise to return here without invoking va_end()?\n>>\n>> I guess since it already checks for NULL, invoking va_end() will make\n>> it redundant[3].\n>\n> Sorry, your response does not compute. Each va_start() *must* be\n> balanced with a va_end(). (While it's true that you may encounters\n> platforms/compilers for which a missing va_end() does no harm, such\n> code is not portable.)\n\nI am sorry for my misunderstanding. I had very little idea about\nvariable arguments. I have searched on this now. I will update by\naccording to Johannes which seems nice to me.\n\n>>>> +       va_end(matches);\n>>>> +\n>>>> +       return 0;\n>>>> +}\n>>>> +\n>>>> +static int check_term_format(const char *term, const char *orig_term,\n>>>> +                            int flag)\n>>>\n>>> What is 'flag' for? The single caller only ever passes 0, so why is this needed?\n>>\n>> Well, currently the subcommand does not use this flag but this flag is\n>> present in the method check_refname_format() so it would be better to\n>> use it. This flag might be useful in further parts of conversion since\n>> as I previously mentioned check-term-format isn't a permanent\n>> solution.\n>\n> Sorry, again this does not compute. Certainly, you must pass *some*\n> flags argument to check_refname_format() as 'flags' is part of its\n> signature, but that doesn't explain why check_term_format() accepts a\n> 'flag' argument. Moreover, check_term_format() is not a general\n> purpose function like check_refname_format(), so this sort of\n> *apparent* flexibility adds complexity with no obvious benefit.\n\nI check the future functions and it does not require the flag argument\nso I will remove it.\n\n>>>> +       strbuf_addf(&new_term, \"refs/bisect/%s\", term);\n>>>> +\n>>>> +       if (check_refname_format(new_term.buf, flag))\n>>>> +               die(_(\"'%s' is not a valid term\\n\"), term);\n>>>\n>>> Why does this die() while the other \"invalid\" cases merely return\n>>> error()? What makes this special?\n>>\n>> This is because I felt that if check_refname_format() fails then its a\n>> fatal error while in other cases, it is not as fatal.\n>\n> The name of the command is \"check-term-format\" and that is precisely\n> its purpose so, from the perspective of the caller, *all* problems\n> with the term are fatal. It's black-and-white, there is no grey:\n> either a term is acceptable, or it isn't; that's all the caller wants\n> to know. Consequently, all problems detected by this function should\n> be reported the same way (preferably via 'return error()').\n\nSure. I will use 'return error()'. Any particular reason why this\ninstead of die() ?\n\n>>>> +       else if (one_of(term, \"help\", \"start\", \"skip\", \"next\", \"reset\",\n>>>\n>>> s/else //\n>>\n>> Agree since it would be a part of the switch which is not included\n>> with the check_refname_format().\n>>\n>>>> +       else if ((one_of(term, \"bad\", \"new\", NULL) && strcmp(orig_term, \"bad\")) ||\n>>>\n>>> s/else //\n>>\n>> In the shell script a switch was used, thus `else if` would be a more\n>> appropriate choice over `if`. Also if the first if statement fails\n>> then it is unnecessary to go further.\n>\n> Whether this was a 'switch' statement in the shell script is\n> immaterial. The body of each of these 'if' statements exits the\n> function, so no following code will be executed anyhow when the\n> condition is true. This makes the 'else' pure noise which is why\n> 's/else //' is suggested and good style. The less the reader's brain\n> has to process, the easier the code is to comprehend.\n\nOkay. I get it. Will drop off the else.\n\n>>>> +               OPT_CMDMODE(0, \"check-term-format\", &sub_command,\n>>>> +                        N_(\"check format of the ref\"), CHECK_TERM_FMT),\n>>>\n>>> What \"ref\"?\n>>\n>> The ref here means that ref (like HEAD).\n>\n> Sorry, does not compute. To what HEAD or other ref are you referring?\n> This command is about checking the name of a bisection term. Where\n> does 'ref' come into it (other than as an implementation detail)?\n\nI guess it would be more appropriate to use term.\n\nThanks,\nPranit Bauva\n"},{"id":"285465","messageId":"CAFZEwPMM9vg7pAZwqwaC2HUWo+xnq3X6SrTQEUc20bs_nbzMmw@mail.gmail.com","threadId":"41774","inReplyTo":"alpine.DEB.2.20.1605041309430.9313@virtualbox","subject":"Re: [PATCH 2/2] bisect: rewrite `check_term_format` shell function in C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-04T12:00:10Z","receivedAt":"2016-05-04T12:00:10Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"On Wed, May 4, 2016 at 4:43 PM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> Hi Pranit,\n>\n> On Wed, 4 May 2016, Pranit Bauva wrote:\n>\n>> On Wed, May 4, 2016 at 12:22 PM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n>> > On Wed, May 4, 2016 at 1:07 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>> >\n>> >> +static int one_of(const char *term, ...)\n>> >> +{\n>> >> +       va_list matches;\n>> >> +       const char *match;\n>> >> +\n>> >> +       va_start(matches, term);\n>> >> +       while ((match = va_arg(matches, const char *)) != NULL)\n>> >> +               if (!strcmp(term, match))\n>> >> +                       return 1;\n>> >\n>> > Is it wise to return here without invoking va_end()?\n>>\n>> I guess since it already checks for NULL, invoking va_end() will make\n>> it redundant[3].\n>\n> Actually, this is my fault (I suggested that form of the one_of()\n> function). The man page for va_end() clearly states that every call to\n> va_start() needs to be paired with a corresponding va_end(), so it is\n> incorrect to return without a call to va_end().\n>\n> Maybe something like instead?\n>\n>         static int one_of(const char *term, ...)\n>         {\n>                 int res = 0;\n>                 va_list matches;\n>                 const char *match;\n>\n>                 va_start(matches, term);\n>                 while (!res && (match = va_arg(matches, const char *)))\n>                         res = !strcmp(term, match);\n>                 va_end(matches);\n>\n>                 return res;\n>         }\n> Ciao,\n> Dscho\n\nThanks for this. I had little idea about variable arguments before. I\nhave searched it now. Will use your bits.\n"},{"id":"285466","messageId":"CAFZEwPMOuDB-SrNGPp3D1yBSVLaEvbJujKa7PVKOBt8PqUvk0w@mail.gmail.com","threadId":"41774","inReplyTo":"alpine.DEB.2.20.1605041304050.9313@virtualbox","subject":"Re: [PATCH 1/2] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-04T12:04:54Z","receivedAt":"2016-05-04T12:04:54Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"On Wed, May 4, 2016 at 4:35 PM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> Hi Christian,\n>\n> On Wed, 4 May 2016, Christian Couder wrote:\n>\n>> On Wed, May 4, 2016 at 8:07 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n>> > On Wed, May 4, 2016 at 1:07 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>> >> bisect--helper: use OPT_CMDMODE instead of OPT_BOOL\n>> >\n>> > This subject is too low-level, talking about implementation details,\n>> > whereas it should be giving a high-level summary of the change.\n>>\n>> When a patch is all about a low level detail, I think it is good to\n>> talk about the detail in the subject.\n>\n> Well, this is not the case here. The intent of this commit is to prepare\n> for other command modes.\n>\n> So... why not just say \"bisect--helper: prepare for modes other than\n> 'next-all'\"?\n\nSounds nice!\n\n> Ciao,\n> Dscho\n\nThanks,\nPranit Bauva\n"},{"id":"285467","messageId":"CAP8UFD2k=JMYUg1SPE1TP6uD1bUnheYs8YhFDrzgEny85ocQFw@mail.gmail.com","threadId":"41774","inReplyTo":"alpine.DEB.2.20.1605041304050.9313@virtualbox","subject":"Re: [PATCH 1/2] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-04T12:05:36Z","receivedAt":"2016-05-04T12:05:36Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Wed, May 4, 2016 at 1:05 PM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> Hi Christian,\n>\n> On Wed, 4 May 2016, Christian Couder wrote:\n>\n>> On Wed, May 4, 2016 at 8:07 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n>> > On Wed, May 4, 2016 at 1:07 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>> >> bisect--helper: use OPT_CMDMODE instead of OPT_BOOL\n>> >\n>> > This subject is too low-level, talking about implementation details,\n>> > whereas it should be giving a high-level summary of the change.\n>>\n>> When a patch is all about a low level detail, I think it is good to\n>> talk about the detail in the subject.\n>\n> Well, this is not the case here. The intent of this commit is to prepare\n> for other command modes.\n\nIt depends if you think that describing the long term intent of a\ncommit is more important than just describing what the commit actually\ndoes in the subject.\nIn my opinion the long term intent of the commit is better explained\nin the commit message. (And the patch indeed talks about what the long\nterm intent is, even if it could probably be improved.)\n\n> So... why not just say \"bisect--helper: prepare for modes other than\n> 'next-all'\"?\n\nFor (an extreme) example, in my patch series about libifying \"git\napply\" functionality, should many of the patches have subjects like\n\"builtin/apply: prepare for an apply.{c,h} lib\"?\n"},{"id":"285468","messageId":"CAP8UFD11h4rbLWsx52mze64HANVyXRHDnj_5F9F4FHW63pM5aA@mail.gmail.com","threadId":"41774","inReplyTo":"alpine.DEB.2.20.1605041309430.9313@virtualbox","subject":"Re: [PATCH 2/2] bisect: rewrite `check_term_format` shell function in C","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-04T12:21:31Z","receivedAt":"2016-05-04T12:21:31Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Wed, May 4, 2016 at 1:13 PM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> Maybe something like instead?\n>\n>         static int one_of(const char *term, ...)\n>         {\n>                 int res = 0;\n>                 va_list matches;\n>                 const char *match;\n>\n>                 va_start(matches, term);\n>                 while (!res && (match = va_arg(matches, const char *)))\n>                         res = !strcmp(term, match);\n\nYeah or maybe:\n\n                    while ((match = va_arg(matches, const char *)) != NULL)\n                            if (!strcmp(term, match)) {\n                                    res = 1\n                                    break;\n                            }\n\n>                 va_end(matches);\n>\n>                 return res;\n>         }\n"},{"id":"285469","messageId":"alpine.DEB.2.20.1605041416030.9313@virtualbox","threadId":"41774","inReplyTo":"CAP8UFD2k=JMYUg1SPE1TP6uD1bUnheYs8YhFDrzgEny85ocQFw@mail.gmail.com","subject":"Re: [PATCH 1/2] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-05-04T12:21:58Z","receivedAt":"2016-05-04T12:21:58Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Chris,\n\nOn Wed, 4 May 2016, Christian Couder wrote:\n\n> On Wed, May 4, 2016 at 1:05 PM, Johannes Schindelin\n> <Johannes.Schindelin@gmx.de> wrote:\n> \n> > So... why not just say \"bisect--helper: prepare for modes other than\n> > 'next-all'\"?\n> \n> For (an extreme) example, in my patch series about libifying \"git apply\"\n> functionality, should many of the patches have subjects like\n> \"builtin/apply: prepare for an apply.{c,h} lib\"?\n\nYou are deliberately misunderstanding me.\n\nIf your patch series contained *one* patch whose intent was to prepare for\na libified 'apply', yes, indeed, I would think that it would make for a\nfine commit subject. Especially if the other patches tried to do\ncompletely unrelated things. Then your \"low-level\" change would really\nbenefit from a \"high-level\" commit message: the \"low-level\" aspect is seen\neasily enough in the patch itself, thankyouverymuch.\n\nIt really misrepresents my comment to pretend that I had tried to\nsuggest something as utterly confusing as identically repeated commit\nsubjects.\n\nCiao,\nJohannes\n"},{"id":"285470","messageId":"CAP8UFD0QeZqLaPwFe5wo0n1fdtSppJmYdUDc+Yo1duH1uyWbpw@mail.gmail.com","threadId":"41774","inReplyTo":"alpine.DEB.2.20.1605041416030.9313@virtualbox","subject":"Re: [PATCH 1/2] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-04T12:41:32Z","receivedAt":"2016-05-04T12:41:32Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Hi Dscho,\n\nOn Wed, May 4, 2016 at 2:21 PM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> If your patch series contained *one* patch whose intent was to prepare for\n> a libified 'apply', yes, indeed, I would think that it would make for a\n> fine commit subject. Especially if the other patches tried to do\n> completely unrelated things. Then your \"low-level\" change would really\n> benefit from a \"high-level\" commit message: the \"low-level\" aspect is seen\n> easily enough in the patch itself, thankyouverymuch.\n\nOne can also say that if the long term intent is described in the\ncommit message and if the commit message is already \"high level\", then\na \"high level\" subject on top of it doesn't provide any more benefit.\nA \"high level\" subject on top can just make it harder to relate the\npatch, when you only see its subject, to what it contains.\n\n> It really misrepresents my comment to pretend that I had tried to\n> suggest something as utterly confusing as identically repeated commit\n> subjects.\n\nSorry but that was not my intent to suggest that. My intent was to try\nto show that there is some important value to make the subject close\nto the \"low level\" thing the patch actually does.\n\nThanks,\nChristian.\n"},{"id":"285472","messageId":"alpine.DEB.2.20.1605041654300.9313@virtualbox","threadId":"41774","inReplyTo":"CAP8UFD0QeZqLaPwFe5wo0n1fdtSppJmYdUDc+Yo1duH1uyWbpw@mail.gmail.com","subject":"Re: [PATCH 1/2] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-05-04T14:56:22Z","receivedAt":"2016-05-04T14:56:22Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Christian,\n\nOn Wed, 4 May 2016, Christian Couder wrote:\n\n> My intent was to try to show that there is some important value to make\n> the subject close to the \"low level\" thing the patch actually does.\n\nI disagree. The place to describe low-level details that are not\nimmediately obvious from the patch is the commit message. Way, way down on\nthe bottom.\n\nThe commit message should start with a subject that gives me a good clue\nwhy this is a good change. A low-level detail won't do that very often.\n\nCiao,\nJohannes\n"},{"id":"285478","messageId":"CAPig+cTXj2=iV0RnZU2Lpr3aqoqWOhPKNdpmOjdh+GocNHiP6g@mail.gmail.com","threadId":"41774","inReplyTo":"CAFZEwPNdmJdt=4Hg7KpfGS51sDeKyAPWgApESf564kt_eaP3Rg@mail.gmail.com","subject":"Re: [PATCH 2/2] bisect: rewrite `check_term_format` shell function in C","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2016-05-04T17:49:39Z","receivedAt":"2016-05-04T17:49:39Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Wed, May 4, 2016 at 7:58 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n> On Wed, May 4, 2016 at 1:58 PM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n>> On Wed, May 4, 2016 at 3:36 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>>> On Wed, May 4, 2016 at 12:22 PM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n>>>> On Wed, May 4, 2016 at 1:07 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>>>>> +       if (check_refname_format(new_term.buf, flag))\n>>>>> +               die(_(\"'%s' is not a valid term\\n\"), term);\n>>>>\n>>>> Why does this die() while the other \"invalid\" cases merely return\n>>>> error()? What makes this special?\n>>>\n>>> This is because I felt that if check_refname_format() fails then its a\n>>> fatal error while in other cases, it is not as fatal.\n>>\n>> The name of the command is \"check-term-format\" and that is precisely\n>> its purpose so, from the perspective of the caller, *all* problems\n>> with the term are fatal. It's black-and-white, there is no grey:\n>> either a term is acceptable, or it isn't; that's all the caller wants\n>> to know. Consequently, all problems detected by this function should\n>> be reported the same way (preferably via 'return error()').\n>\n> Sure. I will use 'return error()'. Any particular reason why this\n> instead of die() ?\n\nThis function's specific purpose is *check* some input for validity\nand let the caller know the result of that check. The most natural way\nto do so is by returning a success/failure value to the caller.\n\ndie() is for signalling an exceptional condition which should abort\nthe program. There is nothing exceptional about a \"false\" result from\ncheck-term-format, thus die() not an appropriate way to pass the\nresult to the caller.\n"},{"id":"285480","messageId":"CAFZEwPO6L_F+VuQ1TAOK8GonmAXqy7WH__-dS2xmvb_cuh0tpw@mail.gmail.com","threadId":"41774","inReplyTo":"CAPig+cTXj2=iV0RnZU2Lpr3aqoqWOhPKNdpmOjdh+GocNHiP6g@mail.gmail.com","subject":"Re: [PATCH 2/2] bisect: rewrite `check_term_format` shell function in C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-04T18:08:22Z","receivedAt":"2016-05-04T18:08:22Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"On Wed, May 4, 2016 at 11:19 PM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> On Wed, May 4, 2016 at 7:58 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>> On Wed, May 4, 2016 at 1:58 PM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n>>> On Wed, May 4, 2016 at 3:36 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>>>> On Wed, May 4, 2016 at 12:22 PM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n>>>>> On Wed, May 4, 2016 at 1:07 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>>>>>> +       if (check_refname_format(new_term.buf, flag))\n>>>>>> +               die(_(\"'%s' is not a valid term\\n\"), term);\n>>>>>\n>>>>> Why does this die() while the other \"invalid\" cases merely return\n>>>>> error()? What makes this special?\n>>>>\n>>>> This is because I felt that if check_refname_format() fails then its a\n>>>> fatal error while in other cases, it is not as fatal.\n>>>\n>>> The name of the command is \"check-term-format\" and that is precisely\n>>> its purpose so, from the perspective of the caller, *all* problems\n>>> with the term are fatal. It's black-and-white, there is no grey:\n>>> either a term is acceptable, or it isn't; that's all the caller wants\n>>> to know. Consequently, all problems detected by this function should\n>>> be reported the same way (preferably via 'return error()').\n>>\n>> Sure. I will use 'return error()'. Any particular reason why this\n>> instead of die() ?\n>\n> This function's specific purpose is *check* some input for validity\n> and let the caller know the result of that check. The most natural way\n> to do so is by returning a success/failure value to the caller.\n>\n> die() is for signalling an exceptional condition which should abort\n> the program. There is nothing exceptional about a \"false\" result from\n> check-term-format, thus die() not an appropriate way to pass the\n> result to the caller.\n\nThanks for the information! :)\n"},{"id":"285491","messageId":"CAP8UFD2qoCPkbDid+k6Lydh7JTM5VhQzxTSuJuRa40sw54_aZw@mail.gmail.com","threadId":"41774","inReplyTo":"alpine.DEB.2.20.1605041654300.9313@virtualbox","subject":"Re: [PATCH 1/2] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-04T19:07:23Z","receivedAt":"2016-05-04T19:07:23Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"Hi Dscho,\n\nOn Wed, May 4, 2016 at 4:56 PM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> Hi Christian,\n>\n> On Wed, 4 May 2016, Christian Couder wrote:\n>\n>> My intent was to try to show that there is some important value to make\n>> the subject close to the \"low level\" thing the patch actually does.\n>\n> I disagree. The place to describe low-level details that are not\n> immediately obvious from the patch is the commit message. Way, way down on\n> the bottom.\n>\n> The commit message should start with a subject that gives me a good clue\n> why this is a good change. A low-level detail won't do that very often.\n\nLet me give you another example.\n\nYou want to do X and you discover that you need to tweek knob foo to\ndo X, and also that tweeking knob foo is a good thing to do in general\n(for example it could be a refactoring that save some lines of code).\nSo you create a patch that tweeks knob foo and call it \"prepare to do\nX\", and then send it so that it can be merged. Then you want to do X\nbut you are interupted by an event, for example you boss tells you to\ndo Y instead of X right away because of an urgent business need. So\nyou do Y instead of X. And then sometimes later (it could be weeks,\nmonths or years later), when you are finished with Y, you now want to\ngo back to your previous work on X. At that time you discover that you\nneed to tweek knob bar (it could be another refactoring of another\npart of the code), but you forgot about your previous patch that\ntweeked knob foo, so you call your new patch that tweeks knob bar\n\"prepare to do X\". As your previous patch that was also called\n\"prepare to do X\" has already been integrated, you now have too\npatches that do different things that are called the same, and you can\neasily mistake the first one for the second one.\n\nIf you had just called your first patch \"tweek knob foo\" and the\nsecond patch \"tweek knob bar\", it would be much clearer which patch\ndoes what.\n"},{"id":"285493","messageId":"xmqqmvo5hc5z.fsf@gitster.mtv.corp.google.com","threadId":"41774","inReplyTo":"alpine.DEB.2.20.1605041309430.9313@virtualbox","subject":"Re: [PATCH 2/2] bisect: rewrite `check_term_format` shell function in C","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-05-04T19:10:32Z","receivedAt":"2016-05-04T19:10:32Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Johannes Schindelin <Johannes.Schindelin@gmx.de> writes:\n\n> Maybe something like instead?\n>\n> \tstatic int one_of(const char *term, ...)\n> \t{\n> \t\tint res = 0;\n> \t\tva_list matches;\n> \t\tconst char *match;\n>\n> \t\tva_start(matches, term);\n> \t\twhile (!res && (match = va_arg(matches, const char *)))\n> \t\t\tres = !strcmp(term, match);\n> \t\tva_end(matches);\n>\n> \t\treturn res;\n> \t}\n> Ciao,\n> Dscho\n\nThis looks good (even though we try to avoid assignment in\nconditionals as much as possible).\n"},{"id":"285707","messageId":"1462546167-1125-1-git-send-email-pranit.bauva@gmail.com","threadId":"41774","inReplyTo":"1462338472-3581-1-git-send-email-pranit.bauva@gmail.com","subject":"[PATCH v5 0/2] bisect--helper: rewrite of check-term-format()","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-06T14:49:25Z","receivedAt":"2016-05-06T14:49:25Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"A very interesting fact to note:\nI made a mistake by dropping of the first argument 'term' in the function\none_of() and compiled and the test suite passed fully (which was pointed\nout by Christian). This shows that the test coverage is incomplete. I am\ncurrently writing tests to improve on that coverage. It will be included\nseparately.\n\nLink to v4: http://thread.gmane.org/gmane.comp.version-control.git/293488\n\nChanges wrt v4:\n * Stick with 'subcommand' in the commit message.\n * Rename enum as 'subcommand' to make it singular.\n * s/bug/BUG/g\n * Drop _() in the default of switch case\n * Use some suggestions for commit message no. 2 and also include why I am\n   using subcommand.\n * Drop of the latter part in the comment of one_of()\n * Remove flag from check_term_format()\n * Use return error() instead of die()\n * Drop '\\n' from the localization strings\n * Include localization for a missed string\n * A comment in function check_term_format() is re-wrapped to fit in 80 columns\n * Use 'term' instead of 'ref'\n * Reword the string in the default of switch case\n * I have kept the commit message same as previous for commit no. 1 except for\n   addressing the minor nits.\n\nPranit Bauva (2):\n  bisect--helper: use OPT_CMDMODE instead of OPT_BOOL\n  bisect: rewrite `check_term_format` shell function in C\n\n builtin/bisect--helper.c | 76 ++++++++++++++++++++++++++++++++++++++++++++----\n git-bisect.sh            | 31 ++------------------\n 2 files changed, 72 insertions(+), 35 deletions(-)\n\n-- \n2.8.1\n"},{"id":"285708","messageId":"1462546167-1125-2-git-send-email-pranit.bauva@gmail.com","threadId":"41774","inReplyTo":"1462546167-1125-1-git-send-email-pranit.bauva@gmail.com","subject":"[PATCH v5 1/2] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-06T14:49:26Z","receivedAt":"2016-05-06T14:49:26Z","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\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 | 21 +++++++++++++++------\n 1 file changed, 15 insertions(+), 6 deletions(-)\n\ndiff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\nindex 3324229..d8de651 100644\n--- a/builtin/bisect--helper.c\n+++ b/builtin/bisect--helper.c\n@@ -8,13 +8,17 @@ static const char * const git_bisect_helper_usage[] = {\n \tNULL\n };\n \n+enum subcommand {\n+\tNEXT_ALL = 1\n+};\n+\n int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n {\n-\tint next_all = 0;\n+\tint subcommand = 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\", &subcommand,\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 +27,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 (!subcommand)\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 (subcommand) {\n+\tcase NEXT_ALL:\n+\t\treturn bisect_next_all(prefix, no_checkout);\n+\tdefault:\n+\t\tdie(\"BUG: unknown subcommand '%d'\", subcommand);\n+\t}\n+\treturn 0;\n }\n-- \n2.8.1\n"},{"id":"285709","messageId":"1462546167-1125-3-git-send-email-pranit.bauva@gmail.com","threadId":"41774","inReplyTo":"1462546167-1125-1-git-send-email-pranit.bauva@gmail.com","subject":"[PATCH v5 2/2] bisect: rewrite `check_term_format` shell function in C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-06T14:49:27Z","receivedAt":"2016-05-06T14:49:27Z","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 loose its existence 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 | 57 +++++++++++++++++++++++++++++++++++++++++++++++-\n git-bisect.sh            | 31 ++------------------------\n 2 files changed, 58 insertions(+), 30 deletions(-)\n\ndiff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\nindex d8de651..cc50438 100644\n--- a/builtin/bisect--helper.c\n+++ b/builtin/bisect--helper.c\n@@ -2,16 +2,65 @@\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 enum subcommand {\n-\tNEXT_ALL = 1\n+\tNEXT_ALL = 1,\n+\tCHECK_TERM_FMT\n };\n \n+/*\n+ * To 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 \tint subcommand = 0;\n@@ -19,6 +68,8 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \tstruct option options[] = {\n \t\tOPT_CMDMODE(0, \"next-all\", &subcommand,\n \t\t\t N_(\"perform 'git bisect next'\"), NEXT_ALL),\n+\t\tOPT_CMDMODE(0, \"check-term-format\", &subcommand,\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@@ -33,6 +84,10 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n \tswitch (subcommand) {\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'\", subcommand);\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.8.1\n"},{"id":"285786","messageId":"xmqqtwia25qc.fsf@gitster.mtv.corp.google.com","threadId":"41774","inReplyTo":"1462546167-1125-1-git-send-email-pranit.bauva@gmail.com","subject":"Re: [PATCH v5 0/2] bisect--helper: rewrite of check-term-format()","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-05-06T22:15:23Z","receivedAt":"2016-05-06T22:15:23Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Pranit Bauva <pranit.bauva@gmail.com> writes:\n\n> A very interesting fact to note:\n> I made a mistake by dropping of the first argument 'term' in the function\n> one_of() and compiled and the test suite passed fully (which was pointed\n> out by Christian). This shows that the test coverage is incomplete. \n> I am\n> currently writing tests to improve on that coverage. It will be included\n> separately.\n>\n> Link to v4: http://thread.gmane.org/gmane.comp.version-control.git/293488\n>\n> Changes wrt v4:\n>  * Stick with 'subcommand' in the commit message.\n>  * Rename enum as 'subcommand' to make it singular.\n\nI've already said what needs to be said on this.\n\n>  * s/bug/BUG/g\n>  * Drop _() in the default of switch case\n>  * Use some suggestions for commit message no. 2 and also include why I am\n>    using subcommand.\n\nI am not particularly impressed by the rationale, though.\n\nAs a starter project to show that you learned how to add a new mode\nto bisect--helper, check-term-format may be a small enough function\nthat is easy to dip the toe into the codebase, so in that sense it\nmay be an appropriate first step, but otherwise it is not all that\ninteresting, especially when we _know_ that it will be discarded.\n"},{"id":"285791","messageId":"CAPig+cSc-k-+41=mspJ_XS+cZXn-rM+h_tSSGVobU+gH6fxxEg@mail.gmail.com","threadId":"41774","inReplyTo":"1462546167-1125-3-git-send-email-pranit.bauva@gmail.com","subject":"Re: [PATCH v5 2/2] bisect: rewrite `check_term_format` shell function in C","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2016-05-07T00:05:55Z","receivedAt":"2016-05-07T00:05:55Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Fri, May 6, 2016 at 10:49 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n> Reimplement the `check_term_format` shell function in C and add\n> a `--check-term-format` subcommand to `git bisect--helper` to call it\n> from git-bisect.sh\n>\n> Using `--check-term-format` subcommand is a temporary measure to port\n> shell function to C so as to use the existing test suite. As more\n> functions are ported, this subcommand will loose its existence and will\n\ns/loose/lose/\n\nThough, maybe it would be better to say:\n\n    ...this subcommand will be retired...\n\n> be called by some other method/subcommand. For eg. In conversion of\n> write_terms() of git-bisect.sh, the subcommand will be removed and\n> instead check_term_format() will be called in its C implementation while\n> a new subcommand will be introduced for write_terms().\n>\n> Signed-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n> ---\n> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\n> @@ -2,16 +2,65 @@\n> +/*\n> + * To check whether the string `term` belongs to the set of strings\n> + * included in the variable arguments.\n\nThis is still a sentence fragment as pointed out last time[1]. You can\nfix it with: s/To check/Check/\n\n> + */\n> +static int one_of(const char *term, ...)\n> +{\n> +       int res = 0;\n> +       va_list matches;\n> +       const char *match;\n> +\n> +       va_start(matches, term);\n> +       while (!res && (match=va_arg(matches, const char *)))\n\nStyle: add spaces around '='\n\n> +               res = !strcmp(term, match);\n> +       va_end(matches);\n> +\n> +       return res;\n> +}\n\nThe rest of the patch seems to address the issues raised by my\nprevious review[1] (aside from my comments[1,2] about this bottom-up\napproach repeatedly adding and removing unnecessary complexity as each\nlittle function is ported from shell to C, but that's a separate\nphilosophical discussion).\n\n[1]: http://thread.gmane.org/gmane.comp.version-control.git/289476/focus=293501\n[2]: http://thread.gmane.org/gmane.comp.version-control.git/289476/focus=293517\n"},{"id":"285816","messageId":"CAFZEwPOA9c8eQAacnuB1n=juOhN1zsMdzcupS3ijqwYFPRrW4A@mail.gmail.com","threadId":"41774","inReplyTo":"xmqqtwia25qc.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v5 0/2] bisect--helper: rewrite of check-term-format()","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-07T13:07:50Z","receivedAt":"2016-05-07T13:07:50Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"On Sat, May 7, 2016 at 3:45 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Pranit Bauva <pranit.bauva@gmail.com> writes:\n>\n>> A very interesting fact to note:\n>> I made a mistake by dropping of the first argument 'term' in the function\n>> one_of() and compiled and the test suite passed fully (which was pointed\n>> out by Christian). This shows that the test coverage is incomplete.\n>> I am\n>> currently writing tests to improve on that coverage. It will be included\n>> separately.\n>>\n>> Link to v4: http://thread.gmane.org/gmane.comp.version-control.git/293488\n>>\n>> Changes wrt v4:\n>>  * Stick with 'subcommand' in the commit message.\n>>  * Rename enum as 'subcommand' to make it singular.\n>\n> I've already said what needs to be said on this.\n>\n>>  * s/bug/BUG/g\n>>  * Drop _() in the default of switch case\n>>  * Use some suggestions for commit message no. 2 and also include why I am\n>>    using subcommand.\n>\n> I am not particularly impressed by the rationale, though.\n>\n> As a starter project to show that you learned how to add a new mode\n> to bisect--helper, check-term-format may be a small enough function\n> that is easy to dip the toe into the codebase, so in that sense it\n> may be an appropriate first step, but otherwise it is not all that\n> interesting, especially when we _know_ that it will be discarded.\n\nI do understand that check-term-format was a suggestion just for me to\n\"Get a taste\" for the project.\nI have now also converted write_terms() function. I have made a PR[1]\nwhich needs a few things to be addressed.\nJust a summary of what the PR does:\n * Converts the shell function write() terms to C\n * Adds a subcommand for write_terms()\n * Remove the subcommand for check_term_format()\n * Call the method check_term_format() from inside write_terms().\n\nDo you want me to include both of the functions check_term_format()\nand write_terms() in the same commit or a different commit.\n\nOR,\nI completely missed your point and you want me to go the Eric Sunshine's way?\n\n[1]: https://github.com/pranitbauva1997/git/pull/3\n"},{"id":"285830","messageId":"xmqq60up1e24.fsf@gitster.mtv.corp.google.com","threadId":"41774","inReplyTo":"CAFZEwPOA9c8eQAacnuB1n=juOhN1zsMdzcupS3ijqwYFPRrW4A@mail.gmail.com","subject":"Re: [PATCH v5 0/2] bisect--helper: rewrite of check-term-format()","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-05-08T02:25:23Z","receivedAt":"2016-05-08T02:25:23Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Pranit Bauva <pranit.bauva@gmail.com> writes:\n\n> I completely missed your point and you want me to go the Eric Sunshine's way?\n\nI am neutral.\n\nWhen I read your response to Eric's \"top down\" suggestion, I didn't\nquite get much more than \"I started going this way, and I do not\nwant to change to the other direction.\", which was what I had the\nmost trouble with.  If your justification for the approach to start\nfrom building a tiny bottom layer that will need to be dismantled\nsoon and repeat that (which sounds somewhat wasteful) were more\nconvincing, I may have felt differently.\n"},{"id":"285831","messageId":"CAFZEwPML8MCAL2quAN3ExMFXrhjS07g3KEC-WuSfYAXc2WQKuQ@mail.gmail.com","threadId":"41774","inReplyTo":"xmqq60up1e24.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v5 0/2] bisect--helper: rewrite of check-term-format()","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-08T06:23:53Z","receivedAt":"2016-05-08T06:23:53Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"On Sun, May 8, 2016 at 7:55 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Pranit Bauva <pranit.bauva@gmail.com> writes:\n>\n>> I completely missed your point and you want me to go the Eric Sunshine's way?\n>\n> I am neutral.\n>\n> When I read your response to Eric's \"top down\" suggestion, I didn't\n> quite get much more than \"I started going this way, and I do not\n> want to change to the other direction.\", which was what I had the\n> most trouble with.  If your justification for the approach to start\n> from building a tiny bottom layer that will need to be dismantled\n> soon and repeat that (which sounds somewhat wasteful) were more\n> convincing, I may have felt differently.\n\nSorry if it seemed that \"I have done quite some work and I don't want\nto scrape it off and redo everything\". This isn't a case for me. I\nthink of this as just a small part in the process of learning and my\nefforts would be completely wasted as I can still reuse the methods I\nwrote. This is still open for a \"philosophical\" discussion. I am\nassuming 1e1ea69fa4e is how Eric is suggesting.\n\nWhy I think its better to go the subcommand way:\n * I can test **C implementation** of the function to verify whether\nit was done in a proper way. By using a \"top down\" approach, I can\nmake the test suite passing by running the code from git-bisect.sh not\nthe re-written C code.\n * I have made a very few minor mistakes in conversion of\ncheck_term_format() which just messed up my head (I actually spent 3\ndays before Christian pointed out that '!' was missing). Imagine\ndebugging the complete git-bisect.sh to find a very small error after\na complete implementation.\n * Using subcommands, I can easily verify whether I have done it the\nright way or not.\n * It makes the review process very simple. The reviewers/testers can\nverify that my method is working correctly and well computers can\ndetect errors better than humans.\n * I can convert small functions which can be reviewed easily rather\nthan dumping a big series.\n\nWhat I think is that the bottom up approach will make life easier for\nthe me and for reviewer. Yes, it does make the code \"unclean\" for the\ntime being and if it is between releases then all the more painful.\nWell, the latter part can be avoided by keeping it in next.\n\nPlease point out if I am mistaken about anything.\n\nRegards,\nPranit Bauva\n"},{"id":"285834","messageId":"alpine.DEB.2.20.1605080841520.4092@virtualbox","threadId":"41774","inReplyTo":"CAP8UFD2qoCPkbDid+k6Lydh7JTM5VhQzxTSuJuRa40sw54_aZw@mail.gmail.com","subject":"Re: [PATCH 1/2] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-05-08T06:54:40Z","receivedAt":"2016-05-08T06:54:40Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Chris,\n\nOn Wed, 4 May 2016, Christian Couder wrote:\n\n> On Wed, May 4, 2016 at 4:56 PM, Johannes Schindelin\n> <Johannes.Schindelin@gmx.de> wrote:\n> >\n> > On Wed, 4 May 2016, Christian Couder wrote:\n> >\n> >> My intent was to try to show that there is some important value to make\n> >> the subject close to the \"low level\" thing the patch actually does.\n> >\n> > I disagree. The place to describe low-level details that are not\n> > immediately obvious from the patch is the commit message. Way, way down on\n> > the bottom.\n> >\n> > The commit message should start with a subject that gives me a good clue\n> > why this is a good change. A low-level detail won't do that very often.\n> \n> Let me give you another example.\n> \n> You want to do X and you discover that you need to tweek knob foo to\n> do X, and also that tweeking knob foo is a good thing to do in general\n> (for example it could be a refactoring that save some lines of code).\n> So you create a patch that tweeks knob foo and call it \"prepare to do\n> X\", and then send it so that it can be merged. Then you want to do X\n> but you are interupted by an event, for example you boss tells you to\n> do Y instead of X right away because of an urgent business need. So\n> you do Y instead of X. And then sometimes later (it could be weeks,\n> months or years later), when you are finished with Y, you now want to\n> go back to your previous work on X. At that time you discover that you\n> need to tweek knob bar (it could be another refactoring of another\n> part of the code), but you forgot about your previous patch that\n> tweeked knob foo, so you call your new patch that tweeks knob bar\n> \"prepare to do X\". As your previous patch that was also called\n> \"prepare to do X\" has already been integrated, you now have too\n> patches that do different things that are called the same, and you can\n> easily mistake the first one for the second one.\n> \n> If you had just called your first patch \"tweek knob foo\" and the\n> second patch \"tweek knob bar\", it would be much clearer which patch\n> does what.\n\nAnd then, six months later, when *you* are stuck in a plane and bisect a\nproblem down to my \"tweak knob foo\", you curse at me, asking fellow\npassengers \"what was Dscho thinking? 'foo'? What the hell is 'foo'\nsupposed to mean? And what was the *intention* of this patch? There is a\nbug! And now I cannot fix it properly because I do not understand what the\npatch was intended to do!\".\n\nDo not believe even one second this scenario s foreign to *me*. Even with\nsome of git.git's commits whose messages were so in love with low-level\ndetails, essentially repeating what the diff already told me, that they\nforgot to include the context, the big picture, leaving me puzzled and\nfrustrated.\n\nAnd my fellow passengers, too.\n\nThis puzzlement and frustration is unnecessary. I typically follow Peff's\nexamples. They typically do a good job of telling me right away what the\nbig picture is, even if they are in the middle of a patch series, not\nworrying too much whether adjacent commits say related things, without\nforgetting low-level details. The crucial point is that they start out by\nassuming little familiarity of the reader with the context.\n\nIn short: you can have both. The commit message *can* be informative, and\n*still* contain low-level details. You simply start with the former and\nease the reader into the latter, instead of skipping the first part, is\nall.\n\nCiao,\nJohannes\n"},{"id":"285835","messageId":"alpine.DEB.2.20.1605080858190.4092@virtualbox","threadId":"41774","inReplyTo":"1462546167-1125-2-git-send-email-pranit.bauva@gmail.com","subject":"Re: [PATCH v5 1/2] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-05-08T07:04:12Z","receivedAt":"2016-05-08T07:04:12Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Pranit,\n\nOn Fri, 6 May 2016, Pranit Bauva wrote:\n\n> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\n> index 3324229..d8de651 100644\n> --- a/builtin/bisect--helper.c\n> +++ b/builtin/bisect--helper.c\n> @@ -8,13 +8,17 @@ static const char * const git_bisect_helper_usage[] = {\n>  \tNULL\n>  };\n>  \n> +enum subcommand {\n> +\tNEXT_ALL = 1\n> +};\n\nI still do not think that this enum needs to have file scope. Function\nscope is enough.\n\n>  int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>  {\n> -\tint next_all = 0;\n> +\tint subcommand = 0;\n\nSince subcommand is not simply an integer, but wants to take on the values\ndefined in the enum above, the type should be changed accordingly. You\ncould do it this way (short and sweet, with the appropriate scope):\n\n\tenum { NEXT_ALL = 1 } subcommand = 0;\n\nSee https://github.com/git/git/blob/v2.8.2/builtin/replace.c#L423-L430 for\nan example (which uses \"cmdmode\" instead of \"subcommand\", too).\n\nCiao,\nDscho\n"},{"id":"285836","messageId":"CAFZEwPOy5avk=3WKj0AdP-j7Ump4ie90+CeFTj6K83EMj-pQQA@mail.gmail.com","threadId":"41774","inReplyTo":"alpine.DEB.2.20.1605080858190.4092@virtualbox","subject":"Re: [PATCH v5 1/2] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-08T07:17:23Z","receivedAt":"2016-05-08T07:17:23Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"On Sun, May 8, 2016 at 12:34 PM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> Hi Pranit,\n>\n> On Fri, 6 May 2016, Pranit Bauva wrote:\n>\n>> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\n>> index 3324229..d8de651 100644\n>> --- a/builtin/bisect--helper.c\n>> +++ b/builtin/bisect--helper.c\n>> @@ -8,13 +8,17 @@ static const char * const git_bisect_helper_usage[] = {\n>>       NULL\n>>  };\n>>\n>> +enum subcommand {\n>> +     NEXT_ALL = 1\n>> +};\n>\n> I still do not think that this enum needs to have file scope. Function\n> scope is enough.\n\nIn the very initial patch I made it in function scope. To which you\npointed out[1] that in all other examples but for one have file scope\nso then I thought maybe that exception was a wrong example and I\nshould stick to the convention of putting it in file scope. But now I\nalso realize that builtin/replace.c uses \"cmdmode\" instead of\n\"subcommand\" so I am still wondering what would be the most\nappropriate?\n\n>>  int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>>  {\n>> -     int next_all = 0;\n>> +     int subcommand = 0;\n>\n> Since subcommand is not simply an integer, but wants to take on the values\n> defined in the enum above, the type should be changed accordingly. You\n> could do it this way (short and sweet, with the appropriate scope):\n>\n>         enum { NEXT_ALL = 1 } subcommand = 0;\n>\n> See https://github.com/git/git/blob/v2.8.2/builtin/replace.c#L423-L430 for\n> an example (which uses \"cmdmode\" instead of \"subcommand\", too).\n>\n> Ciao,\n> Dscho\n[1]: http://article.gmane.org/gmane.comp.version-control.git/289653\n\nRegards,\nPranit Bauva\n"},{"id":"285889","messageId":"CAFZEwPPZJqGHsHk0RLzo-pA8rUN0VP9-ricycNOnGbhO=2JZgg@mail.gmail.com","threadId":"41774","inReplyTo":"CAFZEwPML8MCAL2quAN3ExMFXrhjS07g3KEC-WuSfYAXc2WQKuQ@mail.gmail.com","subject":"Re: [PATCH v5 0/2] bisect--helper: rewrite of check-term-format()","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-08T13:34:54Z","receivedAt":"2016-05-08T13:34:54Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"On Sun, May 8, 2016 at 11:53 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n> On Sun, May 8, 2016 at 7:55 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>> Pranit Bauva <pranit.bauva@gmail.com> writes:\n>>\n>>> I completely missed your point and you want me to go the Eric Sunshine's way?\n>>\n>> I am neutral.\n>>\n>> When I read your response to Eric's \"top down\" suggestion, I didn't\n>> quite get much more than \"I started going this way, and I do not\n>> want to change to the other direction.\", which was what I had the\n>> most trouble with.  If your justification for the approach to start\n>> from building a tiny bottom layer that will need to be dismantled\n>> soon and repeat that (which sounds somewhat wasteful) were more\n>> convincing, I may have felt differently.\n>\n> Sorry if it seemed that \"I have done quite some work and I don't want\n> to scrape it off and redo everything\". This isn't a case for me. I\n> think of this as just a small part in the process of learning and my\n> efforts would be completely wasted as I can still reuse the methods I\n\nefforts would **not** be completely wasted\n\n> wrote. This is still open for a \"philosophical\" discussion. I am\n> assuming 1e1ea69fa4e is how Eric is suggesting.\n>\n> Why I think its better to go the subcommand way:\n>  * I can test **C implementation** of the function to verify whether\n> it was done in a proper way. By using a \"top down\" approach, I can\n> make the test suite passing by running the code from git-bisect.sh not\n> the re-written C code.\n>  * I have made a very few minor mistakes in conversion of\n> check_term_format() which just messed up my head (I actually spent 3\n> days before Christian pointed out that '!' was missing). Imagine\n> debugging the complete git-bisect.sh to find a very small error after\n> a complete implementation.\n>  * Using subcommands, I can easily verify whether I have done it the\n> right way or not.\n>  * It makes the review process very simple. The reviewers/testers can\n> verify that my method is working correctly and well computers can\n> detect errors better than humans.\n>  * I can convert small functions which can be reviewed easily rather\n> than dumping a big series.\n>\n> What I think is that the bottom up approach will make life easier for\n> the me and for reviewer. Yes, it does make the code \"unclean\" for the\n> time being and if it is between releases then all the more painful.\n> Well, the latter part can be avoided by keeping it in next.\n>\n> Please point out if I am mistaken about anything.\n\nThere is also a third way in which I can go which is kind of merge of\nboth the ways:\n\n * Make two branches, one will contain the top down approach and\nanother will contain the subcommand approach.\n\n * I will write convert a function as a subcommand and test it locally\nas well as on Travis-Cl by a PR on my git.git repo. The\nreviewers/testers can consult the Travis-CI for output of the tests.\nThis will also reduce the need of locally compiling/testing.\n\n * I will then just write the function as it is in my \"top down\"\nbranch and thus send the patch to the mailing list. These can be kept\nin next until it finishes.\n\n * Then will remove linking of git-bisect.sh and thus finalize.\n\nThis will be a bit more intensive not in a coding way but in\nmaintaining the repo. So I will have more experience of maintaining a\ngit repo. :)\n\nRegards,\nPranit Bauva\n"},{"id":"285890","messageId":"CAP8UFD1PqU+WeuDp0f0_yyrYsGt=qwbkTUXji4_DJiJoGf_nJg@mail.gmail.com","threadId":"41774","inReplyTo":"CAFZEwPOy5avk=3WKj0AdP-j7Ump4ie90+CeFTj6K83EMj-pQQA@mail.gmail.com","subject":"Re: [PATCH v5 1/2] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-08T15:30:11Z","receivedAt":"2016-05-08T15:30:11Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Sun, May 8, 2016 at 9:17 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n> On Sun, May 8, 2016 at 12:34 PM, Johannes Schindelin\n> <Johannes.Schindelin@gmx.de> wrote:\n>> Hi Pranit,\n>>\n>> On Fri, 6 May 2016, Pranit Bauva wrote:\n>>\n>>> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\n>>> index 3324229..d8de651 100644\n>>> --- a/builtin/bisect--helper.c\n>>> +++ b/builtin/bisect--helper.c\n>>> @@ -8,13 +8,17 @@ static const char * const git_bisect_helper_usage[] = {\n>>>       NULL\n>>>  };\n>>>\n>>> +enum subcommand {\n>>> +     NEXT_ALL = 1\n>>> +};\n>>\n>> I still do not think that this enum needs to have file scope. Function\n>> scope is enough.\n>\n> In the very initial patch I made it in function scope. To which you\n> pointed out[1] that in all other examples but for one have file scope\n> so then I thought maybe that exception was a wrong example and I\n> should stick to the convention of putting it in file scope.\n\nIn the message Dscho wrote:\n\n\"Interesting. I did not think that Git's source code declares enums inside\nfunctions, but builtin/remote.c's config_read_branches() does, so this\ncode is fine.\" So you didn't need to put it back in file scope.\n\nPlease don't change things when you are told they are fine unless\nthere is a good reason like a bug and in this case explain the reason.\n\n> But now I\n> also realize that builtin/replace.c uses \"cmdmode\" instead of\n> \"subcommand\" so I am still wondering what would be the most\n> appropriate?\n>\n>>>  int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>>>  {\n>>> -     int next_all = 0;\n>>> +     int subcommand = 0;\n>>\n>> Since subcommand is not simply an integer, but wants to take on the values\n>> defined in the enum above, the type should be changed accordingly. You\n>> could do it this way (short and sweet, with the appropriate scope):\n>>\n>>         enum { NEXT_ALL = 1 } subcommand = 0;\n>>\n>> See https://github.com/git/git/blob/v2.8.2/builtin/replace.c#L423-L430 for\n>> an example (which uses \"cmdmode\" instead of \"subcommand\", too).\n\nYeah, please use \"cmdmode\" as Junio already suggested and do it like\nin the example that Dscho points to.\n\nThanks,\nChristian.\n"},{"id":"285891","messageId":"CAFZEwPPsY=kf7KjmyGk6xcwzT8Yi_oAQiFAUWNLcU00WZT-1+w@mail.gmail.com","threadId":"41774","inReplyTo":"CAP8UFD1PqU+WeuDp0f0_yyrYsGt=qwbkTUXji4_DJiJoGf_nJg@mail.gmail.com","subject":"Re: [PATCH v5 1/2] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-08T15:33:29Z","receivedAt":"2016-05-08T15:33:29Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"On Sun, May 8, 2016 at 9:00 PM, Christian Couder\n<christian.couder@gmail.com> wrote:\n> On Sun, May 8, 2016 at 9:17 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>> On Sun, May 8, 2016 at 12:34 PM, Johannes Schindelin\n>> <Johannes.Schindelin@gmx.de> wrote:\n>>> Hi Pranit,\n>>>\n>>> On Fri, 6 May 2016, Pranit Bauva wrote:\n>>>\n>>>> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\n>>>> index 3324229..d8de651 100644\n>>>> --- a/builtin/bisect--helper.c\n>>>> +++ b/builtin/bisect--helper.c\n>>>> @@ -8,13 +8,17 @@ static const char * const git_bisect_helper_usage[] = {\n>>>>       NULL\n>>>>  };\n>>>>\n>>>> +enum subcommand {\n>>>> +     NEXT_ALL = 1\n>>>> +};\n>>>\n>>> I still do not think that this enum needs to have file scope. Function\n>>> scope is enough.\n>>\n>> In the very initial patch I made it in function scope. To which you\n>> pointed out[1] that in all other examples but for one have file scope\n>> so then I thought maybe that exception was a wrong example and I\n>> should stick to the convention of putting it in file scope.\n>\n> In the message Dscho wrote:\n>\n> \"Interesting. I did not think that Git's source code declares enums inside\n> functions, but builtin/remote.c's config_read_branches() does, so this\n> code is fine.\" So you didn't need to put it back in file scope.\n>\n> Please don't change things when you are told they are fine unless\n> there is a good reason like a bug and in this case explain the reason.\n\nI will keep this in mind.\n\n>> But now I\n>> also realize that builtin/replace.c uses \"cmdmode\" instead of\n>> \"subcommand\" so I am still wondering what would be the most\n>> appropriate?\n>>\n>>>>  int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>>>>  {\n>>>> -     int next_all = 0;\n>>>> +     int subcommand = 0;\n>>>\n>>> Since subcommand is not simply an integer, but wants to take on the values\n>>> defined in the enum above, the type should be changed accordingly. You\n>>> could do it this way (short and sweet, with the appropriate scope):\n>>>\n>>>         enum { NEXT_ALL = 1 } subcommand = 0;\n>>>\n>>> See https://github.com/git/git/blob/v2.8.2/builtin/replace.c#L423-L430 for\n>>> an example (which uses \"cmdmode\" instead of \"subcommand\", too).\n>\n> Yeah, please use \"cmdmode\" as Junio already suggested and do it like\n> in the example that Dscho points to.\n\nYes sure!\n\n> Thanks,\n> Christian.\n"},{"id":"285920","messageId":"alpine.DEB.2.20.1605091657290.4092@virtualbox","threadId":"41774","inReplyTo":"CAFZEwPOy5avk=3WKj0AdP-j7Ump4ie90+CeFTj6K83EMj-pQQA@mail.gmail.com","subject":"Re: [PATCH v5 1/2] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-05-09T14:59:41Z","receivedAt":"2016-05-09T14:59:41Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Pranit,\n\nOn Sun, 8 May 2016, Pranit Bauva wrote:\n\n> On Sun, May 8, 2016 at 12:34 PM, Johannes Schindelin\n> <Johannes.Schindelin@gmx.de> wrote:\n> >\n> > On Fri, 6 May 2016, Pranit Bauva wrote:\n> >\n> >> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\n> >> index 3324229..d8de651 100644\n> >> --- a/builtin/bisect--helper.c\n> >> +++ b/builtin/bisect--helper.c\n> >> @@ -8,13 +8,17 @@ static const char * const git_bisect_helper_usage[] = {\n> >>       NULL\n> >>  };\n> >>\n> >> +enum subcommand {\n> >> +     NEXT_ALL = 1\n> >> +};\n> >\n> > I still do not think that this enum needs to have file scope. Function\n> > scope is enough.\n> \n> In the very initial patch I made it in function scope. To which you\n> pointed out[1] that in all other examples but for one have file scope\n> so then I thought maybe that exception was a wrong example and I\n> should stick to the convention of putting it in file scope.\n\nOh, sorry, I meant to imply that it is good as it is by saying \"so this\ncode is fine\"...\n\nI was just surprised because I thought I remembered that some old C\nstandard does not allow enums to be function scoped. But I was wrong.\n\n> But now I also realize that builtin/replace.c uses \"cmdmode\" instead of\n> \"subcommand\" so I am still wondering what would be the most appropriate?\n\nI think the replace.c code is really a good example. Function-scoped,\nusing the \"cmdmode\" name that obviously corresponds to the OPT_CMDMODE\nname.\n\nCiao,\nDscho\n"},{"id":"285923","messageId":"CAFZEwPNgEHOYhdqaX6W=_j7OUoBbX-=fHBLndGYO20OZjRUx2w@mail.gmail.com","threadId":"41774","inReplyTo":"alpine.DEB.2.20.1605091657290.4092@virtualbox","subject":"Re: [PATCH v5 1/2] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-09T15:33:34Z","receivedAt":"2016-05-09T15:33:34Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"Hey Johannes,\n\nOn Mon, May 9, 2016 at 8:29 PM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> Hi Pranit,\n>\n> On Sun, 8 May 2016, Pranit Bauva wrote:\n>\n>> On Sun, May 8, 2016 at 12:34 PM, Johannes Schindelin\n>> <Johannes.Schindelin@gmx.de> wrote:\n>> >\n>> > On Fri, 6 May 2016, Pranit Bauva wrote:\n>> >\n>> >> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\n>> >> index 3324229..d8de651 100644\n>> >> --- a/builtin/bisect--helper.c\n>> >> +++ b/builtin/bisect--helper.c\n>> >> @@ -8,13 +8,17 @@ static const char * const git_bisect_helper_usage[] = {\n>> >>       NULL\n>> >>  };\n>> >>\n>> >> +enum subcommand {\n>> >> +     NEXT_ALL = 1\n>> >> +};\n>> >\n>> > I still do not think that this enum needs to have file scope. Function\n>> > scope is enough.\n>>\n>> In the very initial patch I made it in function scope. To which you\n>> pointed out[1] that in all other examples but for one have file scope\n>> so then I thought maybe that exception was a wrong example and I\n>> should stick to the convention of putting it in file scope.\n>\n> Oh, sorry, I meant to imply that it is good as it is by saying \"so this\n> code is fine\"...\n>\n> I was just surprised because I thought I remembered that some old C\n> standard does not allow enums to be function scoped. But I was wrong.\n>\n>> But now I also realize that builtin/replace.c uses \"cmdmode\" instead of\n>> \"subcommand\" so I am still wondering what would be the most appropriate?\n>\n> I think the replace.c code is really a good example. Function-scoped,\n> using the \"cmdmode\" name that obviously corresponds to the OPT_CMDMODE\n> name.\n\nSure. WIll do!\n\nRegards,\nPranit Bauva\n"},{"id":"286310","messageId":"1463031127-17718-1-git-send-email-pranit.bauva@gmail.com","threadId":"41774","inReplyTo":"1462546167-1125-1-git-send-email-pranit.bauva@gmail.com","subject":"[PATCH v6 0/3] bisect--helper: check_term_format() & write_terms()","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-12T05:32:04Z","receivedAt":"2016-05-12T05:32:04Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"To show how I am going to approach conversion of shell function to its C\nimplementation by using the subcommand/cmdmode approach, I have first converted\ncheck_terms_format() to a subcommand then I have converted write_terms() to\na subcommand and then remove the subcommand for check_terms_format() and\ninstead call that function from write_terms().\n\nAlso I investigated about the test coverage which I mentioned in my previous\nversion and there is nothing that could be done to improve it.\n\nMinor changes wrt v5:\n * Use the term cmdmode instead of subcommand as pointed out by Junio. (I\n   didn't understand his response in v4 then Christian and Johannes pointed\n   it out to me what he meant).\n * Move the enum cmdmode (for subcommand) to function scope as suggested by\n   Johannes Schindelin.\n * A few minor nits by Eric Sunshine.\n\nLink for v5: http://thread.gmane.org/gmane.comp.version-control.git/293785\n\nPranit Bauva (3):\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\n builtin/bisect--helper.c | 97 +++++++++++++++++++++++++++++++++++++++++++++---\n git-bisect.sh            | 49 ++++--------------------\n 2 files changed, 98 insertions(+), 48 deletions(-)\n\n-- \n2.8.2\n"},{"id":"286309","messageId":"1463031127-17718-2-git-send-email-pranit.bauva@gmail.com","threadId":"41774","inReplyTo":"1463031127-17718-1-git-send-email-pranit.bauva@gmail.com","subject":"[PATCH v6 1/3] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-12T05:32:05Z","receivedAt":"2016-05-12T05:32:05Z","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.8.2\n"},{"id":"286311","messageId":"1463031127-17718-3-git-send-email-pranit.bauva@gmail.com","threadId":"41774","inReplyTo":"1463031127-17718-1-git-send-email-pranit.bauva@gmail.com","subject":"[PATCH v6 2/3] bisect: rewrite `check_term_format` shell function in C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-12T05:32:06Z","receivedAt":"2016-05-12T05:32: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.8.2\n"},{"id":"286312","messageId":"1463031127-17718-4-git-send-email-pranit.bauva@gmail.com","threadId":"41774","inReplyTo":"1463031127-17718-1-git-send-email-pranit.bauva@gmail.com","subject":"[PATCH v6 3/3] bisect--helper: `write_terms` shell function in C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-12T05:32:07Z","receivedAt":"2016-05-12T05:32: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\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 | 37 ++++++++++++++++++++++++++++++-------\n git-bisect.sh            | 22 +++++++---------------\n 2 files changed, 37 insertions(+), 22 deletions(-)\n\ndiff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\nindex 3c748d1..2b21c02 100644\n--- a/builtin/bisect--helper.c\n+++ b/builtin/bisect--helper.c\n@@ -6,7 +6,7 @@\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 +56,41 @@ static int check_term_format(const char *term, const char *orig_term)\n \treturn 0;\n }\n \n+int write_terms(const char *bad, const char *good)\n+{\n+\tstruct strbuf content = STRBUF_INIT;\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+\tstrbuf_addf(&content, \"%s\\n%s\\n\", bad, good);\n+\tfp = fopen(\".git/BISECT_TERMS\", \"w\");\n+\tif (!fp){\n+\t\tstrbuf_release(&content);\n+\t\tdie_errno(_(\"could not open the file to read terms\"));\n+\t}\n+\tres = strbuf_write(&content, fp);\n+\tfclose(fp);\n+\tstrbuf_release(&content);\n+\treturn (res < 0) ? -1 : 0;\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 +105,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..2dd7ec5 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\"\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\"\n \t\t\tfi\n \t\t\t;;\n \t\tesac ;;\n-- \n2.8.2\n"},{"id":"286408","messageId":"xmqq37pmdhtk.fsf@gitster.mtv.corp.google.com","threadId":"41774","inReplyTo":"1463031127-17718-3-git-send-email-pranit.bauva@gmail.com","subject":"Re: [PATCH v6 2/3] bisect: rewrite `check_term_format` shell function in C","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-05-12T22:36:55Z","receivedAt":"2016-05-12T22:36:55Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Pranit Bauva <pranit.bauva@gmail.com> writes:\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\nThe above comes from below\n\n> -\tbad|new)\n> -\t\tif test \"$2\" != bad\n> -\t\tthen\n> -\t\t\tdie \"$(eval_gettext \"can't change the meaning ...\n\nSo it is not your fault, but it is quite hard to understand.\n\nThe original says \"You are trying to use 'bad' (or 'new') for\nsomething that is not 'bad'--which is confusing; do not do it\".\n\nI _think_ the reason I find C version harder to read is the use of\nstrcmp(orig_term, \"bad\") to say \"orig_term is not BAD\".  The shell\nversion visually tells with \"!=\" that the meaning of the new term is\n*NOT* \"bad\", and does not ahve such a problem.\n\nPerhaps if we rewrote it to\n\n\tif ((!strcmp(orig_term, \"good\") &&\n             one_of(term, \"bad\", \"new\", NULL)) ||\n             (!strcmp(orig_term, \"bad\") &&\n             one_of(term, \"good\", \"old\", NULL)))\n\ni.e. \"If you are using \"bad\" or \"new\" to mean \"good\", that is not a\ngood idea\", as a follow-up change after the dust settles, the result\nmight be easier to read.\n\nBut this is just commenting for future reference, not suggesting to\nupdate this patch at all.  If we were to do the change, that must\ncome as a separate step.\n\nThanks.\n"},{"id":"286434","messageId":"CAFZEwPP+w4BOU+jKSRqGLBx-1f9JtZCq5bj-kkg4-Yw_omeswg@mail.gmail.com","threadId":"41774","inReplyTo":"xmqq37pmdhtk.fsf@gitster.mtv.corp.google.com","subject":"Re: [PATCH v6 2/3] bisect: rewrite `check_term_format` shell function in C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-13T06:59:59Z","receivedAt":"2016-05-13T06:59:59Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"On Fri, May 13, 2016 at 4:06 AM, Junio C Hamano <gitster@pobox.com> wrote:\n> Pranit Bauva <pranit.bauva@gmail.com> writes:\n>\n>> +     /*\n>> +      * In theory, nothing prevents swapping completely good and bad,\n>> +      * but this situation could be confusing and hasn't been tested\n>> +      * enough. Forbid it for now.\n>> +      */\n>> +\n>> +     if ((strcmp(orig_term, \"bad\") && one_of(term, \"bad\", \"new\", NULL)) ||\n>> +              (strcmp(orig_term, \"good\") && one_of(term, \"good\", \"old\", NULL)))\n>> +             return error(_(\"can't change the meaning of the term '%s'\"), term);\n>\n> The above comes from below\n>\n>> -     bad|new)\n>> -             if test \"$2\" != bad\n>> -             then\n>> -                     die \"$(eval_gettext \"can't change the meaning ...\n>\n> So it is not your fault, but it is quite hard to understand.\n>\n> The original says \"You are trying to use 'bad' (or 'new') for\n> something that is not 'bad'--which is confusing; do not do it\".\n>\n> I _think_ the reason I find C version harder to read is the use of\n> strcmp(orig_term, \"bad\") to say \"orig_term is not BAD\".  The shell\n> version visually tells with \"!=\" that the meaning of the new term is\n> *NOT* \"bad\", and does not ahve such a problem.\n>\n> Perhaps if we rewrote it to\n>\n>         if ((!strcmp(orig_term, \"good\") &&\n>              one_of(term, \"bad\", \"new\", NULL)) ||\n>              (!strcmp(orig_term, \"bad\") &&\n>              one_of(term, \"good\", \"old\", NULL)))\n>\n> i.e. \"If you are using \"bad\" or \"new\" to mean \"good\", that is not a\n> good idea\", as a follow-up change after the dust settles, the result\n> might be easier to read.\n\nNot just that, it would also be fundamentally more correct as there is\na difference between \" !strcmp(\"good\") \" and \" strcmp(\"bad\") \". Yours\napproach suggests that it should be \"good\" specifically which is\ntechnically more correct as then only it would be sensible to check\nwhether it is trying to change the meaning of the term.\n\n> But this is just commenting for future reference, not suggesting to\n> update this patch at all.  If we were to do the change, that must\n> come as a separate step.\n>\n> Thanks.\n\nWill do this change in a separate patch after the dust settles.\n\nRegards,\nPranit Bauva\n"},{"id":"286473","messageId":"xmqq60uhalcp.fsf@gitster.mtv.corp.google.com","threadId":"41774","inReplyTo":"CAFZEwPP+w4BOU+jKSRqGLBx-1f9JtZCq5bj-kkg4-Yw_omeswg@mail.gmail.com","subject":"Re: [PATCH v6 2/3] bisect: rewrite `check_term_format` shell function in C","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-05-13T18:01:10Z","receivedAt":"2016-05-13T18:01:10Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Pranit Bauva <pranit.bauva@gmail.com> writes:\n\n> Not just that, it would also be fundamentally more correct as there is\n> a difference between \" !strcmp(\"good\") \" and \" strcmp(\"bad\") \".\n\nNot really.  As long as you are in tight control of the callers,\nbecause we'd never call $2 with anything other than good and bad in\nthe original, there is no deep fundmental difference between them.\n\nIt is just \"test bad != $2\" makes it more clear that we are checking\nif $2 is not 'bad', but strcmp(orig_term, \"bad\") doesn't do so as\nstrongly as that.\n\n> Will do this change in a separate patch after the dust settles.\n\nThanks.\n"},{"id":"286630","messageId":"CAPig+cRhfJbbP7FE-XkW4uaMu5Gy+UvBbh-rHOY5NK4_SrwjcA@mail.gmail.com","threadId":"41774","inReplyTo":"CAFZEwPPZJqGHsHk0RLzo-pA8rUN0VP9-ricycNOnGbhO=2JZgg@mail.gmail.com","subject":"Re: [PATCH v5 0/2] bisect--helper: rewrite of check-term-format()","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2016-05-16T00:35:40Z","receivedAt":"2016-05-16T00:35:40Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Sun, May 8, 2016 at 9:34 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n> On Sun, May 8, 2016 at 11:53 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>> On Sun, May 8, 2016 at 7:55 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>>> Pranit Bauva <pranit.bauva@gmail.com> writes:\n>>>> I completely missed your point and you want me to go the Eric Sunshine's way?\n>>>\n>>> I am neutral.\n>>>\n>>> When I read your response to Eric's \"top down\" suggestion, I didn't\n>>> quite get much more than \"I started going this way, and I do not\n>>> want to change to the other direction.\", which was what I had the\n>>> most trouble with.  If your justification for the approach to start\n>>> from building a tiny bottom layer that will need to be dismantled\n>>> soon and repeat that (which sounds somewhat wasteful) were more\n>>> convincing, I may have felt differently.\n>>\n>> Sorry if it seemed that \"I have done quite some work and I don't want\n>> to scrape it off and redo everything\". This isn't a case for me. I\n>> think of this as just a small part in the process of learning and my\n>> efforts would be completely wasted as I can still reuse the methods I\n>\n> efforts would **not** be completely wasted\n>\n>> wrote. This is still open for a \"philosophical\" discussion. I am\n>> assuming 1e1ea69fa4e is how Eric is suggesting.\n\nSpeaking of 1e1ea69 (pull: implement skeletal builtin pull,\n2015-06-14), one of the (numerous) things Paul Tan did which impressed\nme was to formally measure test suite coverage of the commands he was\nconverting to C, and then improve coverage where it was lacking. That\napproach increases confidence in the conversion far more than fallible\nhuman reviews do.\n\nSetting aside the top-down vs. bottom-up discussion, as a reviewer\n(and user) I'd be far more interested in seeing you spend a good\ninitial chunk of your project emulating Paul's approach to measuring\nand improving test coverage (though I don't know how your GSoC mentors\nfeel about that).\n"},{"id":"286649","messageId":"CAPig+cQM2tyXWek7cMZkfks1SA4MHcf9yvfJ1SRZ2-mRf1Q47g@mail.gmail.com","threadId":"41774","inReplyTo":"1463031127-17718-2-git-send-email-pranit.bauva@gmail.com","subject":"Re: [PATCH v6 1/3] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2016-05-16T07:07:06Z","receivedAt":"2016-05-16T07:07:06Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Thu, May 12, 2016 at 1:32 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n> `--next-all` is meant to be used as a subcommand to support multiple\n> \"operation mode\" though the current implementation does not contain any\n> other subcommand along side with `--next-all` but further commits will\n> include some more subcommands.\n>\n> Signed-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n> ---\n> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\n> @@ -23,9 +23,14 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n> -       if (!next_all)\n> +       if (!cmdmode)\n>                 usage_with_options(git_bisect_helper_usage, options);\n>\n> -       /* next-all */\n> -       return bisect_next_all(prefix, no_checkout);\n> +       switch (cmdmode) {\n> +       case NEXT_ALL:\n> +               return bisect_next_all(prefix, no_checkout);\n> +       default:\n> +               die(\"BUG: unknown subcommand '%d'\", cmdmode);\n> +       }\n> +       return 0;\n\nWhat happens if you remove this useless 'return 0'? Does the (or some)\ncompiler incorrectly complain about it falling off the end of the\nfunction without returning a value?\n\n>  }\n"},{"id":"286650","messageId":"CAPig+cS=zcSVLwARZ5A8hdiE0wqgYPU2Jwnr0OcjDXZFO--cZw@mail.gmail.com","threadId":"41774","inReplyTo":"1463031127-17718-4-git-send-email-pranit.bauva@gmail.com","subject":"Re: [PATCH v6 3/3] bisect--helper: `write_terms` shell function in C","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2016-05-16T07:28:42Z","receivedAt":"2016-05-16T07:28:42Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Thu, May 12, 2016 at 1:32 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n> Reimplement the `write_terms` shell function in C and add a `write-terms`\n> subcommand to `git bisect--helper` to call it from git-bisect.sh . Also\n> remove the subcommand `--check-term-format` as it can now be called from\n> inside the function write_terms() C implementation.\n>\n> Using `--write-terms` subcommand is a temporary measure to port shell\n> function to C so as to use the existing test suite. As more functions\n> are ported, this subcommand will be retired and will be called by some\n> other method.\n>\n> Signed-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n> ---\n> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\n> @@ -56,18 +56,41 @@ static int check_term_format(const char *term, const char *orig_term)\n> +int write_terms(const char *bad, const char *good)\n\ns/^/static/\n\n> +{\n> +       struct strbuf content = STRBUF_INIT;\n> +       FILE *fp;\n> +       int res;\n> +\n> +       if (!strcmp(bad, good))\n> +               return error(_(\"please use two different terms\"));\n> +\n> +       if (check_term_format(bad, \"bad\") || check_term_format(good, \"good\"))\n> +               return -1;\n> +\n> +       strbuf_addf(&content, \"%s\\n%s\\n\", bad, good);\n\nWhat's the point of the strbuf when you could more easily emit this\nsame content directly to the file via:\n\n    fprintf(fp, \"%s\\n%s\\n\", bad, good);\n\n> +       fp = fopen(\".git/BISECT_TERMS\", \"w\");\n\nHardcoding \".git/\" is wrong for a variety of reasons: It won't be\ncorrect with linked worktrees, or when GIT_DIR is pointing elsewhere,\nor when \".git\" is a symbolic link, etc. Check out the get_git_dir(),\nget_git_common_dir(), etc. functions in cache.h instead.\n\n> +       if (!fp){\n\nStyle: space before '{'\n\n> +               strbuf_release(&content);\n> +               die_errno(_(\"could not open the file to read terms\"));\n\n\"read terms\"? I thought this was writing.\n\nIs dying here correct? I thought we established previously that you\nshould be reporting failure via normal -1 return value rather than\ndying. Indeed, you're doing so below when strbuf_write() fails.\n\n> +       }\n> +       res = strbuf_write(&content, fp);\n> +       fclose(fp);\n> +       strbuf_release(&content);\n> +       return (res < 0) ? -1 : 0;\n> +}\n>  int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n\nStyle: insert blank line between functions\n"},{"id":"286656","messageId":"alpine.DEB.2.20.1605161508230.3303@virtualbox","threadId":"41774","inReplyTo":"CAPig+cS=zcSVLwARZ5A8hdiE0wqgYPU2Jwnr0OcjDXZFO--cZw@mail.gmail.com","subject":"Re: [PATCH v6 3/3] bisect--helper: `write_terms` shell function in C","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-05-16T13:16:49Z","receivedAt":"2016-05-16T13:16:49Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi,\n\nOn Mon, 16 May 2016, Eric Sunshine wrote:\n\n> On Thu, May 12, 2016 at 1:32 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n> \n> > +       fp = fopen(\".git/BISECT_TERMS\", \"w\");\n> \n> Hardcoding \".git/\" is wrong for a variety of reasons: It won't be correct\n> with linked worktrees, or when GIT_DIR is pointing elsewhere, or when \".git\"\n> is a symbolic link, etc. Check out the get_git_dir(), get_git_common_dir(),\n> etc. functions in cache.h instead.\n\nMaybe in this case, `git_path(\"BISECT_TERMS\")` would be a good idea. Or even\nbetter: follow the example of bisect.c and use\n`GIT_PATH_FUNC(bisect_terms_path, \"BISECT_TERMS\")`.\n\n> > +               strbuf_release(&content);\n> > +               die_errno(_(\"could not open the file to read terms\"));\n> \n> \"read terms\"? I thought this was writing.\n> \n> Is dying here correct? I thought we established previously that you\n> should be reporting failure via normal -1 return value rather than\n> dying. Indeed, you're doing so below when strbuf_write() fails.\n\nThe rule of thumb seems to be that die()ing is okay in builtin/*.c, but not\nin *.c. So technically, it would be okay here, too. However, I think that\nthis code should be written with libification in mind, so I would also\nprefer it to error() and return, to give the caller a chance to do other\nthings after an error occurred.\n\nCiao,\nDscho\n"},{"id":"286664","messageId":"CAPig+cQ=Gche_uO840wF6qE4WD-ZNZj1HFzNNgaBi_UjG1sjEg@mail.gmail.com","threadId":"41774","inReplyTo":"alpine.DEB.2.20.1605161508230.3303@virtualbox","subject":"Re: [PATCH v6 3/3] bisect--helper: `write_terms` shell function in C","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2016-05-16T15:42:01Z","receivedAt":"2016-05-16T15:42:01Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Mon, May 16, 2016 at 9:16 AM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> On Mon, 16 May 2016, Eric Sunshine wrote:\n>> On Thu, May 12, 2016 at 1:32 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>> > +       fp = fopen(\".git/BISECT_TERMS\", \"w\");\n>>\n>> Hardcoding \".git/\" is wrong for a variety of reasons: It won't be correct\n>> with linked worktrees, or when GIT_DIR is pointing elsewhere, or when \".git\"\n>> is a symbolic link, etc. Check out the get_git_dir(), get_git_common_dir(),\n>> etc. functions in cache.h instead.\n>\n> Maybe in this case, `git_path(\"BISECT_TERMS\")` would be a good idea. Or even\n> better: follow the example of bisect.c and use\n> `GIT_PATH_FUNC(bisect_terms_path, \"BISECT_TERMS\")`.\n\nThanks for pointing this out. My review time is severely limited these\ndays so I didn't go the distance of re-studying and re-digesting which\nfunction was the correct one to use.\n\n>> > +               strbuf_release(&content);\n>> > +               die_errno(_(\"could not open the file to read terms\"));\n>>\n>> Is dying here correct? I thought we established previously that you\n>> should be reporting failure via normal -1 return value rather than\n>> dying. Indeed, you're doing so below when strbuf_write() fails.\n>\n> The rule of thumb seems to be that die()ing is okay in builtin/*.c, but not\n> in *.c. So technically, it would be okay here, too. However, I think that\n> this code should be written with libification in mind, so I would also\n> prefer it to error() and return, to give the caller a chance to do other\n> things after an error occurred.\n\nAgreed. Specific to the \"established previously\" I wrote above, I was\nreferring to [1] from just a few days ago which explained why 'return\n-1' was preferable to die() in a similar case that had an odd mix of\n'return -1' and die() in the same function.\n\n[1]: http://thread.gmane.org/gmane.comp.version-control.git/289476/focus=293556\n"},{"id":"286675","messageId":"alpine.DEB.2.20.1605161830200.3303@virtualbox","threadId":"41774","inReplyTo":"CAPig+cQ=Gche_uO840wF6qE4WD-ZNZj1HFzNNgaBi_UjG1sjEg@mail.gmail.com","subject":"Re: [PATCH v6 3/3] bisect--helper: `write_terms` shell function in C","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-05-16T16:45:42Z","receivedAt":"2016-05-16T16:45:42Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Eric,\n\nOn Mon, 16 May 2016, Eric Sunshine wrote:\n\n> On Mon, May 16, 2016 at 9:16 AM, Johannes Schindelin\n> <Johannes.Schindelin@gmx.de> wrote:\n> > On Mon, 16 May 2016, Eric Sunshine wrote:\n> >> On Thu, May 12, 2016 at 1:32 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n> >> > +       fp = fopen(\".git/BISECT_TERMS\", \"w\");\n> >>\n> >> Hardcoding \".git/\" is wrong for a variety of reasons: It won't be correct\n> >> with linked worktrees, or when GIT_DIR is pointing elsewhere, or when \".git\"\n> >> is a symbolic link, etc. Check out the get_git_dir(), get_git_common_dir(),\n> >> etc. functions in cache.h instead.\n> >\n> > Maybe in this case, `git_path(\"BISECT_TERMS\")` would be a good idea. Or even\n> > better: follow the example of bisect.c and use\n> > `GIT_PATH_FUNC(bisect_terms_path, \"BISECT_TERMS\")`.\n> \n> Thanks for pointing this out. My review time is severely limited these\n> days so I didn't go the distance of re-studying and re-digesting which\n> function was the correct one to use.\n\nI am constantly amazed how much you manage to review, and how helpful your\ncomments are. I am glad if I could contribute a little.\n\n> >> > +               strbuf_release(&content);\n> >> > +               die_errno(_(\"could not open the file to read terms\"));\n> >>\n> >> Is dying here correct? I thought we established previously that you\n> >> should be reporting failure via normal -1 return value rather than\n> >> dying. Indeed, you're doing so below when strbuf_write() fails.\n> >\n> > The rule of thumb seems to be that die()ing is okay in builtin/*.c, but not\n> > in *.c. So technically, it would be okay here, too. However, I think that\n> > this code should be written with libification in mind, so I would also\n> > prefer it to error() and return, to give the caller a chance to do other\n> > things after an error occurred.\n> \n> Agreed. Specific to the \"established previously\" I wrote above, I was\n> referring to [1] from just a few days ago which explained why 'return\n> -1' was preferable to die() in a similar case that had an odd mix of\n> 'return -1' and die() in the same function.\n> \n> [1]: http://thread.gmane.org/gmane.comp.version-control.git/289476/focus=293556\n\nYes, this is an excellent link. Maybe we would want something like this,\ntoo?\n\n-- snipsnap --\n(From: Eric Sunshine <sunshine@sunshineco.com>)\nCodingGuidelines: mention that die() is for fatal errors only\n\nLet's formalize the rule when to use die() and when to use error().\n\ndiff --git a/Documentation/CodingGuidelines\nb/Documentation/CodingGuidelines\nindex 0ddd368..5d2d65f 100644\n--- a/Documentation/CodingGuidelines\n+++ b/Documentation/CodingGuidelines\n@@ -333,6 +333,10 @@ For C programs:\n \n  - When you come up with an API, document it.\n \n+ - Use die() only to signal an exceptional conditions which should\n+   abort the program. All other error conditions should instead\n+   return e.g. using \"return error(...)\".\n+\n  - The first #include in C files, except in platform specific compat/\n    implementations, must be either \"git-compat-util.h\", \"cache.h\" or\n    \"builtin.h\".  You do not have to include more than one of these.\n"},{"id":"286676","messageId":"CAPig+cRZKpjYBJ9bUG-X3WcpXYvHW-wgMDVYTg7a6_q8N+7qNg@mail.gmail.com","threadId":"41774","inReplyTo":"alpine.DEB.2.20.1605161830200.3303@virtualbox","subject":"Re: [PATCH v6 3/3] bisect--helper: `write_terms` shell function in C","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2016-05-16T16:59:50Z","receivedAt":"2016-05-16T16:59:50Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Mon, May 16, 2016 at 12:45 PM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> On Mon, 16 May 2016, Eric Sunshine wrote:\n>> On Mon, May 16, 2016 at 9:16 AM, Johannes Schindelin\n>> <Johannes.Schindelin@gmx.de> wrote:\n>> > On Mon, 16 May 2016, Eric Sunshine wrote:\n>> Agreed. Specific to the \"established previously\" I wrote above, I was\n>> referring to [1] from just a few days ago which explained why 'return\n>> -1' was preferable to die() in a similar case that had an odd mix of\n>> 'return -1' and die() in the same function.\n>>\n>> [1]: http://thread.gmane.org/gmane.comp.version-control.git/289476/focus=293556\n>\n> Yes, this is an excellent link. Maybe we would want something like this,\n> too?\n>\n> -- snipsnap --\n> diff --git a/Documentation/CodingGuidelines\n> @@ -333,6 +333,10 @@ For C programs:\n> + - Use die() only to signal an exceptional conditions which should\n> +   abort the program. All other error conditions should instead\n> +   return e.g. using \"return error(...)\".\n\nHmm, the bit you said earlier about \"library\" code vs. end-user code\nwould be important, too, I'd think. Also, I'd expect that this sort of\nthing is implicitly understood by most programmers, and as this is\nonly the first time (in recent memory) that it has needed explanation\non the mailing list, I'm not sure that it deserves explicit mention in\nCodingGuidelines (but perhaps I'm not a good judge of these things).\n"},{"id":"286677","messageId":"CAP8UFD1BD9JtcW_BGZtrS0vdaC7YpvgohpJWC813RX03HfKNUA@mail.gmail.com","threadId":"41774","inReplyTo":"CAPig+cRhfJbbP7FE-XkW4uaMu5Gy+UvBbh-rHOY5NK4_SrwjcA@mail.gmail.com","subject":"Re: [PATCH v5 0/2] bisect--helper: rewrite of check-term-format()","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-16T17:07:35Z","receivedAt":"2016-05-16T17:07:35Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Mon, May 16, 2016 at 2:35 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> On Sun, May 8, 2016 at 9:34 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>> On Sun, May 8, 2016 at 11:53 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>>> On Sun, May 8, 2016 at 7:55 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>>>> Pranit Bauva <pranit.bauva@gmail.com> writes:\n>>>>> I completely missed your point and you want me to go the Eric Sunshine's way?\n>>>>\n>>>> I am neutral.\n>>>>\n>>>> When I read your response to Eric's \"top down\" suggestion, I didn't\n>>>> quite get much more than \"I started going this way, and I do not\n>>>> want to change to the other direction.\", which was what I had the\n>>>> most trouble with.  If your justification for the approach to start\n>>>> from building a tiny bottom layer that will need to be dismantled\n>>>> soon and repeat that (which sounds somewhat wasteful) were more\n>>>> convincing, I may have felt differently.\n>>>\n>>> Sorry if it seemed that \"I have done quite some work and I don't want\n>>> to scrape it off and redo everything\". This isn't a case for me. I\n>>> think of this as just a small part in the process of learning and my\n>>> efforts would be completely wasted as I can still reuse the methods I\n>>\n>> efforts would **not** be completely wasted\n>>\n>>> wrote. This is still open for a \"philosophical\" discussion. I am\n>>> assuming 1e1ea69fa4e is how Eric is suggesting.\n>\n> Speaking of 1e1ea69 (pull: implement skeletal builtin pull,\n> 2015-06-14), one of the (numerous) things Paul Tan did which impressed\n> me was to formally measure test suite coverage of the commands he was\n> converting to C, and then improve coverage where it was lacking. That\n> approach increases confidence in the conversion far more than fallible\n> human reviews do.\n>\n> Setting aside the top-down vs. bottom-up discussion, as a reviewer\n> (and user) I'd be far more interested in seeing you spend a good\n> initial chunk of your project emulating Paul's approach to measuring\n> and improving test coverage (though I don't know how your GSoC mentors\n> feel about that).\n\nIf we could test each `git bisect-helper` subcommand that has been\nconverted to C separately, then I think it would be quite easy and a\ngood idea. And maybe Paul's approach is really great and easy to use,\nbut I haven't followed his GSoC, so I cannot tell.\n\nAs we take the approach of testing the whole thing, which is made of a\nnumber of different source files (shell code in git-bisect.sh, C code\nin `git bisect-helper` subcommands and in bisect.{c,h}), I am worried\nthat Pranit would spend too much time initially not only to measure\ntest coverage but especially to find ways to improve it.\n\nThe good thing with converting code incrementally to C is that one\ndoes not need to understand everything first. While if one wants to\nincrease test coverage initially, it might be needed to understand\nmany things.\n\nWhat I started asking though is to take advantage of bugs that are\nfound, and were not covered by the test suite, to improve test\ncoverage.\n\nAlso starting to convert functions right away can make the student\nfeel productive early and in turn make everyone else happy to see some\nprogress.\n"},{"id":"287072","messageId":"CAFZEwPM5AVx9ErCUCmEq=z5_8g9eL72BtqdEok+EMU0R8uC5JA@mail.gmail.com","threadId":"41774","inReplyTo":"CAPig+cRhfJbbP7FE-XkW4uaMu5Gy+UvBbh-rHOY5NK4_SrwjcA@mail.gmail.com","subject":"Re: [PATCH v5 0/2] bisect--helper: rewrite of check-term-format()","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-20T06:59:21Z","receivedAt":"2016-05-20T06:59:21Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"Hey Eric,\nSorry for the late reply. I was on vacation.\n\nOn Mon, May 16, 2016 at 6:05 AM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> On Sun, May 8, 2016 at 9:34 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>> On Sun, May 8, 2016 at 11:53 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>>> On Sun, May 8, 2016 at 7:55 AM, Junio C Hamano <gitster@pobox.com> wrote:\n>>>> Pranit Bauva <pranit.bauva@gmail.com> writes:\n>>>>> I completely missed your point and you want me to go the Eric Sunshine's way?\n>>>>\n>>>> I am neutral.\n>>>>\n>>>> When I read your response to Eric's \"top down\" suggestion, I didn't\n>>>> quite get much more than \"I started going this way, and I do not\n>>>> want to change to the other direction.\", which was what I had the\n>>>> most trouble with.  If your justification for the approach to start\n>>>> from building a tiny bottom layer that will need to be dismantled\n>>>> soon and repeat that (which sounds somewhat wasteful) were more\n>>>> convincing, I may have felt differently.\n>>>\n>>> Sorry if it seemed that \"I have done quite some work and I don't want\n>>> to scrape it off and redo everything\". This isn't a case for me. I\n>>> think of this as just a small part in the process of learning and my\n>>> efforts would be completely wasted as I can still reuse the methods I\n>>\n>> efforts would **not** be completely wasted\n>>\n>>> wrote. This is still open for a \"philosophical\" discussion. I am\n>>> assuming 1e1ea69fa4e is how Eric is suggesting.\n>\n> Speaking of 1e1ea69 (pull: implement skeletal builtin pull,\n> 2015-06-14), one of the (numerous) things Paul Tan did which impressed\n> me was to formally measure test suite coverage of the commands he was\n> converting to C, and then improve coverage where it was lacking. That\n> approach increases confidence in the conversion far more than fallible\n> human reviews do.\n>\n> Setting aside the top-down vs. bottom-up discussion, as a reviewer\n> (and user) I'd be far more interested in seeing you spend a good\n> initial chunk of your project emulating Paul's approach to measuring\n> and improving test coverage (though I don't know how your GSoC mentors\n> feel about that).\n\nJust adding to the points mentioned by Christian.\n\nI had initially planned to first improve test coverage and then start\nwith function conversion as I mentioned in my introductory mail[1]. I\nalso pointed out that I did some work searching about the tools to\ntest coverage (kcov as Matthieu) suggested and I found that it is not\nthat easy to set it up. Then Christian pointed it out (privately) that\nI can do this afterwards too before the code is finally merged. And\nalso I am trying to see the test coverage as and when I am converting\neach function.\n\n[1]: http://thread.gmane.org/gmane.comp.version-control.git/292308\n\nRegards,\nPranit Bauva\n"},{"id":"287073","messageId":"CAFZEwPPDU4NXP-nMXsEa2iB8j5nApxOdXXjGSW_OyLoum11ttw@mail.gmail.com","threadId":"41774","inReplyTo":"CAPig+cQM2tyXWek7cMZkfks1SA4MHcf9yvfJ1SRZ2-mRf1Q47g@mail.gmail.com","subject":"Re: [PATCH v6 1/3] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-20T07:17:47Z","receivedAt":"2016-05-20T07:17:47Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"Hey Eric,\n\nOn Mon, May 16, 2016 at 12:37 PM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> On Thu, May 12, 2016 at 1:32 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>> `--next-all` is meant to be used as a subcommand to support multiple\n>> \"operation mode\" though the current implementation does not contain any\n>> other subcommand along side with `--next-all` but further commits will\n>> include some more subcommands.\n>>\n>> Signed-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n>> ---\n>> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\n>> @@ -23,9 +23,14 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>> -       if (!next_all)\n>> +       if (!cmdmode)\n>>                 usage_with_options(git_bisect_helper_usage, options);\n>>\n>> -       /* next-all */\n>> -       return bisect_next_all(prefix, no_checkout);\n>> +       switch (cmdmode) {\n>> +       case NEXT_ALL:\n>> +               return bisect_next_all(prefix, no_checkout);\n>> +       default:\n>> +               die(\"BUG: unknown subcommand '%d'\", cmdmode);\n>> +       }\n>> +       return 0;\n>\n> What happens if you remove this useless 'return 0'? Does the (or some)\n> compiler incorrectly complain about it falling off the end of the\n> function without returning a value?\n\nI tried removing it. It works fine with gcc and clang. You can see the\nbuild on travis-CI[1]. I am not sure of other compilers and also don't\nknow a way to test it either. You could use my branch on github[2] if\nyou want to test it on other compilers. I think its better to keep the\nreturn 0 if we aren't sure whether it would work on every compiler.\n\n[1]: https://travis-ci.org/pranitbauva1997/git/builds/131622175\n[2]: https://github.com/pranitbauva1997/git/tree/return-try\n\nRegards,\nPranit Bauva\n"},{"id":"287076","messageId":"CAFZEwPPp+CWpnW-RMz5aYsgYDfdVVSZqCCXQQp0z=uC5QE140g@mail.gmail.com","threadId":"41774","inReplyTo":"CAPig+cS=zcSVLwARZ5A8hdiE0wqgYPU2Jwnr0OcjDXZFO--cZw@mail.gmail.com","subject":"Re: [PATCH v6 3/3] bisect--helper: `write_terms` shell function in C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-20T07:42:01Z","receivedAt":"2016-05-20T07:42:01Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"Hey Eric,\n\nOn Mon, May 16, 2016 at 12:58 PM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> On Thu, May 12, 2016 at 1:32 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>> Reimplement the `write_terms` shell function in C and add a `write-terms`\n>> subcommand to `git bisect--helper` to call it from git-bisect.sh . Also\n>> remove the subcommand `--check-term-format` as it can now be called from\n>> inside the function write_terms() C implementation.\n>>\n>> Using `--write-terms` subcommand is a temporary measure to port shell\n>> function to C so as to use the existing test suite. As more functions\n>> are ported, this subcommand will be retired and will be called by some\n>> other method.\n>>\n>> Signed-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n>> ---\n>> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\n>> @@ -56,18 +56,41 @@ static int check_term_format(const char *term, const char *orig_term)\n>> +int write_terms(const char *bad, const char *good)\n>\n> s/^/static/\n\nSure. Will include this in re-roll.\n\n>> +{\n>> +       struct strbuf content = STRBUF_INIT;\n>> +       FILE *fp;\n>> +       int res;\n>> +\n>> +       if (!strcmp(bad, good))\n>> +               return error(_(\"please use two different terms\"));\n>> +\n>> +       if (check_term_format(bad, \"bad\") || check_term_format(good, \"good\"))\n>> +               return -1;\n>> +\n>> +       strbuf_addf(&content, \"%s\\n%s\\n\", bad, good);\n>\n> What's the point of the strbuf when you could more easily emit this\n> same content directly to the file via:\n>\n>     fprintf(fp, \"%s\\n%s\\n\", bad, good);\n\nfprintf seems way better and it is also extensively used in git's\nsource code. Will update.\n\n>> +       fp = fopen(\".git/BISECT_TERMS\", \"w\");\n>\n> Hardcoding \".git/\" is wrong for a variety of reasons: It won't be\n> correct with linked worktrees, or when GIT_DIR is pointing elsewhere,\n> or when \".git\" is a symbolic link, etc. Check out the get_git_dir(),\n> get_git_common_dir(), etc. functions in cache.h instead.\n>\n>> +       if (!fp){\n>\n> Style: space before '{'\n\nSorry. Might have missed this. Will include this in re-roll\n\n>> +               strbuf_release(&content);\n>> +               die_errno(_(\"could not open the file to read terms\"));\n>\n> \"read terms\"? I thought this was writing.\n\nYa. It should be \"write terms\".\n\n> Is dying here correct? I thought we established previously that you\n> should be reporting failure via normal -1 return value rather than\n> dying. Indeed, you're doing so below when strbuf_write() fails.\n\nI was confused about this. I thought not able to open a file is an\nexceptional situation (because it has never happened with me) and thus\nI used die(). I will use error() as further justified by Johannes.\n\n>> +       }\n>> +       res = strbuf_write(&content, fp);\n>> +       fclose(fp);\n>> +       strbuf_release(&content);\n>> +       return (res < 0) ? -1 : 0;\n>> +}\n>>  int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>\n> Style: insert blank line between functions\n\nSure.\n\nRegards,\nPranit Bauva\n"},{"id":"287077","messageId":"CAFZEwPNkPZ6JnzqbTyhYMwEF-hor2rm39NcB84omrh+uCiVPNw@mail.gmail.com","threadId":"41774","inReplyTo":"alpine.DEB.2.20.1605161508230.3303@virtualbox","subject":"Re: [PATCH v6 3/3] bisect--helper: `write_terms` shell function in C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-20T07:45:51Z","receivedAt":"2016-05-20T07:45:51Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"Hey Johannes,\n\nOn Mon, May 16, 2016 at 6:46 PM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> Hi,\n>\n> On Mon, 16 May 2016, Eric Sunshine wrote:\n>\n>> On Thu, May 12, 2016 at 1:32 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>>\n>> > +       fp = fopen(\".git/BISECT_TERMS\", \"w\");\n>>\n>> Hardcoding \".git/\" is wrong for a variety of reasons: It won't be correct\n>> with linked worktrees, or when GIT_DIR is pointing elsewhere, or when \".git\"\n>> is a symbolic link, etc. Check out the get_git_dir(), get_git_common_dir(),\n>> etc. functions in cache.h instead.\n>\n> Maybe in this case, `git_path(\"BISECT_TERMS\")` would be a good idea. Or even\n> better: follow the example of bisect.c and use\n> `GIT_PATH_FUNC(bisect_terms_path, \"BISECT_TERMS\")`.\n\nThanks. I will look into this.\n\n\n>> > +               strbuf_release(&content);\n>> > +               die_errno(_(\"could not open the file to read terms\"));\n>>\n>> \"read terms\"? I thought this was writing.\n>>\n>> Is dying here correct? I thought we established previously that you\n>> should be reporting failure via normal -1 return value rather than\n>> dying. Indeed, you're doing so below when strbuf_write() fails.\n>\n> The rule of thumb seems to be that die()ing is okay in builtin/*.c, but not\n> in *.c. So technically, it would be okay here, too. However, I think that\n> this code should be written with libification in mind, so I would also\n> prefer it to error() and return, to give the caller a chance to do other\n> things after an error occurred.\n\nFrankly, I have no idea what you mean by libification but I will use\nerror() since efforts for libification have already started.\n\nRegards,\nPranit Bauva\n\n> Ciao,\n> Dscho\n"},{"id":"287237","messageId":"alpine.DEB.2.20.1605231301560.4122@virtualbox","threadId":"41774","inReplyTo":"CAFZEwPNkPZ6JnzqbTyhYMwEF-hor2rm39NcB84omrh+uCiVPNw@mail.gmail.com","subject":"Re: [PATCH v6 3/3] bisect--helper: `write_terms` shell function in C","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-05-23T11:07:38Z","receivedAt":"2016-05-23T11:07:38Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Pranit,\n\nOn Fri, 20 May 2016, Pranit Bauva wrote:\n\n> Frankly, I have no idea what you mean by libification but I will use\n> error() since efforts for libification have already started.\n\nThe term \"libification\" is frequently used in the Git project: it means to\nconvert code that was formerly used in a standalone program to make it\nusable as a library function.\n\nThe main differences:\n\n- in the standalone program, you can get away with calling die() when\n  anything goes wrong. Not so in a library function: you need to give the\n  caller a chance to fail gracefully, or even to continue.\n\n- in a standalone program, you can be sloppy and \"let exit() clean up\",\n  i.e. omit free() calls or even close() calls. In library functions, this\n  is not possible.\n\n- in a standalone program, you may mess with the stdio handles. This is\n  an absolute no-go in library functions.\n\nThere are other differences, of course. The gist is that you have to be a\nlot more careful for library functions.\n\nCiao,\nJohannes\n"},{"id":"287246","messageId":"CAP8UFD1gjfFC_v23RDiHedzwQm3XoYJKv32GT7R9GNyK4pXJpQ@mail.gmail.com","threadId":"41774","inReplyTo":"alpine.DEB.2.20.1605231301560.4122@virtualbox","subject":"Re: [PATCH v6 3/3] bisect--helper: `write_terms` shell function in C","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-23T13:58:52Z","receivedAt":"2016-05-23T13:58:52Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Mon, May 23, 2016 at 1:07 PM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n>\n> On Fri, 20 May 2016, Pranit Bauva wrote:\n>\n>> Frankly, I have no idea what you mean by libification but I will use\n>> error() since efforts for libification have already started.\n>\n> The term \"libification\" is frequently used in the Git project: it means to\n> convert code that was formerly used in a standalone program to make it\n> usable as a library function.\n\nYeah, and Git standalone programs in C are builtin/*.c files, while\nGit lib code in C is in *.{c,h} files at the root of the repo.\n\nThe build also generates libgit.a from all the lib code, for example:\n\n$ touch bisect.c\n$ make CFLAGS=\"-g3 -Wall\"\n    CC bisect.o\n    AR libgit.a\n...\n"},{"id":"287247","messageId":"CAFZEwPPbCBAXq6ri1Ew8-+vY-iAJKtyJB_Nf+Syv4WB+2ktc1w@mail.gmail.com","threadId":"41774","inReplyTo":"alpine.DEB.2.20.1605231301560.4122@virtualbox","subject":"Re: [PATCH v6 3/3] bisect--helper: `write_terms` shell function in C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-23T14:33:19Z","receivedAt":"2016-05-23T14:33:19Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"Hey Johannes,\n\nOn Mon, May 23, 2016 at 4:37 PM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> Hi Pranit,\n>\n> On Fri, 20 May 2016, Pranit Bauva wrote:\n>\n>> Frankly, I have no idea what you mean by libification but I will use\n>> error() since efforts for libification have already started.\n>\n> The term \"libification\" is frequently used in the Git project: it means to\n> convert code that was formerly used in a standalone program to make it\n> usable as a library function.\n>\n> The main differences:\n>\n> - in the standalone program, you can get away with calling die() when\n>   anything goes wrong. Not so in a library function: you need to give the\n>   caller a chance to fail gracefully, or even to continue.\n>\n> - in a standalone program, you can be sloppy and \"let exit() clean up\",\n>   i.e. omit free() calls or even close() calls. In library functions, this\n>   is not possible.\n>\n> - in a standalone program, you may mess with the stdio handles. This is\n>   an absolute no-go in library functions.\n>\n> There are other differences, of course. The gist is that you have to be a\n> lot more careful for library functions.\n\nThanks for the explanation. It seems a bit clearer to me now.\n\nRegards,\nPranit Bauva\n\n>\n> Ciao,\n> Johannes\n"},{"id":"287248","messageId":"1464014928-31548-1-git-send-email-pranit.bauva@gmail.com","threadId":"41774","inReplyTo":"1463031127-17718-1-git-send-email-pranit.bauva@gmail.com","subject":"[PATCH v7 0/3] bisect--helper: check_term_format() & write_terms()","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-23T14:48:45Z","receivedAt":"2016-05-23T14:48:45Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"Here is the link to v6[1]. I have kept bisect_log() and bisect_voc() on hold\nright now. It would be sent to the list whenever it is required which would\nprobably be during the end.\n\nImportant Changes wrt v6:\n\n * make the method write_terms() static\n\n * Use fprintf() instead of strbuf functions\n\n * Previously \".git/\" was hardcoded. Now it uses GIT_PATH_FUNC\n\n * Use error() instead of die.\n\n[1]: http://thread.gmane.org/gmane.comp.version-control.git/294388\nPranit Bauva (3):\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\n builtin/bisect--helper.c | 96 +++++++++++++++++++++++++++++++++++++++++++++---\n git-bisect.sh            | 49 ++++--------------------\n 2 files changed, 97 insertions(+), 48 deletions(-)\n\n-- \n2.8.2\n"},{"id":"287249","messageId":"1464014928-31548-2-git-send-email-pranit.bauva@gmail.com","threadId":"41774","inReplyTo":"1464014928-31548-1-git-send-email-pranit.bauva@gmail.com","subject":"[PATCH v7 1/3] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-23T14:48:46Z","receivedAt":"2016-05-23T14:48:46Z","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.8.2\n"},{"id":"287250","messageId":"1464014928-31548-3-git-send-email-pranit.bauva@gmail.com","threadId":"41774","inReplyTo":"1464014928-31548-1-git-send-email-pranit.bauva@gmail.com","subject":"[PATCH v7 2/3] bisect: rewrite `check_term_format` shell function in C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-23T14:48:47Z","receivedAt":"2016-05-23T14:48:47Z","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.8.2\n"},{"id":"287251","messageId":"1464014928-31548-4-git-send-email-pranit.bauva@gmail.com","threadId":"41774","inReplyTo":"1464014928-31548-1-git-send-email-pranit.bauva@gmail.com","subject":"[PATCH v7 3/3] bisect--helper: `write_terms` shell function in C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-23T14:48:48Z","receivedAt":"2016-05-23T14:48:48Z","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\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..8c7a5fc 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_write_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_write_terms(), \"w\");\n+\tif (!fp)\n+\t\treturn error(_(\"could not open the file to write 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..2dd7ec5 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\"\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\"\n \t\t\tfi\n \t\t\t;;\n \t\tesac ;;\n-- \n2.8.2\n"},{"id":"287254","messageId":"alpine.DEB.2.20.1605231709170.4449@virtualbox","threadId":"41774","inReplyTo":"CAP8UFD1gjfFC_v23RDiHedzwQm3XoYJKv32GT7R9GNyK4pXJpQ@mail.gmail.com","subject":"Re: [PATCH v6 3/3] bisect--helper: `write_terms` shell function in C","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-05-23T15:10:03Z","receivedAt":"2016-05-23T15:10:03Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Christian,\n\nOn Mon, 23 May 2016, Christian Couder wrote:\n\n> On Mon, May 23, 2016 at 1:07 PM, Johannes Schindelin\n> <Johannes.Schindelin@gmx.de> wrote:\n> >\n> > On Fri, 20 May 2016, Pranit Bauva wrote:\n> >\n> >> Frankly, I have no idea what you mean by libification but I will use\n> >> error() since efforts for libification have already started.\n> >\n> > The term \"libification\" is frequently used in the Git project: it means to\n> > convert code that was formerly used in a standalone program to make it\n> > usable as a library function.\n> \n> Yeah, and Git standalone programs in C are builtin/*.c files,\n\nDo not forget the non-builtins, e.g. git-upload-pack. And scripts.\n\nCiao,\nJohannes\n"},{"id":"287255","messageId":"CAPig+cSOOv9sGGCTD7=5As9Opu3=e9ofkTpFhCzXC9cJPK21Tg@mail.gmail.com","threadId":"41774","inReplyTo":"1464014928-31548-4-git-send-email-pranit.bauva@gmail.com","subject":"Re: [PATCH v7 3/3] bisect--helper: `write_terms` shell function in C","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2016-05-23T16:01:46Z","receivedAt":"2016-05-23T16:01:46Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Mon, May 23, 2016 at 10:48 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n> Reimplement the `write_terms` shell function in C and add a `write-terms`\n> subcommand to `git bisect--helper` to call it from git-bisect.sh . Also\n> remove the subcommand `--check-term-format` as it can now be called from\n> inside the function write_terms() C implementation.\n> [...]\n> Signed-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n> ---\n> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\n> @@ -56,18 +58,38 @@ static int check_term_format(const char *term, const char *orig_term)\n> +static int write_terms(const char *bad, const char *good)\n> +{\n> +       FILE *fp;\n> +       int res;\n> +\n> +       if (!strcmp(bad, good))\n> +               return error(_(\"please use two different terms\"));\n> +\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> +       if (!fp)\n> +               return error(_(\"could not open the file to write terms\"));\n\nBy adding two pieces of information, you could make this error message\nmuch more helpful for anyone trying to debug the failure.\nSpecifically:\n\n(1) the pathname for which open() failed\n(2) the actual system-level error\n\nFor (2), you could use strerror(errno) or, better yet, error_errno()\nwhich recently graduated to 'master'.\n\n> +       res = fprintf(fp, \"%s\\n%s\\n\", bad, good);\n> +       fclose(fp);\n> +       return (res < 0) ? -1 : 0;\n> +}\n"},{"id":"287263","messageId":"CAFZEwPNrAj0-8W150Yg1E+7y-y6_XB_=m2BLpaZqAOBRbksPCg@mail.gmail.com","threadId":"41774","inReplyTo":"CAPig+cSOOv9sGGCTD7=5As9Opu3=e9ofkTpFhCzXC9cJPK21Tg@mail.gmail.com","subject":"Re: [PATCH v7 3/3] bisect--helper: `write_terms` shell function in C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-23T17:59:21Z","receivedAt":"2016-05-23T17:59:21Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"On Mon, May 23, 2016 at 9:31 PM, Eric Sunshine <sunshine@sunshineco.com> wrote:\n> On Mon, May 23, 2016 at 10:48 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>> Reimplement the `write_terms` shell function in C and add a `write-terms`\n>> subcommand to `git bisect--helper` to call it from git-bisect.sh . Also\n>> remove the subcommand `--check-term-format` as it can now be called from\n>> inside the function write_terms() C implementation.\n>> [...]\n>> Signed-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n>> ---\n>> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\n>> @@ -56,18 +58,38 @@ static int check_term_format(const char *term, const char *orig_term)\n>> +static int write_terms(const char *bad, const char *good)\n>> +{\n>> +       FILE *fp;\n>> +       int res;\n>> +\n>> +       if (!strcmp(bad, good))\n>> +               return error(_(\"please use two different terms\"));\n>> +\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>> +       if (!fp)\n>> +               return error(_(\"could not open the file to write terms\"));\n>\n> By adding two pieces of information, you could make this error message\n> much more helpful for anyone trying to debug the failure.\n> Specifically:\n>\n> (1) the pathname for which open() failed\n> (2) the actual system-level error\n>\n> For (2), you could use strerror(errno) or, better yet, error_errno()\n> which recently graduated to 'master'.\n\nYes it would definitely be better to make the error message more\nhelpful. I will dig more into this.\n\n>> +       res = fprintf(fp, \"%s\\n%s\\n\", bad, good);\n>> +       fclose(fp);\n>> +       return (res < 0) ? -1 : 0;\n>> +}\n"},{"id":"287342","messageId":"20160524072124.2945-1-pranit.bauva@gmail.com","threadId":"41774","inReplyTo":"1464014928-31548-1-git-send-email-pranit.bauva@gmail.com","subject":"[PATCH v8 0/3] bisect--helper: check-term-format() & write_terms()","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-24T07:21:21Z","receivedAt":"2016-05-24T07:21:21Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"Here is the link to v7[1]. This has a few modifications.\n\nChanges wrt v7 as suggested by Eric are:\n\n * Include the name of the file in the error message which couldn't be opened.\n\n * Use error_errno() with which we can make the error message more valuable.\n\nPranit Bauva (3):\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\n builtin/bisect--helper.c | 96 +++++++++++++++++++++++++++++++++++++++++++++---\n git-bisect.sh            | 49 ++++--------------------\n 2 files changed, 97 insertions(+), 48 deletions(-)\n\n-- \n2.8.3\n"},{"id":"287343","messageId":"20160524072124.2945-2-pranit.bauva@gmail.com","threadId":"41774","inReplyTo":"20160524072124.2945-1-pranit.bauva@gmail.com","subject":"[PATCH v8 1/3] bisect--helper: use OPT_CMDMODE instead of OPT_BOOL","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-24T07:21:22Z","receivedAt":"2016-05-24T07:21:22Z","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.8.3\n"},{"id":"287344","messageId":"20160524072124.2945-3-pranit.bauva@gmail.com","threadId":"41774","inReplyTo":"20160524072124.2945-1-pranit.bauva@gmail.com","subject":"[PATCH v8 2/3] bisect: rewrite `check_term_format` shell function in C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-24T07:21:23Z","receivedAt":"2016-05-24T07:21:23Z","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.8.3\n"},{"id":"287345","messageId":"20160524072124.2945-4-pranit.bauva@gmail.com","threadId":"41774","inReplyTo":"20160524072124.2945-1-pranit.bauva@gmail.com","subject":"[PATCH v8 3/3] bisect--helper: `write_terms` shell function in C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-24T07:21:24Z","receivedAt":"2016-05-24T07:21:24Z","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..91027b0 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_write_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_write_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\" || exit\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.8.3\n"},{"id":"287346","messageId":"CAP8UFD1WZ=5e9u5awrHDG-vhMR5dw5NNY_yVEkp2o0rgx59nnQ@mail.gmail.com","threadId":"41774","inReplyTo":"20160524072124.2945-4-pranit.bauva@gmail.com","subject":"Re: [PATCH v8 3/3] bisect--helper: `write_terms` shell function in C","fromName":"Christian Couder","fromEmail":"christian.couder@gmail.com","sentAt":"2016-05-24T07:33:18Z","receivedAt":"2016-05-24T07:33:18Z","isPatch":true,"sender":{"key":"christian.couder@gmail.com","avatar":"https://avatars.githubusercontent.com/u/208954?v=4"},"body":"On Tue, May 24, 2016 at 9:21 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n> Reimplement the `write_terms` shell function in C and add a `write-terms`\n> subcommand to `git bisect--helper` to call it from git-bisect.sh . Also\n> remove the subcommand `--check-term-format` as it can now be called from\n> inside the function write_terms() C implementation.\n>\n> Also `|| exit` is added when calling write-terms subcommand from\n> git-bisect.sh so as to exit whenever there is an error.\n>\n> Using `--write-terms` subcommand is a temporary measure to port shell\n> function to C so as to use the existing test suite. As more functions\n> are ported, this subcommand will be retired and will be called by some\n> other method.\n>\n> Mentored-by: Lars Schneider <larsxschneider@gmail.com>\n> Mentored-by: Christian Couder <chriscool@tuxfamily.org>\n> Signed-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>\n> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c\n> index 3c748d1..91027b0 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_write_terms, \"BISECT_TERMS\")\n> +\n>  static const char * const git_bisect_helper_usage[] = {\n>         N_(\"git bisect--helper --next-all [--no-checkout]\"),\n> -       N_(\"git bisect--helper --check-term-format <term> <orig_term>\"),\n> +       N_(\"git bisect--helper --write-terms <bad_term> <good_term>\"),\n>         NULL\n>  };\n>\n> @@ -56,18 +58,38 @@ static int check_term_format(const char *term, const char *orig_term)\n>         return 0;\n>  }\n>\n> +static int write_terms(const char *bad, const char *good)\n> +{\n> +       FILE *fp;\n> +       int res;\n> +\n> +       if (!strcmp(bad, good))\n> +               return error(_(\"please use two different terms\"));\n> +\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> +       if (!fp)\n> +               return error_errno(_(\"could not open the file BISECT_TERMS\"));\n> +\n> +       res = fprintf(fp, \"%s\\n%s\\n\", bad, good);\n> +       fclose(fp);\n> +       return (res < 0) ? -1 : 0;\n> +}\n> +\n>  int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>  {\n>         enum {\n>                 NEXT_ALL = 1,\n> -               CHECK_TERM_FMT\n> +               WRITE_TERMS\n>         } cmdmode = 0;\n>         int no_checkout = 0;\n>         struct option options[] = {\n>                 OPT_CMDMODE(0, \"next-all\", &cmdmode,\n>                          N_(\"perform 'git bisect next'\"), NEXT_ALL),\n> -               OPT_CMDMODE(0, \"check-term-format\", &cmdmode,\n> -                        N_(\"check format of the term\"), CHECK_TERM_FMT),\n> +               OPT_CMDMODE(0, \"write-terms\", &cmdmode,\n> +                        N_(\"write the terms to .git/BISECT_TERMS\"), WRITE_TERMS),\n>                 OPT_BOOL(0, \"no-checkout\", &no_checkout,\n>                          N_(\"update BISECT_HEAD instead of checking out the current commit\")),\n>                 OPT_END()\n> @@ -82,10 +104,10 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)\n>         switch (cmdmode) {\n>         case NEXT_ALL:\n>                 return bisect_next_all(prefix, no_checkout);\n> -       case CHECK_TERM_FMT:\n> +       case WRITE_TERMS:\n>                 if (argc != 2)\n> -                       die(_(\"--check-term-format requires two arguments\"));\n> -               return check_term_format(argv[0], argv[1]);\n> +                       die(_(\"--write-terms requires two arguments\"));\n> +               return write_terms(argv[0], argv[1]);\n>         default:\n>                 die(\"BUG: unknown subcommand '%d'\", cmdmode);\n>         }\n> diff --git a/git-bisect.sh b/git-bisect.sh\n> index 7d7965d..cd39bd0 100755\n> --- a/git-bisect.sh\n> +++ b/git-bisect.sh\n> @@ -210,7 +210,7 @@ bisect_start() {\n>         eval \"$eval true\" &&\n>         if test $must_write_terms -eq 1\n>         then\n> -               write_terms \"$TERM_BAD\" \"$TERM_GOOD\"\n> +               git bisect--helper --write-terms \"$TERM_BAD\" \"$TERM_GOOD\" || exit\n\nThis `|| exit` is not needed because...\n\n>         fi &&\n>         echo \"git bisect start$orig_args\" >>\"$GIT_DIR/BISECT_LOG\" || exit\n\n... there is an `|| exit` on the line above (which is chained using\n`&&` to the previous lines).\n"},{"id":"287431","messageId":"xmqqbn3v5p9w.fsf@gitster.mtv.corp.google.com","threadId":"41774","inReplyTo":"CAP8UFD1WZ=5e9u5awrHDG-vhMR5dw5NNY_yVEkp2o0rgx59nnQ@mail.gmail.com","subject":"Re: [PATCH v8 3/3] bisect--helper: `write_terms` shell function in C","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2016-05-24T17:39:23Z","receivedAt":"2016-05-24T17:39:23Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Christian Couder <christian.couder@gmail.com> writes:\n\n>> diff --git a/git-bisect.sh b/git-bisect.sh\n>> index 7d7965d..cd39bd0 100755\n>> --- a/git-bisect.sh\n>> +++ b/git-bisect.sh\n>> @@ -210,7 +210,7 @@ bisect_start() {\n>>         eval \"$eval true\" &&\n>>         if test $must_write_terms -eq 1\n>>         then\n>> -               write_terms \"$TERM_BAD\" \"$TERM_GOOD\"\n>> +               git bisect--helper --write-terms \"$TERM_BAD\" \"$TERM_GOOD\" || exit\n>\n> This `|| exit` is not needed because...\n>\n>>         fi &&\n>>         echo \"git bisect start$orig_args\" >>\"$GIT_DIR/BISECT_LOG\" || exit\n>\n> ... there is an `|| exit` on the line above (which is chained using\n> `&&` to the previous lines).\n\nCould you please trim parts that you are not commenting on when\nquoting?  Thanks.\n"},{"id":"287435","messageId":"CAFZEwPMiNNB5CKOYWmHGR=sU8i1t9qb+-RTSrcNVkVZW14UMFg@mail.gmail.com","threadId":"41774","inReplyTo":"CAP8UFD1WZ=5e9u5awrHDG-vhMR5dw5NNY_yVEkp2o0rgx59nnQ@mail.gmail.com","subject":"Re: [PATCH v8 3/3] bisect--helper: `write_terms` shell function in C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-24T18:31:29Z","receivedAt":"2016-05-24T18:31:29Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"Hey Christian,\n\nOn Tue, May 24, 2016 at 1:03 PM, Christian Couder\n<christian.couder@gmail.com> wrote:\n> On Tue, May 24, 2016 at 9:21 AM, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>> diff --git a/git-bisect.sh b/git-bisect.sh\n>> index 7d7965d..cd39bd0 100755\n>> --- a/git-bisect.sh\n>> +++ b/git-bisect.sh\n>> @@ -210,7 +210,7 @@ bisect_start() {\n>>         eval \"$eval true\" &&\n>>         if test $must_write_terms -eq 1\n>>         then\n>> -               write_terms \"$TERM_BAD\" \"$TERM_GOOD\"\n>> +               git bisect--helper --write-terms \"$TERM_BAD\" \"$TERM_GOOD\" || exit\n>\n> This `|| exit` is not needed because...\n>\n>>         fi &&\n>>         echo \"git bisect start$orig_args\" >>\"$GIT_DIR/BISECT_LOG\" || exit\n>\n> ... there is an `|| exit` on the line above (which is chained using\n> `&&` to the previous lines).\n\nNice notice. I will send a re-roll\n\nRegards,\nPranit Bauva\n"},{"id":"287478","messageId":"alpine.DEB.2.20.1605250657250.4449@virtualbox","threadId":"41774","inReplyTo":"20160524072124.2945-3-pranit.bauva@gmail.com","subject":"Re: [PATCH v8 2/3] bisect: rewrite `check_term_format` shell function in C","fromName":"Johannes Schindelin","fromEmail":"johannes.schindelin@gmx.de","sentAt":"2016-05-25T05:04:38Z","receivedAt":"2016-05-25T05:04:38Z","isPatch":true,"sender":{"key":"johannes.schindelin@gmx.de","avatar":"https://avatars.githubusercontent.com/u/127790?v=4"},"body":"Hi Pranit,\n\nI think this patch series is now in a fine shape. Just one minor nit:\n\nOn Tue, 24 May 2016, Pranit Bauva wrote:\n\n> +\t\tOPT_CMDMODE(0, \"check-term-format\", &cmdmode,\n> +\t\t\t N_(\"check format of the term\"), CHECK_TERM_FMT),\n\nJust like with cmd_mode and CMD_MODE, it would be more consistent to use\nCHECK_TERM_FORMAT (instead of abbreviating it) when the option is already\nspelled --check-term-format and the function name is check_term_format.\n\nIt not only causes the eyes to stumble less, being consistent in naming\ncauses less typos and also makes it easier to dig into the source code\n(think: `git grep -i check.name.format`).\n\nNot a big thing, but if you re-roll for any other reason, it would be good\nto make the naming consistent, too.\n\nCiao,\nJohannes\n"},{"id":"287480","messageId":"CAFZEwPPf6sRnJDyW9hLjEYa-=6Bjw_rWss9T5D_n_aXUX=TcGA@mail.gmail.com","threadId":"41774","inReplyTo":"alpine.DEB.2.20.1605250657250.4449@virtualbox","subject":"Re: [PATCH v8 2/3] bisect: rewrite `check_term_format` shell function in C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-05-25T05:13:43Z","receivedAt":"2016-05-25T05:13:43Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"Hey Johannes,\n\nOn Wed, May 25, 2016 at 10:34 AM, Johannes Schindelin\n<Johannes.Schindelin@gmx.de> wrote:\n> Hi Pranit,\n>\n> I think this patch series is now in a fine shape. Just one minor nit:\n\nThanks!\n\n> On Tue, 24 May 2016, Pranit Bauva wrote:\n>\n>> +             OPT_CMDMODE(0, \"check-term-format\", &cmdmode,\n>> +                      N_(\"check format of the term\"), CHECK_TERM_FMT),\n>\n> Just like with cmd_mode and CMD_MODE, it would be more consistent to use\n> CHECK_TERM_FORMAT (instead of abbreviating it) when the option is already\n> spelled --check-term-format and the function name is check_term_format.\n>\n> It not only causes the eyes to stumble less, being consistent in naming\n> causes less typos and also makes it easier to dig into the source code\n> (think: `git grep -i check.name.format`).\n>\n> Not a big thing, but if you re-roll for any other reason, it would be good\n> to make the naming consistent, too.\n\nSure I would include this in a re-roll. Anywhich ways it will really\nnot make a big difference because after some time, \"git grep -i\ncheck.term.format\" wouldn't return anything except for the method\nname. Other occurrences would be vanished.\n\nRegards,\nPranit Bauva\n\n> Ciao,\n> Johannes\n"},{"id":"289394","messageId":"B8F28BE0-B43A-489F-9BCC-B40712C450D3@gmail.com","threadId":"41774","inReplyTo":"20160524072124.2945-3-pranit.bauva@gmail.com","subject":"Re: [PATCH v8 2/3] bisect: rewrite `check_term_format` shell function in C","fromName":"Lars Schneider","fromEmail":"larsxschneider@gmail.com","sentAt":"2016-06-16T07:10:12Z","receivedAt":"2016-06-16T19:58:03Z","isPatch":true,"sender":{"key":"larsxschneider@gmail.com","avatar":"https://avatars.githubusercontent.com/u/477434?v=4"},"body":"\nOn 24 May 2016, at 09:21, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n\n> Reimplement the `check_term_format` shell function in C and add\n> a `--check-term-format` subcommand to `git bisect--helper` to call it\n> from git-bisect.sh\n> \n> Using `--check-term-format` subcommand is a temporary measure to port\n> shell function to C so as to use the existing test suite. As more\n> functions are ported, this subcommand will be retired and will\n> be called by some other method/subcommand. For eg. In conversion of\n> write_terms() of git-bisect.sh, the subcommand will be removed and\n> instead check_term_format() will be called in its C implementation while\n> a new subcommand will be introduced for write_terms().\n> \n> Helped-by: Johannes Schindelein <Johannes.Schindelein@gmx.de>\n> Mentored-by: Lars Schneider <larsxschneider@gmail.com>\n> Mentored-by: Christian Couder <chriscool@tuxfamily.org>\n\nHi Pranit,\n\nplease drop my Mentored-by until I contribute something\nuseful. I feel bad being mentioned in the same way as\nChristian although he does all the work.\n\nThanks,\nLars\n\n> Signed-off-by: Pranit Bauva <pranit.bauva@gmail.com>\n> ---\n\n"},{"id":"289437","messageId":"CAFZEwPNJLk3Y2KQopsc6AC4-LHUeam-ts5sHn4qdhbKM8UWiGA@mail.gmail.com","threadId":"41774","inReplyTo":"B8F28BE0-B43A-489F-9BCC-B40712C450D3@gmail.com","subject":"Re: [PATCH v8 2/3] bisect: rewrite `check_term_format` shell function in C","fromName":"Pranit Bauva","fromEmail":"pranit.bauva@gmail.com","sentAt":"2016-06-17T12:48:48Z","receivedAt":"2016-06-17T12:48:53Z","isPatch":true,"sender":{"key":"pranit.bauva@gmail.com","avatar":"https://avatars.githubusercontent.com/u/2959938?v=4"},"body":"Hey Lars,\nHope you enjoyed your vacations. :)\n\nOn Thu, Jun 16, 2016 at 12:40 PM, Lars Schneider\n<larsxschneider@gmail.com> wrote:\n>\n> On 24 May 2016, at 09:21, Pranit Bauva <pranit.bauva@gmail.com> wrote:\n>\n>> Reimplement the `check_term_format` shell function in C and add\n>> a `--check-term-format` subcommand to `git bisect--helper` to call it\n>> from git-bisect.sh\n>>\n>> Using `--check-term-format` subcommand is a temporary measure to port\n>> shell function to C so as to use the existing test suite. As more\n>> functions are ported, this subcommand will be retired and will\n>> be called by some other method/subcommand. For eg. In conversion of\n>> write_terms() of git-bisect.sh, the subcommand will be removed and\n>> instead check_term_format() will be called in its C implementation while\n>> a new subcommand will be introduced for write_terms().\n>>\n>> Helped-by: Johannes Schindelein <Johannes.Schindelein@gmx.de>\n>> Mentored-by: Lars Schneider <larsxschneider@gmail.com>\n>> Mentored-by: Christian Couder <chriscool@tuxfamily.org>\n>\n> Hi Pranit,\n>\n> please drop my Mentored-by until I contribute something\n> useful. I feel bad being mentioned in the same way as\n> Christian although he does all the work.\n\nSure! I will looking forward for you to comment more!\n\nRegards,\nPranit Bauva\n"}]}