From: Jeff King <peff@peff.net>
To: Karthik Nayak <karthik.188@gmail.com>
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: Thu, 14 Apr 2016 16:36:15 -0400 [thread overview]
Message-ID: <20160414203615.GA31504@sigill.intra.peff.net> (raw)
In-Reply-To: <20160414200530.GA26513@sigill.intra.peff.net>
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 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.
---
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(¶ms, 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;
}
/*
next prev parent reply other threads:[~2016-04-14 20:36 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 [this message]
2016-04-15 20:27 ` Karthik Nayak
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=20160414203615.GA31504@sigill.intra.peff.net \
--to=peff@peff.net \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=karthik.188@gmail.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).