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

Re: [PATCH/WIP v3 07/31] am: extract patch, message and authorship with git-mailinfo

From
Paul Tan <pyokagan@gmail.com>
Date
Jun 26, 2015, 08:11 UTC
Message-ID
<CACRoPnSyu6or8nkMQ0yS_KcLwumJVNv3pfSFGcSDyk4-P_VZ_A@mail.gmail.com>
In-Reply-To
<72c470f3a6890dfcb66f1439383d2278@www.dscho.org>

On Thu, Jun 25, 2015 at 12:36 AM, Johannes Schindelin <johannes.schindelin@gmx.de> wrote:

Show 44 quoted lines
> On 2015-06-18 13:25, Paul Tan wrote:
>> diff --git a/builtin/am.c b/builtin/am.c
>> index 7b97ea8..d6434e4 100644
>> --- a/builtin/am.c
>> +++ b/builtin/am.c
>> @@ -94,6 +126,105 @@ static int read_state_file(struct strbuf *sb,
>> const char *file, size_t hint, int
>>  }
>>
>>  /**
>> + * Reads a KEY=VALUE shell variable assignment from fp, and returns the VALUE
>> + * in `value`. VALUE must be a quoted string, and the KEY must match `key`.
>> + * Returns 0 on success, -1 on failure.
>> + *
>> + * This is used by read_author_script() to read the GIT_AUTHOR_* variables from
>> + * the author-script.
>> + */
>> +static int read_shell_var(struct strbuf *value, FILE *fp, const char *key)
>> +{
>> +     struct strbuf sb = STRBUF_INIT;
>> +     char *str;
>> +
>> +     if (strbuf_getline(&sb, fp, '\n'))
>> +             return -1;
>> +
>> +     if (!skip_prefix(sb.buf, key, (const char **)&str))
>> +             return -1;
>> +
>> +     if (!skip_prefix(str, "=", (const char **)&str))
>> +             return -1;
>> +
>> +     str = sq_dequote(str);
>> +     if (!str)
>> +             return -1;
>> +
>> +     strbuf_reset(value);
>> +     strbuf_addstr(value, str);
>> +
>> +     strbuf_release(&sb);
>> +
>> +     return 0;
>> +}
>
> How about using `strbuf_remove()` and keeping `str` as `const char *`?
OK, I'll try that out. Looks like this now:
static char *read_shell_var(FILE *fp, const char *key)
{
    struct strbuf sb = STRBUF_INIT;
    const char *str;
    if (strbuf_getline(&sb, fp, '\n'))
        return NULL;
    if (!skip_prefix(sb.buf, key, &str))
        return NULL;
    if (!skip_prefix(str, "=", &str))
        return NULL;
    strbuf_remove(&sb, 0, str - sb.buf);
    str = sq_dequote(sb.buf);
    if (!str)
        return NULL;
    return strbuf_detach(&sb, NULL);
}
> I also think we can fold it into the `read_author_script()` function and make it more resilient with regards to the order of the variables. Something like this:
> [...]

Hmm, I think we should be very strict about parsing the author-script file though. As explained in read_author_script(), git-am.sh evals the author-script, which we can't in C. I would much rather we barf at the first sign that the author-script is not what we expect, rather than attempt to parse it as much as possible, but end up with the wrong results as compared to git-am.sh.

Besides, currently git-am.sh will always write the author-script with the order of GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL and GIT_AUTHOR_DATE. If the order is wrong, I would think it means that something is messing with the author-script, and it would be better if we bail out immediately, instead of potentially doing something wrong.

Show 18 quoted lines
>> +/**
>> + * Saves state->author_name, state->author_email and state->author_date in
>> + * `filename` as an "author script", which is the format used by git-am.sh.
>> + */
>> +static void write_author_script(const struct am_state *state)
>> +{
>> +     static const char fmt[] = "GIT_AUTHOR_NAME=%s\n"
>> +             "GIT_AUTHOR_EMAIL=%s\n"
>> +             "GIT_AUTHOR_DATE=%s\n";
>> +     struct strbuf author_name = STRBUF_INIT;
>> +     struct strbuf author_email = STRBUF_INIT;
>> +     struct strbuf author_date = STRBUF_INIT;
>> +
>> +     sq_quote_buf(&author_name, state->author_name.buf);
>> +     sq_quote_buf(&author_email, state->author_email.buf);
>> +     sq_quote_buf(&author_date, state->author_date.buf);
>
> The `sq_quote_buf()` function does not call `strbuf_reset()`. Therefore you could just use a single strbuf to construct the entire three lines and then write that out. Again, if you follow my suggestion to keep a "scratch pad" strbuf in am_state, you could reuse that.
Right, makes sense. I've implemented it on my end.

Thanks, Paul

Previous: Johannes SchindelinNext: Junio C Hamano
Message 34 of 64 in “Make git-am a builtin”
  1. 00/31 Make git-am a builtinPaul Tan, Jun 18, 2015
  2. 01/31 wrapper: implement xopen()Paul Tan, Jun 18, 2015
  3. Johannes SchindelinJun 24, 2015
  4. Stefan BellerJun 24, 2015
  5. Johannes SchindelinJun 24, 2015
  6. Paul TanJul 1, 2015
  7. Paul TanJul 1, 2015
  8. 02/31 wrapper: implement xfopen()Paul Tan, Jun 18, 2015
  9. 03/31 am: implement skeletal builtin amPaul Tan, Jun 18, 2015
  10. Junio C HamanoJun 18, 2015
  11. Paul TanJun 19, 2015
  12. 04/31 am: implement patch queue mechanismPaul Tan, Jun 18, 2015
  13. Stefan BellerJun 18, 2015
  14. Junio C HamanoJun 18, 2015
  15. Paul TanJun 19, 2015
  16. Johannes SchindelinJun 24, 2015
  17. Paul TanJun 25, 2015
  18. 05/31 am: split out mbox/maildir patches with git-mailsplitPaul Tan, Jun 18, 2015
  19. Junio C HamanoJun 18, 2015
  20. 06/31 am: detect mbox patchesPaul Tan, Jun 18, 2015
  21. Junio C HamanoJun 18, 2015
  22. Paul TanJun 24, 2015
  23. Johannes SchindelinJun 24, 2015
  24. Paul TanJun 25, 2015
  25. Paul TanJun 26, 2015
  26. 07/31 am: extract patch, message and authorship with git-mailinfoPaul Tan, Jun 18, 2015
  27. Junio C HamanoJun 18, 2015
  28. Paul TanJun 19, 2015
  29. Junio C HamanoJun 19, 2015
  30. Paul TanJun 24, 2015
  31. Junio C HamanoJun 24, 2015
  32. Paul TanJun 25, 2015
  33. Johannes SchindelinJun 24, 2015
  34. Paul TanJun 26, 2015
  35. Junio C HamanoJun 26, 2015
  36. 08/31 am: apply patch with git-applyPaul Tan, Jun 18, 2015
  37. Junio C HamanoJun 18, 2015
  38. 09/31 am: commit applied patchPaul Tan, Jun 18, 2015
  39. 10/31 am: refresh the index at startPaul Tan, Jun 18, 2015
  40. Junio C HamanoJun 18, 2015
  41. Paul TanJun 19, 2015
  42. 11/31 am: refuse to apply patches if index is dirtyPaul Tan, Jun 18, 2015
  43. 12/31 am: implement --resolved/--continuePaul Tan, Jun 18, 2015
  44. 13/31 am: implement --skipPaul Tan, Jun 18, 2015
  45. 14/31 am: implement --abortPaul Tan, Jun 18, 2015
  46. 15/31 am: don't accept patches when there's a session in progressPaul Tan, Jun 18, 2015
  47. 16/31 am: implement quiet optionPaul Tan, Jun 18, 2015
  48. 17/31 am: exit with user friendly message on patch failurePaul Tan, Jun 18, 2015
  49. 18/31 am: implement am --signoffPaul Tan, Jun 18, 2015
  50. 19/31 cache-tree: introduce write_index_as_tree()Paul Tan, Jun 18, 2015
  51. 20/31 am: implement 3-way mergePaul Tan, Jun 18, 2015
  52. 21/31 am: --rebasingPaul Tan, Jun 18, 2015
  53. 22/31 am: don't use git-mailinfo if --rebasingPaul Tan, Jun 18, 2015
  54. 23/31 am: handle stray state directoryPaul Tan, Jun 18, 2015
  55. 24/31 am: implement -k/--keep, --keep-non-patchPaul Tan, Jun 18, 2015
  56. 25/31 am: implement --[no-]message-id, am.messageidPaul Tan, Jun 18, 2015
  57. 26/31 am: support --keep-cr, am.keepcrPaul Tan, Jun 18, 2015
  58. 27/31 am: implement --[no-]scissorsPaul Tan, Jun 18, 2015
  59. 28/31 am: pass git-apply's options to git-applyPaul Tan, Jun 18, 2015
  60. 29/31 am: implement --ignore-datePaul Tan, Jun 18, 2015
  61. 30/31 am: implement --committer-date-is-author-datePaul Tan, Jun 18, 2015
  62. 31/31 am: implement -S/--gpg-sign, commit.gpgsignPaul Tan, Jun 18, 2015
  63. Paul TanJun 19, 2015
  64. Johannes SchindelinJun 19, 2015

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.