git/list[1] front-page[2] threads[3] people[4] search[5] about
 

Re: [PATCH v15 15/27] bisect--helper: `bisect_next` and `bisect_auto_next` shell function in C

From
Pranit Bauva <pranit.bauva@gmail.com>
Date
Dec 31, 2016, 10:43 UTC
Message-ID
<CAFZEwPPtF5P5nGp+=btHtwNm1unTJ7qo1khJHCqLvNn1=RYAUQ@mail.gmail.com>
In-Reply-To
<06402c8a-14a4-3d70-8d98-659cfe9f1aa2@gmx.net>
Hey Stephan,
On Tue, Nov 22, 2016 at 3:05 AM, Stephan Beyer <s-beyer@gmx.net> wrote:
Show 35 quoted lines
> Hi Pranit,
>
> in this mail I review the "second part" of your patch: the transition of
> bisect_next and bisect_auto_next to C.
>
> On 10/14/2016 04:14 PM, Pranit Bauva wrote:
>> diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c
>> index 1d3e17f..fcd7574 100644
>> --- a/builtin/bisect--helper.c
>> +++ b/builtin/bisect--helper.c
>> @@ -408,6 +411,136 @@ static int bisect_terms(struct bisect_terms *terms, const char **argv, int argc)
>>       return 0;
>>  }
>>
>> +static int register_good_ref(const char *refname,
>> +                          const struct object_id *oid, int flags,
>> +                          void *cb_data)
>> +{
>> +     struct string_list *good_refs = cb_data;
>> +     string_list_append(good_refs, oid_to_hex(oid));
>> +     return 0;
>> +}
>> +
>> +static int bisect_next(struct bisect_terms *terms, const char *prefix)
>> +{
>> +     int res, no_checkout;
>> +
>> +     /*
>> +      * In case of mistaken revs or checkout error, or signals received,
>> +      * "bisect_auto_next" below may exit or misbehave.
>> +      * We have to trap this to be able to clean up using
>> +      * "bisect_clean_state".
>> +      */
>
> The comment above makes no sense here, or does it?

No it doesn't right now. I had this initally because I was trying to keep bisect_clean_state() call inside this function but then I realized it should be placed elsewhere. I will remove this.

Show 9 quoted lines
>> +     if (bisect_next_check(terms, terms->term_good))
>> +             return -1;
>> +
>> +     no_checkout = !is_empty_or_missing_file(git_path_bisect_head());
>> +
>> +     /* Perform all bisection computation, display and checkout */
>> +     res = bisect_next_all(prefix , no_checkout);
>
> Style: there is a space left of the comma.

Nice catch! ;) I have gone through this patch so many times, yet I have forgot to notice this.

Show 101 quoted lines
>> +
>> +     if (res == 10) {
>> +             FILE *fp = NULL;
>> +             unsigned char sha1[20];
>> +             struct commit *commit;
>> +             struct pretty_print_context pp = {0};
>> +             struct strbuf commit_name = STRBUF_INIT;
>> +             char *bad_ref = xstrfmt("refs/bisect/%s",
>> +                                           terms->term_bad);
>> +             int retval = 0;
>> +
>> +             read_ref(bad_ref, sha1);
>> +             commit = lookup_commit_reference(sha1);
>> +             format_commit_message(commit, "%s", &commit_name, &pp);
>> +             fp = fopen(git_path_bisect_log(), "a");
>> +             if (!fp) {
>> +                     retval = -1;
>> +                     goto finish_10;
>> +             }
>> +             if (fprintf(fp, "# first %s commit: [%s] %s\n",
>> +                         terms->term_bad, sha1_to_hex(sha1),
>> +                         commit_name.buf) < 1){
>> +                     retval = -1;
>> +                     goto finish_10;
>> +             }
>> +             goto finish_10;
>> +     finish_10:
>> +             if (fp)
>> +                     fclose(fp);
>> +             strbuf_release(&commit_name);
>> +             free(bad_ref);
>> +             return retval;
>> +     }
>> +     else if (res == 2) {
>> +             FILE *fp = NULL;
>> +             struct rev_info revs;
>> +             struct argv_array rev_argv = ARGV_ARRAY_INIT;
>> +             struct string_list good_revs = STRING_LIST_INIT_DUP;
>> +             struct pretty_print_context pp = {0};
>> +             struct commit *commit;
>> +             char *term_good = xstrfmt("%s-*", terms->term_good);
>> +             int i, retval = 0;
>> +
>> +             fp = fopen(git_path_bisect_log(), "a");
>> +             if (!fp) {
>> +                     retval = -1;
>> +                     goto finish_2;
>> +             }
>> +             if (fprintf(fp, "# only skipped commits left to test\n") < 1) {
>> +                     retval = -1;
>> +                     goto finish_2;
>> +             }
>> +             for_each_glob_ref_in(register_good_ref, term_good,
>> +                                  "refs/bisect/", (void *) &good_revs);
>> +
>> +             argv_array_pushl(&rev_argv, "skipped_commits", "refs/bisect/bad", "--not", NULL);
>> +             for (i = 0; i < good_revs.nr; i++)
>> +                     argv_array_push(&rev_argv, good_revs.items[i].string);
>> +
>> +             /* It is important to reset the flags used by revision walks
>> +              * as the previous call to bisect_next_all() in turn
>> +              * setups a revision walk.
>> +              */
>> +             reset_revision_walk();
>> +             init_revisions(&revs, NULL);
>> +             rev_argv.argc = setup_revisions(rev_argv.argc, rev_argv.argv, &revs, NULL);
>> +             argv_array_clear(&rev_argv);
>> +             string_list_clear(&good_revs, 0);
>> +             if (prepare_revision_walk(&revs))
>> +                     die(_("revision walk setup failed\n"));
>> +
>> +             while ((commit = get_revision(&revs)) != NULL) {
>> +                     struct strbuf commit_name = STRBUF_INIT;
>> +                     format_commit_message(commit, "%s",
>> +                                           &commit_name, &pp);
>> +                     fprintf(fp, "# possible first %s commit: "
>> +                                 "[%s] %s\n", terms->term_bad,
>> +                                 oid_to_hex(&commit->object.oid),
>> +                                 commit_name.buf);
>> +                     strbuf_release(&commit_name);
>> +             }
>> +             goto finish_2;
>> +     finish_2:
>> +             if (fp)
>> +                     fclose(fp);
>> +             string_list_clear(&good_revs, 0);
>> +             argv_array_clear(&rev_argv);
>> +             free(term_good);
>> +             if (retval)
>> +                     return retval;
>> +             else
>> +                     return res;
>> +     }
>> +     return res;
>> +}
>
> It would be much nicer if you put the (res == 10) branch and the
> (res == 2) branch into separate functions and just call them.
> Then you also won't need ugly label naming like finish_10 or finish_2.
> I'd also (again) recommend to use goto fail instead of setting retval to
> -1 separately each time.
Yes, that seems a better way to go! Thanks! :)
> I'd also recommend to use a separate function to append to the bisect
> log file. There is a lot of duplicated opening, checking, closing code;
> IIRC such a function would also already be handy for some of the
> previous patches.
True. I have made that function. Will reuse it here. Thanks! :)
Show 13 quoted lines
>> +
>> +static int bisect_auto_next(struct bisect_terms *terms, const char *prefix)
>> +{
>> +     if (!bisect_next_check(terms, NULL))
>> +             return bisect_next(terms, prefix);
>> +
>> +     return 0;
>> +}
>
> Hmm, the handling of the return values is a little confusing. However,
> if I understand the sh source correctly, it always returns success, no
> matter if bisect_next failed or not. I do not know if you had something
> special in mind here.

Umm. Shell code used to die() and thus exit with an error code. Thus it is important to return the exit code. Handling return values was *very confusing* for me too while writing this commit ;) A lot of behaviour is changed in this commit regarding return values.

Show 11 quoted lines
>>  int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
>> @@ -643,6 +794,10 @@ int cmd_bisect__helper(int argc, const char **argv, const char *prefix)
>>                        N_("print out the bisect terms"), BISECT_TERMS),
>>               OPT_CMDMODE(0, "bisect-start", &cmdmode,
>>                        N_("start the bisect session"), BISECT_START),
>> +             OPT_CMDMODE(0, "bisect-next", &cmdmode,
>> +                      N_("find the next bisection commit"), BISECT_NEXT),
>> +             OPT_CMDMODE(0, "bisect-auto-next", &cmdmode,
>> +                      N_("verify the next bisection state then find the next bisection state"), BISECT_AUTO_NEXT),
>
> The next bisection *state* is found?
checkout is more appropriate. I don't remember why I used "find".
Show 13 quoted lines
>> diff --git a/git-bisect.sh b/git-bisect.sh
>> index f0896b3..d574c44 100755
>> --- a/git-bisect.sh
>> +++ b/git-bisect.sh
>> @@ -139,45 +119,7 @@ bisect_state() {
>>       *)
>>               usage ;;
>>       esac
>> -     bisect_auto_next
> [...deleted lines...]
>> +     git bisect--helper --bisect-auto-next || exit
>
> Why is the "|| exit" necessary?

Since it returning exit code, we need to quit, see earlier comment. Earlier in shell script we used die() but now we are using return error() thus we need to make it exit here too.

Show 17 quoted lines
>> @@ -319,14 +260,15 @@ case "$#" in
>>       help)
>>               git bisect -h ;;
>>       start)
>> -             bisect_start "$@" ;;
>> +             git bisect--helper --bisect-start "$@" ;;
>>       bad|good|new|old|"$TERM_BAD"|"$TERM_GOOD")
>>               bisect_state "$cmd" "$@" ;;
>>       skip)
>>               bisect_skip "$@" ;;
>>       next)
>>               # Not sure we want "next" at the UI level anymore.
>> -             bisect_next "$@" ;;
>> +             get_terms
>> +             git bisect--helper --bisect-next "$@" || exit ;;
>
> Why is the "|| exit" necessary? ;)
Same as before.
>
> Furthermore:
> Where is the bisect_autostart call from bisect_next() sh source gone?
> Was it not necessary?

It is necessary, but I couldn't just incorporate it in one commit. The functions are called in a circular fashion. Thus I skipped bisect_autostart() as for now but then when I managed to port bisect_autostart(), I called that function from this.

Regards, Pranit Bauva

Previous: Stephan BeyerNext: Stephan Beyer
Message 51 of 82 in “bisect--helper: use OPT_CMDMODE instead of OPT_BOOL”
  1. 01/27 bisect--helper: use OPT_CMDMODE instead of OPT_BOOLPranit Bauva, Oct 14, 2016
  2. 06/27 wrapper: move is_empty_file() and rename it as is_empty_or_missing_file()Pranit Bauva, Oct 14, 2016
  3. 05/27 t6030: explicitly test for bisection cleanupPranit Bauva, Oct 14, 2016
  4. 22/27 bisect--helper: `bisect_log` shell function in CPranit Bauva, Oct 14, 2016
  5. Stephan BeyerNov 17, 2016
  6. Pranit BauvaDec 6, 2016
  7. 10/27 bisect--helper: `check_and_set_terms` shell function in CPranit Bauva, Oct 14, 2016
  8. Stephan BeyerNov 17, 2016
  9. Pranit BauvaDec 6, 2016
  10. 23/27 bisect--helper: `bisect_replay` shell function in CPranit Bauva, Oct 14, 2016
  11. Stephan BeyerNov 22, 2016
  12. Pranit BauvaDec 6, 2016
  13. Stephan BeyerDec 6, 2016
  14. Stephan BeyerDec 6, 2016
  15. Christian CouderDec 7, 2016
  16. 04/27 bisect--helper: `bisect_clean_state` shell function in CPranit Bauva, Oct 14, 2016
  17. Stephan BeyerNov 15, 2016
  18. Junio C HamanoNov 15, 2016
  19. Stephan BeyerNov 15, 2016
  20. Pranit BauvaNov 16, 2016
  21. 09/27 bisect--helper: `bisect_write` shell function in CPranit Bauva, Oct 14, 2016
  22. Stephan BeyerNov 17, 2016
  23. Pranit BauvaDec 6, 2016
  24. 20/27 bisect--helper: retire `--check-expected-revs` subcommandPranit Bauva, Oct 14, 2016
  25. 12/27 bisect--helper: `get_terms` & `bisect_terms` shell function in CPranit Bauva, Oct 14, 2016
  26. Stephan BeyerNov 17, 2016
  27. Pranit BauvaDec 6, 2016
  28. Stephan BeyerDec 6, 2016
  29. Pranit BauvaDec 7, 2016
  30. 13/27 bisect--helper: `bisect_start` shell function partially in CPranit Bauva, Oct 14, 2016
  31. Stephan BeyerNov 15, 2016
  32. Pranit BauvaNov 16, 2016
  33. Stephan BeyerNov 20, 2016
  34. Stephan BeyerNov 20, 2016
  35. 18/27 bisect--helper: `bisect_autostart` shell function in CPranit Bauva, Oct 14, 2016
  36. Stephan BeyerNov 20, 2016
  37. Pranit BauvaDec 6, 2016
  38. 21/27 bisect--helper: retire `--write-terms` subcommandPranit Bauva, Oct 14, 2016
  39. 19/27 bisect--helper: `bisect_state` & `bisect_head` shell function in CPranit Bauva, Oct 14, 2016
  40. Stephan BeyerNov 22, 2016
  41. Pranit BauvaDec 6, 2016
  42. Stephan BeyerDec 6, 2016
  43. Pranit BauvaDec 8, 2016
  44. 14/27 t6030: no cleanup with bad merge basePranit Bauva, Oct 14, 2016
  45. Junio C HamanoOct 14, 2016
  46. Pranit BauvaOct 15, 2016
  47. 15/27 bisect--helper: `bisect_next` and `bisect_auto_next` shell function in CPranit Bauva, Oct 14, 2016
  48. Stephan BeyerNov 20, 2016
  49. Pranit BauvaDec 31, 2016
  50. Stephan BeyerNov 21, 2016
  51. Pranit BauvaDec 31, 2016
  52. Stephan BeyerJan 1, 2017
  53. Pranit BauvaJan 1, 2017
  54. 07/27 bisect--helper: `bisect_reset` shell function in CPranit Bauva, Oct 14, 2016
  55. Stephan BeyerNov 16, 2016
  56. Pranit BauvaNov 17, 2016
  57. 17/27 bisect--helper: retire `--next-all` subcommandPranit Bauva, Oct 14, 2016
  58. 24/27 bisect--helper: retire `--bisect-write` subcommandPranit Bauva, Oct 14, 2016
  59. 03/27 bisect--helper: `write_terms` shell function in CPranit Bauva, Oct 14, 2016
  60. 02/27 bisect: rewrite `check_term_format` shell function in CPranit Bauva, Oct 14, 2016
  61. Stephan BeyerNov 14, 2016
  62. Pranit BauvaNov 15, 2016
  63. 26/27 bisect--helper: retire `--bisect-auto-next` subcommandPranit Bauva, Oct 14, 2016
  64. 16/27 bisect--helper: retire `--bisect-clean-state` subcommandPranit Bauva, Oct 14, 2016
  65. 08/27 bisect--helper: `is_expected_rev` & `check_expected_revs` shell function in CPranit Bauva, Oct 14, 2016
  66. Stephan BeyerNov 16, 2016
  67. Pranit BauvaDec 6, 2016
  68. Pranit BauvaDec 16, 2016
  69. Stephan BeyerDec 17, 2016
  70. Pranit BauvaDec 16, 2016
  71. Stephan BeyerDec 17, 2016
  72. 25/27 bisect--helper: retire `--bisect-autostart` subcommandPranit Bauva, Oct 14, 2016
  73. Pranit BauvaOct 14, 2016
  74. 11/27 bisect--helper: `bisect_next_check` & bisect_voc shell function in CPranit Bauva, Oct 14, 2016
  75. Stephan BeyerNov 17, 2016
  76. Pranit BauvaDec 6, 2016
  77. 27/27 bisect--helper: remove the dequote in bisect_start()Pranit Bauva, Oct 14, 2016
  78. Junio C HamanoOct 27, 2016
  79. Christian CouderOct 27, 2016
  80. Matthieu MoyOct 28, 2016
  81. Stephan BeyerNov 15, 2016
  82. Junio C HamanoNov 16, 2016

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.