On Fri, Sep 29, 2017 at 11:22:38PM -0700, Taylor Blau wrote:

> The %(contents) atom takes a contents "field" as its argument. Since 
> "trailers"
> is one of those fields, extend contents_atom_parser to parse "trailers"'s
> arguments when used through "%(contents)", like:
> 
>   %(contents:trailers:unfold,only)
> 
> A caveat: trailers_atom_parser expects NULL when no arguments are given (see:
> `parse_ref_filter_atom`). To simulate this behavior without teaching
> trailers_atom_parser to accept strings with length zero, conditionally pass
> NULL to trailers_atom_parser if the arguments portion of the argument to
> %(contents) is empty.

Yeah, this is a weird effect of trailers_atom_parser() doing double-duty
to parse both "%(contents:trailers)" and "%(trailers)".

Though I think trailers_atom_parser() does do the sensible thing with an
empty string (there are no options, so nothing to parse). I.e., I'd
expect the same thing out of:

  %(trailers:)

and

  %(trailers)

even though one gets a NULL "arg" field and the other gets an empty
string.

> diff --git a/Documentation/git-for-each-ref.txt 
> b/Documentation/git-for-each-ref.txt
> index b7325a25d..0aaac8af9 100644
> --- a/Documentation/git-for-each-ref.txt
> +++ b/Documentation/git-for-each-ref.txt
> @@ -214,10 +214,11 @@ blank line.  The optional GPG signature is 
> `contents:signature`.  The
>  first `N` lines of the message is obtained using `contents:lines=N`.
>  Additionally, the trailers as interpreted by 
> linkgit:git-interpret-trailers[1]
>  are obtained as 'contents:trailers'. Non-trailer lines from the trailer block
> -can be omitted with 'trailers:only'. Whitespace-continuations can be removed
> -from trailers so that each trailer appears on a line by itself with its full
> -content with 'trailers:unfold'. Both can be used together as
> -'trailers:unfold,only'.
> +can be omitted with 'trailers:only', or 'contents:trailers:only'.
> +Whitespace-continuations can be removed from trailers so that each trailer
> +appears on a line by itself with its full content with 'trailers:unfold' or
> +'contents:trailers:unfold'. Both can be used together as 
> 'trailers:unfold,only',
> +or 'contents:trailers:unfold,only'.

Rather than enumerate each, we might do better to just say explicitly
"contents:trailers" and "trailers" are aliases of one another. It looks
like we don't even document %(trailers) at all here. I'd actually be in
favor of just declaring %(trailers) the official spelling, and calling
"%(contents:trailers)" a historical alias.

> diff --git a/ref-filter.c b/ref-filter.c
> index 8573acbed..a8d4a52bd 100644
> --- a/ref-filter.c
> +++ b/ref-filter.c
> @@ -207,8 +207,10 @@ static void contents_atom_parser(struct used_atom *atom, 
> const char *arg)
>               atom->u.contents.option = C_SIG;
>       else if (!strcmp(arg, "subject"))
>               atom->u.contents.option = C_SUB;
> -     else if (!strcmp(arg, "trailers"))
> -             atom->u.contents.option = C_TRAILERS;
> +     else if (skip_prefix(arg, "trailers", &arg)) {
> +             skip_prefix(arg, ":", &arg);
> +             trailers_atom_parser(atom, strlen(arg) ? arg : NULL);
> +     }

We usually spell "is this an empty string?" as "*arg" rather than
calling strlen().

However, I'm not sure we need to check. As I said above, I think
trailers_atom_parser() does the sensible thing with an empty string.

And if we _did_ want to distinguish between

  %(contents:trailers:)

and

  %(contents:trailers)

then I don't think this quite does it. It passes NULL for both cases. So
if we really want to emulate how parse_ref_filter_atom calls it, we'd
want:

  if (!skip_prefix(arg, ":", &arg))
        arg = NULL;
  trailers_atom_parser(atom, arg);

> diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh
> index 2bd0c5da7..d9b71589f 100755
> --- a/t/t6300-for-each-ref.sh
> +++ b/t/t6300-for-each-ref.sh
> @@ -642,6 +642,35 @@ test_expect_success '%(trailers:only) and 
> %(trailers:unfold) work together' '
>       test_cmp expect actual
>  '
>  
> +test_expect_success '%(contents:trailers:unfold) unfolds trailers' '
> +  git for-each-ref --format="%(contents:trailers:unfold)" refs/heads/master 
> >actual &&
> +  {

This has the same spaces/tabs thing going on as the previous commit.

-Peff

Reply via email to