On Wed, May 4, 2016 at 12:22 PM, Eric Sunshine <sunsh...@sunshineco.com> wrote:
> On Wed, May 4, 2016 at 1:07 AM, Pranit Bauva <pranit.ba...@gmail.com> wrote:
>> This reimplements the `check_term_format` shell function in C and adds
>
> s/This reimplements/Reimplement/
> s/adds/add/
>
>> a `--check-term-format` subcommand to `git bisect--helper` to call it
>> from git-bisect.sh
>
> s/$/./

Sure.

> Okay, I'll bite: Why is this a good idea? What does it buy you?
>
> It's not as if the rewrite is especially faster or more easily
> expressed in C; quite the contrary, the shell code is more concise and
> probably about equally as fast (not that execution speed matters in
> this case).
>
> I could understand this functionality being ported to C in the form of
> a static function as a minor part of porting "git bisect terms" in its
> entirety to C, but I'm not imaginative enough to see why this
> functionality is useful as a standalone git-bisect--helper subcommand,
> and the commit message doesn't enlighten. Consequently, it seems like
> unnecessary complexity.

It is important to understand that the subcommand is just a
**temporary** measure.
Yes, I agree that making it a subcommand increases unnecessary
complexity. As a part of complete rewrite of git-bisect.sh, I am
converting one function individually to C. The functionality of
subcommand is useful so that I can use the existing test suite to
verify whether I have done the conversion properly. As more functions
get ported (which I intend to finish this summers), previously
existing subcommands will be removed. For eg. After this patch, I will
now convert the function write_terms(). So in that patch, I will
remove the subcommand for check-term-format and instead use the
check_term_format() method and then introduce a new subcommand for
write_terms(). Verifying the function conversion was suggested by
Stefan Beller[1] and Christian Couder[2] gave a hint of how to go
about with using the existing test suite. As for the current
situation, git-bisect.sh calls `--next-all` in a similar way which was
the hint for me of how to go about with this project.

>> Signed-off-by: Pranit Bauva <pranit.ba...@gmail.com>
>> ---
>> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c
>> @@ -2,16 +2,66 @@
>>  static const char * const git_bisect_helper_usage[] = {
>>         N_("git bisect--helper --next-all [--no-checkout]"),
>> +       N_("git bisect--helper --check-term-format <term> <orig_term>"),
>
> Could this be shortened to --check-term or would that be undesirable?

I guess --check-term-format would be more appropriate and as this is
temporary, it wouldn't matter afterwards.

>>         NULL
>>  };
>>
>>  enum sub_commands {
>> -       NEXT_ALL = 1
>> +       NEXT_ALL = 1,
>> +       CHECK_TERM_FMT
>>  };
>>
>> +/*
>> + * To check whether the string `term` belongs to the set of strings
>> + * included in the variable arguments so as to make the code look
>> + * clean and avoid having long lines in the `if` statement.
>> + */
>
> Is this a (long) sentence fragment? Code cleanliness is an obviously
> desirable trait, thus talking about it in the comment adds no value;
> it's just noise.

I will keep the initial part of the comment.

>> +static int one_of(const char *term, ...)
>> +{
>> +       va_list matches;
>> +       const char *match;
>> +
>> +       va_start(matches, term);
>> +       while ((match = va_arg(matches, const char *)) != NULL)
>> +               if (!strcmp(term, match))
>> +                       return 1;
>
> Is it wise to return here without invoking va_end()?

I guess since it already checks for NULL, invoking va_end() will make
it redundant[3].

>> +       va_end(matches);
>> +
>> +       return 0;
>> +}
>> +
>> +static int check_term_format(const char *term, const char *orig_term,
>> +                            int flag)
>
> What is 'flag' for? The single caller only ever passes 0, so why is this 
> needed?

Well, currently the subcommand does not use this flag but this flag is
present in the method check_refname_format() so it would be better to
use it. This flag might be useful in further parts of conversion since
as I previously mentioned check-term-format isn't a permanent
solution.

>> +{
>> +       struct strbuf new_term = STRBUF_INIT;
>
> 'new_term' is being leaked at every 'return' statement in this function.

I will have to free this memory.

>
>> +       strbuf_addf(&new_term, "refs/bisect/%s", term);
>> +
>> +       if (check_refname_format(new_term.buf, flag))
>> +               die(_("'%s' is not a valid term\n"), term);
>
> Why does this die() while the other "invalid" cases merely return
> error()? What makes this special?

This is because I felt that if check_refname_format() fails then its a
fatal error while in other cases, it is not as fatal.

> Also, drop "\n" from the error string.

Sure!

>> +       else if (one_of(term, "help", "start", "skip", "next", "reset",
>
> s/else //

Agree since it would be a part of the switch which is not included
with the check_refname_format().

>> +                       "visualize", "replay", "log", "run", NULL))
>> +               return error("can't use the builtin command '%s' as a 
>> term\n", term);
>
> This should be wrapped in _(...). Also, drop the "\n".
>
>> +       /*
>> +        * In theory, nothing prevents swapping
>> +        * completely good and bad, but this situation
>> +        * could be confusing and hasn't been tested
>> +        * enough. Forbid it for now.
>> +        */
>
> This would be a bit easier to read if re-wrapped to fit within 80
> columns rather than 53 or so.
>
>> +       else if ((one_of(term, "bad", "new", NULL) && strcmp(orig_term, 
>> "bad")) ||
>
> s/else //

In the shell script a switch was used, thus `else if` would be a more
appropriate choice over `if`. Also if the first if statement fails
then it is unnecessary to go further.

>
>> +                (one_of(term, "good", "old", NULL) && strcmp(orig_term, 
>> "good")))
>
> This can be more efficient by doing the strcmp() before the expensive 
> one_of():
>
>     if ((strcmp(...) && one_of(...)) ||
>         strcmp(...) && one_of(...)))

Nice. Will include this.

>> +               return error("can't change the meaning of the term '%s'\n", 
>> term);
>
> This should be wrapped in _(...). Also, drop the "\n".

Sure

>
>> +       return 0;
>> +}
>> +
>>  int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
>>  {
>>         int sub_command = 0;
>> @@ -19,6 +69,8 @@ int cmd_bisect__helper(int argc, const char **argv, const 
>> char *prefix)
>>         struct option options[] = {
>>                 OPT_CMDMODE(0, "next-all", &sub_command,
>>                          N_("perform 'git bisect next'"), NEXT_ALL),
>> +               OPT_CMDMODE(0, "check-term-format", &sub_command,
>> +                        N_("check format of the ref"), CHECK_TERM_FMT),
>
> What "ref"?

The ref here means that ref (like HEAD).


>>                 OPT_BOOL(0, "no-checkout", &no_checkout,
>>                          N_("update BISECT_HEAD instead of checking out the 
>> current commit")),
>>                 OPT_END()
>> @@ -33,6 +85,10 @@ int cmd_bisect__helper(int argc, const char **argv, const 
>> char *prefix)
>>         switch (sub_command) {
>>         case NEXT_ALL:
>>                 return bisect_next_all(prefix, no_checkout);
>> +       case CHECK_TERM_FMT:
>> +               if (argc != 2)
>> +                       die(_("--check-term-format should be followed by 
>> exactly 2 arguments."));
>
> Drop the period. Possible reword:
>
>     --check-term-format requires two arguments

Seems better

>> +               return check_term_format(argv[0], argv[1], 0);
>>         default:
>>                 die(_("bug: unknown subcommand '%d'"), sub_command);
>>         }

[1]: http://article.gmane.org/gmane.comp.version-control.git/293489

[2]: http://article.gmane.org/gmane.comp.version-control.git/293489

[3]: http://article.gmane.org/gmane.comp.version-control.git/293489
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majord...@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to