All of lore.kernel.org
 help / color / mirror / Atom feed
From: Karthik Nayak <karthik.188@gmail.com>
To: Jeff King <peff@peff.net>
Cc: Junio C Hamano <gitster@pobox.com>, Git <git@vger.kernel.org>
Subject: Re: [PATCH v4 15/16] branch: use ref-filter printing APIs
Date: Sat, 16 Apr 2016 01:57:23 +0530	[thread overview]
Message-ID: <CAOLa=ZSdnDFR52BJB1dm-D=gyUo=oB0aoh5pKAvwyNG5+u0P_A@mail.gmail.com> (raw)
In-Reply-To: <20160414203615.GA31504@sigill.intra.peff.net>

On Fri, Apr 15, 2016 at 2:06 AM, Jeff King <peff@peff.net> wrote:
> On Thu, Apr 14, 2016 at 04:05:30PM -0400, Jeff King wrote:
>
>> It looks like that's a little tricky for %(upstream) and %(push), which
>> have extra tracking options, but it's pretty trivial for %(symref):
>> [...]
>> I suspect it could work for the remote_ref_atom_parser, too, if you did
>> something like:
>
> So here that is (handling both %(symref) and %(upstream), so replacing
> what I sent a few minutes ago). It's only lightly tested by me, so there
> may be more corner cases to think about. I kept things where they were
> to create a minimal diff, but if it gets squashed in, it might be worth
> re-ordering a little to avoid the need for forward declarations.
>

I had a look at your patch and even tested it, seems solid, I like how you
integrated all these atoms together under refname_atom_parser_internal().
I'm squashing this in, for my re-roll. Thanks.

>> I don't know if that would create weird corner cases with RR_SHORTEN
>> and RR_TRACK, though, which are currently in the same enum (and thus
>> cannot be used at the same time). But it's not like we parse
>> "%(upstream:short:track)" anyway, I don't think. For each "%()"
>> placeholder you have to choose one or the other: showing the tracking
>> info, or showing the refname (possibly with modifiers). So ":track"
>> isn't so much a modifier as "upstream:track" is this totally other
>> thing.
>
> So actually, we _do_ accept "%(upstream:short,track)" with your patch,
> which is somewhat nonsensical. It just ignores "short" and takes
> whatever option came last. Which is reasonable, though flagging an error
> would also be reasonable (and I think is what existing git does). I
> don't think it matters much either way.
>

I think it was decided a while ago that it'd be best to ignore all and
accept the
last argument without barfing, I couldn't find the exact link. But I'm
open to both.
But if you look at the %(align) atom, even that accepts mutually
exclusive arguments
and accepts the last argument without reporting an error.

> ---
> diff --git a/ref-filter.c b/ref-filter.c
> index 3435df1..951c57e 100644
> --- a/ref-filter.c
> +++ b/ref-filter.c
> @@ -50,6 +50,11 @@ struct if_then_else {
>                 condition_satisfied : 1;
>  };
>
> +struct refname_atom {
> +       enum { R_BASE, R_DIR, R_NORMAL, R_SHORT, R_STRIP } option;
> +       unsigned int strip;
> +};
> +
>  /*
>   * An atom is a valid field atom listed below, possibly prefixed with
>   * a "*" to denote deref_tag().
> @@ -67,7 +72,8 @@ static struct used_atom {
>                 char color[COLOR_MAXLEN];
>                 struct align align;
>                 struct {
> -                       enum { RR_NORMAL, RR_SHORTEN, RR_TRACK, RR_TRACKSHORT } option;
> +                       enum { RR_REF, RR_TRACK, RR_TRACKSHORT } option;
> +                       struct refname_atom refname;
>                         unsigned int nobracket: 1;
>                 } remote_ref;
>                 struct {
> @@ -82,16 +88,14 @@ static struct used_atom {
>                         enum { O_FULL, O_LENGTH, O_SHORT } option;
>                         unsigned int length;
>                 } objectname;
> -               enum { S_FULL, S_SHORT } symref;
> -               struct {
> -                       enum { R_BASE, R_DIR, R_NORMAL, R_SHORT, R_STRIP } option;
> -                       unsigned int strip;
> -               } refname;
> +               struct refname_atom refname;
>         } u;
>  } *used_atom;
>  static int used_atom_cnt, need_tagged, need_symref;
>  static int need_color_reset_at_eol;
>
> +static const char *show_ref(struct refname_atom *atom, const char *refname);
> +
>  static void color_atom_parser(struct used_atom *atom, const char *color_value)
>  {
>         if (!color_value)
> @@ -100,13 +104,34 @@ static void color_atom_parser(struct used_atom *atom, const char *color_value)
>                 die(_("unrecognized color: %%(color:%s)"), color_value);
>  }
>
> +static void refname_atom_parser_internal(struct refname_atom *atom,
> +                                        const char *arg, const char *name)
> +{
> +       if (!arg)
> +               atom->option = R_NORMAL;
> +       else if (!strcmp(arg, "short"))
> +               atom->option = R_SHORT;
> +       else if (skip_prefix(arg, "strip=", &arg)) {
> +               atom->option = R_STRIP;
> +               if (strtoul_ui(arg, 10, &atom->strip) || atom->strip <= 0)
> +                       die(_("positive value expected refname:strip=%s"), arg);
> +       } else if (!strcmp(arg, "dir"))
> +               atom->option = R_DIR;
> +       else if (!strcmp(arg, "base"))
> +               atom->option = R_BASE;
> +       else
> +               die(_("unrecognized %%(%s) argument: %s"), name, arg);
> +}
> +
>  static void remote_ref_atom_parser(struct used_atom *atom, const char *arg)
>  {
>         struct string_list params = STRING_LIST_INIT_DUP;
>         int i;
>
>         if (!arg) {
> -               atom->u.remote_ref.option = RR_NORMAL;
> +               atom->u.remote_ref.option = RR_REF;
> +               refname_atom_parser_internal(&atom->u.remote_ref.refname,
> +                                            arg, atom->name);
>                 return;
>         }
>
> @@ -116,16 +141,17 @@ static void remote_ref_atom_parser(struct used_atom *atom, const char *arg)
>         for (i = 0; i < params.nr; i++) {
>                 const char *s = params.items[i].string;
>
> -               if (!strcmp(s, "short"))
> -                       atom->u.remote_ref.option = RR_SHORTEN;
> -               else if (!strcmp(s, "track"))
> +               if (!strcmp(s, "track"))
>                         atom->u.remote_ref.option = RR_TRACK;
>                 else if (!strcmp(s, "trackshort"))
>                         atom->u.remote_ref.option = RR_TRACKSHORT;
>                 else if (!strcmp(s, "nobracket"))
>                         atom->u.remote_ref.nobracket = 1;
> -               else
> -                       die(_("unrecognized format: %%(%s)"), atom->name);
> +               else {
> +                       atom->u.remote_ref.option = RR_REF;
> +                       refname_atom_parser_internal(&atom->u.remote_ref.refname,
> +                                                    s, atom->name);
> +               }
>         }
>
>         string_list_clear(&params, 0);
> @@ -244,31 +270,12 @@ static void if_atom_parser(struct used_atom *atom, const char *arg)
>
>  static void symref_atom_parser(struct used_atom *atom, const char *arg)
>  {
> -       if (!arg)
> -               atom->u.symref = S_FULL;
> -       else if (!strcmp(arg, "short"))
> -               atom->u.symref = S_SHORT;
> -       else
> -               die(_("unrecognized %%(symref) argument: %s"), arg);
> +       return refname_atom_parser_internal(&atom->u.refname, arg, atom->name);
>  }
>
>  static void refname_atom_parser(struct used_atom *atom, const char *arg)
>  {
> -       if (!arg)
> -               atom->u.refname.option = R_NORMAL;
> -       else if (!strcmp(arg, "short"))
> -               atom->u.refname.option = R_SHORT;
> -       else if (skip_prefix(arg, "strip=", &arg)) {
> -               atom->u.contents.option = R_STRIP;
> -               if (strtoul_ui(arg, 10, &atom->u.refname.strip) ||
> -                       atom->u.refname.strip <= 0)
> -                       die(_("positive value expected refname:strip=%s"), arg);
> -       } else if (!strcmp(arg, "dir"))
> -               atom->u.contents.option = R_DIR;
> -       else if (!strcmp(arg, "base"))
> -               atom->u.contents.option = R_BASE;
> -       else
> -               die(_("unrecognized %%(refname) argument: %s"), arg);
> +       return refname_atom_parser_internal(&atom->u.refname, arg, atom->name);
>  }
>
>  static struct {
> @@ -1112,8 +1119,8 @@ static void fill_remote_ref_details(struct used_atom *atom, const char *refname,
>                                     struct branch *branch, const char **s)
>  {
>         int num_ours, num_theirs;
> -       if (atom->u.remote_ref.option == RR_SHORTEN)
> -               *s = shorten_unambiguous_ref(refname, warn_ambiguous_refs);
> +       if (atom->u.remote_ref.option == RR_REF)
> +               *s = show_ref(&atom->u.remote_ref.refname, refname);
>         else if (atom->u.remote_ref.option == RR_TRACK) {
>                 if (stat_tracking_info(branch, &num_ours,
>                                        &num_theirs, NULL)) {
> @@ -1145,8 +1152,8 @@ static void fill_remote_ref_details(struct used_atom *atom, const char *refname,
>                         *s = ">";
>                 else
>                         *s = "<>";
> -       } else /* RR_NORMAL */
> -               *s = refname;
> +       } else
> +               die("BUG: unhandled RR_* enum");
>  }
>
>  char *get_head_description(void)
> @@ -1184,41 +1191,43 @@ static const char *get_symref(struct used_atom *atom, struct ref_array_item *ref
>  {
>         if (!ref->symref)
>                 return "";
> -       else if (atom->u.symref == S_SHORT)
> -               return shorten_unambiguous_ref(ref->symref,
> -                                              warn_ambiguous_refs);
>         else
> -               return ref->symref;
> +               return show_ref(&atom->u.refname, ref->symref);
>  }
>
>  static const char *get_refname(struct used_atom *atom, struct ref_array_item *ref)
>  {
>         if (ref->kind & FILTER_REFS_DETACHED_HEAD)
>                 return get_head_description();
> -       if (atom->u.refname.option == R_SHORT)
> -               return shorten_unambiguous_ref(ref->refname, warn_ambiguous_refs);
> -       else if (atom->u.refname.option == R_STRIP)
> -               return strip_ref_components(ref->refname, atom->u.refname.strip);
> -       else if (atom->u.refname.option == R_BASE) {
> +       return show_ref(&atom->u.refname, ref->refname);
> +}
> +
> +static const char *show_ref(struct refname_atom *atom, const char *refname)
> +{
> +       if (atom->option == R_SHORT)
> +               return shorten_unambiguous_ref(refname, warn_ambiguous_refs);
> +       else if (atom->option == R_STRIP)
> +               return strip_ref_components(refname, atom->strip);
> +       else if (atom->option == R_BASE) {
>                 const char *sp, *ep;
>
> -               if (skip_prefix(ref->refname, "refs/", &sp)) {
> +               if (skip_prefix(refname, "refs/", &sp)) {
>                         ep = strchr(sp, '/');
>                         if (!ep)
>                                 return "";
>                         return xstrndup(sp, ep - sp);
>                 }
>                 return "";
> -       } else if (atom->u.refname.option == R_DIR) {
> +       } else if (atom->option == R_DIR) {
>                 const char *sp, *ep;
>
> -               sp = ref->refname;
> +               sp = refname;
>                 ep = strrchr(sp, '/');
>                 if (!ep)
>                         return "";
>                 return xstrndup(sp, ep - sp);
>         } else
> -               return ref->refname;
> +               return refname;
>  }
>
>  /*



-- 
Regards,
Karthik Nayak

  reply	other threads:[~2016-04-15 20:28 UTC|newest]

Thread overview: 31+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-04-09 18:44 [PATCH v4 00/16] port branch.c to use ref-filter's printing options Karthik Nayak
2016-04-09 18:45 ` [PATCH v4 01/16] ref-filter: implement %(if), %(then), and %(else) atoms Karthik Nayak
2016-04-09 18:45 ` [PATCH v4 02/16] ref-filter: include reference to 'used_atom' within 'atom_value' Karthik Nayak
2016-04-09 18:45 ` [PATCH v4 03/16] ref-filter: implement %(if:equals=<string>) and %(if:notequals=<string>) Karthik Nayak
2016-04-09 18:45 ` [PATCH v4 04/16] ref-filter: modify "%(objectname:short)" to take length Karthik Nayak
2016-04-09 18:45 ` [PATCH v4 05/16] ref-filter: move get_head_description() from branch.c Karthik Nayak
2016-04-09 18:45 ` [PATCH v4 06/16] ref-filter: introduce format_ref_array_item() Karthik Nayak
2016-04-09 18:45 ` [PATCH v4 07/16] ref-filter: make %(upstream:track) prints "[gone]" for invalid upstreams Karthik Nayak
2016-04-09 18:45 ` [PATCH v4 08/16] ref-filter: add support for %(upstream:track,nobracket) Karthik Nayak
2016-04-09 18:45 ` [PATCH v4 09/16] ref-filter: make "%(symref)" atom work with the ':short' modifier Karthik Nayak
2016-04-09 18:45 ` [PATCH v4 10/16] ref-filter: introduce symref_atom_parser() Karthik Nayak
2016-04-09 18:45 ` [PATCH v4 11/16] ref-filter: introduce refname_atom_parser() Karthik Nayak
2016-04-14 20:43   ` Jeff King
2016-04-15 19:02     ` Karthik Nayak
2016-04-09 18:45 ` [PATCH v4 12/16] ref-filter: add support for %(refname:dir) and %(refname:base) Karthik Nayak
2016-04-09 18:45 ` [PATCH v4 13/16] ref-filter: allow porcelain to translate messages in the output Karthik Nayak
2016-04-09 18:45 ` [PATCH v4 14/16] branch, tag: use porcelain output Karthik Nayak
2016-04-09 18:45 ` [PATCH v4 15/16] branch: use ref-filter printing APIs Karthik Nayak
2016-04-12 20:40   ` Junio C Hamano
2016-04-12 21:05     ` Junio C Hamano
2016-04-13 10:49       ` Karthik Nayak
     [not found]         ` <CAPc5daUZvP03o+eb2ngvRtV=aoXWGnZH9FKj9bRCEj3MrCT8WQ@mail.gmail.com>
2016-04-13 19:01           ` Karthik Nayak
2016-04-13 22:05             ` Jeff King
2016-04-14 19:17               ` Karthik Nayak
2016-04-14 20:05                 ` Jeff King
2016-04-14 20:36                   ` Jeff King
2016-04-15 20:27                     ` Karthik Nayak [this message]
2016-04-15 21:09                       ` Jeff King
2016-04-16  0:11   ` Stefan Beller
2016-04-17 20:30     ` Karthik Nayak
2016-04-09 18:45 ` [PATCH v4 16/16] branch: implement '--format' option Karthik Nayak

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CAOLa=ZSdnDFR52BJB1dm-D=gyUo=oB0aoh5pKAvwyNG5+u0P_A@mail.gmail.com' \
    --to=karthik.188@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=peff@peff.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.