Re: [PATCH v3] bisect--helper: convert a function in shell to C

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Mar 23, 2016 at 5:27 PM, Johannes Schindelin
<Johannes.Schindelin@xxxxxx> wrote:
> Hi Pranit,
>
> On Wed, 23 Mar 2016, Pranit Bauva wrote:
>
>> Convert the code literally without changing its design even though it
>> seems that it is obscure as to the use of comparing revision to different
>> bisect arguments which seems like a problem in shell because of the way
>> function arguments are handled.
>
> I still believe that it would make for an improvement to replace
> "revision" by "orig_term".

I missed this. Will do it.

>> The argument handling is kind of hard coded right now because it is not
>> really be meant to be used like this and this is just for testing
>> purposes whether this new method is as functional as its counter part.
>> The shell counter part of the method has been retained for historical
>> purposes.
>
> Well, maybe the argument handling is really meant to be used like this in
> the end? Just skip that paragraph.

Sure.

>> Also using OPT_CMDMODE() to handle check-term-format and next-all
>> because these sub commands are independent and error should be shown if
>> used together and should be handled independently.
>
> As is often the case, after some discussion a single patch becomes more
> than just one change. This is what we see here, too: OPT_CMDMODE() is a
> change that needs preparation of the existing code in
> builtin/bisect--helper.c, and I would highly suggest to split that change
> out into its own patch. It makes for a nicer story, and it is *much*
> easier to review.
>
>> This commit reduces the number of failed tests in
>> t6030-bisect-porcelain.sh and t6041-bisect-submodule.sh
>
> Oh? Which tests are supposed to fail? I do not see any failing tests
> here...

What I meant by this is that before there were 55 out of 70 tests
which failed. After this patch, there are 3 tests out of 70 which
failed.

>> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c
>> index 3324229..ab3891c 100644
>> --- a/builtin/bisect--helper.c
>> +++ b/builtin/bisect--helper.c
>> [...]
>> +static int check_term_format(const char *term, const char *revision, int flag) {
>> +     if (check_refname_format(term, flag))
>> +             die("'%s' is not a valid term", term);
>> +
>> +     if (one_of(term, "help", "start", "skip", "next", "reset", "visualize",
>> +         "replay", "log", "run", NULL))
>
> If I understood Junio correctly, he meant to line up the second line with
> the corresponding level. In this case, as "replay" is a parameter of the
> one_of() function, the indentation would look like this instead:

I misunderstood his point.

>         if (one_of(term, "help", "start", "skip", "next", "reset", "visualize",
>                    "replay", "log", "run", NULL))
>
>> +             die("can't use the builtin command '%s' as a term", term);
>> +
>> +     /* 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.
>> +      */
>
> I see quite a few comments that put the closing "*/" on its own line, but
> do not award the same pleasure to the opening "/*". Personally, I much
> prefer the opening "/*" to have an entire line to itself, too, but I guess
> that there is enough precendence in Git's source code to accept both
> forms.
>
>> +     if (!strcmp(term, "bad") || !strcmp(term, "new"))
>> +             if (strcmp(revision, "bad"))
>> +                     die("can't change the meaning of term '%s'", term);
>> +
>> +     if(!strcmp(term, "good") || !strcmp(term, "old"))
>> +             if (strcmp(revision, "good"))
>> +                     die("can't change the meaning of term '%s'", term);
>
> I am still convinced that
>
>         if ((one_of(term, "bad", "new", NULL) && strcmp(orig_term, "bad")) ||
>             (one_of(term, "good", "old", NULL) && strcmp(orig_term, "good")))
>                 die("can't change the meaning of term '%s'", term);
>
> looks so much nicer.

True. I missed this point.

>>  int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
>>  {
>> -     int next_all = 0;
>> +     int sub_command = 0;
>>       int no_checkout = 0;
>> +
>> +     enum sub_commands {
>> +             NEXT_ALL,
>> +             CHECK_TERM_FMT
>> +     };
>
> Interesting. I did not think that Git's source code declares enums inside
> functions, but builtin/remote.c's config_read_branches() does, so this
> code is fine.

I didn't notice this before. Since git has the convention of declaring
enums outside function, it will be better to follow the trend rather
than allowing another trend to spread.

> Still, the patch would be easier to review (corollary: bugs would have a
> harder time to hide) if the change from OPT_BOOL to OPT_CMDMODE was done
> in a separate, preparatory patch.

I was confused about this. Now that u mention it, I will make the change.

>>       argc = parse_options(argc, argv, prefix, options,
>>                            git_bisect_helper_usage, 0);
>>
>> -     if (!next_all)
>> +     if (sub_command == CHECK_TERM_FMT) {
>> +             if (argc == 2) {
>> +                     if (argv[0] != NULL && argv[1] != NULL)
>> +                             return check_term_format(argv[0], argv[1], 0);
>> +                     else
>> +                             die("no revision or term provided with check_for_term");
>> +             }
>> +             else
>> +                     die("--check-term-format expects 2 arguments");
>> +     }
>> +
>> +     if (sub_command != NEXT_ALL && sub_command != CHECK_TERM_FMT)
>>               usage_with_options(git_bisect_helper_usage, options);
>
> Personally, I would prefer
>
> - the usage_with_options() code to come before any sub_command processing,
>
> - the sub_command enum to be initialized with -1, or alternatively
>   hardcoding NEXT_ALL to 1,

Oh! I now understand that initializing with 0 can be problematic.

> - to avoid else clauses after an if () clause whose block returns or
>   die()s,

Sure

> - to order the clauses of an if/else in ascending size, i.e.
>
>         if (argc != 2)
>                 die(...);
>         if ...
>
> - to avoid checking argv[i] for NULL when i < argc (it is the contract
>   that argv[0..argc-1] are all non-NULL, so checking for it is unnecessary
>   churn),

I wasn't aware of this.

> - use a switch() on sub_command instead of unrolled if () statements, and
I just browsed through some other parts and found that subcommands are
put in switch case

> - wrap the code at 80 columns/row (interpreting tabs as "up to 8 spaces").


> The rest of the patch looks good.
>
> Ciao,
> Johannes

Thanks!
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]