Browse Source

ref-filter: introduce refname_atom_parser()

Using refname_atom_parser_internal(), introduce refname_atom_parser()
which will parse the %(symref) and %(refname) atoms. Store the parsed
information into the 'used_atom' structure based on the modifiers used
along with the atoms.

Now the '%(symref)' atom supports the ':strip' atom modifier. Update the
Documentation and tests to reflect this.

Helped-by: Jeff King <peff@peff.net>
Signed-off-by: Karthik Nayak <Karthik.188@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
maint
Karthik Nayak 8 years ago committed by Junio C Hamano
parent
commit
a798410184
  1. 5
      Documentation/git-for-each-ref.txt
  2. 73
      ref-filter.c
  3. 9
      t/t6300-for-each-ref.sh

5
Documentation/git-for-each-ref.txt

@ -170,6 +170,11 @@ if::
the value between the %(if:...) and %(then) atoms with the the value between the %(if:...) and %(then) atoms with the
given string. given string.


symref::
The ref which the given symbolic ref refers to. If not a
symbolic ref, nothing is printed. Respects the `:short` and
`:strip` options in the same way as `refname` above.

In addition to the above, for commit and tag objects, the header In addition to the above, for commit and tag objects, the header
field names (`tree`, `parent`, `object`, `type`, and `tag`) can field names (`tree`, `parent`, `object`, `type`, and `tag`) can
be used to specify the value in the header field. be used to specify the value in the header field.

73
ref-filter.c

@ -187,6 +187,11 @@ static void objectname_atom_parser(struct used_atom *atom, const char *arg)
die(_("unrecognized %%(objectname) argument: %s"), arg); die(_("unrecognized %%(objectname) argument: %s"), arg);
} }


static void refname_atom_parser(struct used_atom *atom, const char *arg)
{
return refname_atom_parser_internal(&atom->u.refname, arg, atom->name);
}

static align_type parse_align_position(const char *s) static align_type parse_align_position(const char *s)
{ {
if (!strcmp(s, "right")) if (!strcmp(s, "right"))
@ -257,7 +262,7 @@ static struct {
cmp_type cmp_type; cmp_type cmp_type;
void (*parser)(struct used_atom *atom, const char *arg); void (*parser)(struct used_atom *atom, const char *arg);
} valid_atom[] = { } valid_atom[] = {
{ "refname" }, { "refname" , FIELD_STR, refname_atom_parser },
{ "objecttype" }, { "objecttype" },
{ "objectsize", FIELD_ULONG }, { "objectsize", FIELD_ULONG },
{ "objectname", FIELD_STR, objectname_atom_parser }, { "objectname", FIELD_STR, objectname_atom_parser },
@ -287,7 +292,7 @@ static struct {
{ "contents", FIELD_STR, contents_atom_parser }, { "contents", FIELD_STR, contents_atom_parser },
{ "upstream", FIELD_STR, remote_ref_atom_parser }, { "upstream", FIELD_STR, remote_ref_atom_parser },
{ "push", FIELD_STR, remote_ref_atom_parser }, { "push", FIELD_STR, remote_ref_atom_parser },
{ "symref" }, { "symref", FIELD_STR, refname_atom_parser },
{ "flag" }, { "flag" },
{ "HEAD" }, { "HEAD" },
{ "color", FIELD_STR, color_atom_parser }, { "color", FIELD_STR, color_atom_parser },
@ -1082,21 +1087,16 @@ static inline char *copy_advance(char *dst, const char *src)
return dst; return dst;
} }


static const char *strip_ref_components(const char *refname, const char *nr_arg) static const char *strip_ref_components(const char *refname, unsigned int len)
{ {
char *end; long remaining = len;
long nr = strtol(nr_arg, &end, 10);
long remaining = nr;
const char *start = refname; const char *start = refname;


if (nr < 1 || *end != '\0')
die(_(":strip= requires a positive integer argument"));

while (remaining) { while (remaining) {
switch (*start++) { switch (*start++) {
case '\0': case '\0':
die(_("ref '%s' does not have %ld components to :strip"), die(_("ref '%s' does not have %ud components to :strip"),
refname, nr); refname, len);
case '/': case '/':
remaining--; remaining--;
break; break;
@ -1105,6 +1105,16 @@ static const char *strip_ref_components(const char *refname, const char *nr_arg)
return start; return start;
} }


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
return refname;
}

static void fill_remote_ref_details(struct used_atom *atom, const char *refname, static void fill_remote_ref_details(struct used_atom *atom, const char *refname,
struct branch *branch, const char **s) struct branch *branch, const char **s)
{ {
@ -1177,6 +1187,21 @@ char *get_head_description(void)
return strbuf_detach(&desc, NULL); return strbuf_detach(&desc, NULL);
} }


static const char *get_symref(struct used_atom *atom, struct ref_array_item *ref)
{
if (!ref->symref)
return "";
else
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();
return show_ref(&atom->u.refname, ref->refname);
}

/* /*
* Parse the object referred by ref, and grab needed value. * Parse the object referred by ref, and grab needed value.
*/ */
@ -1205,7 +1230,6 @@ static void populate_value(struct ref_array_item *ref)
struct atom_value *v = &ref->value[i]; struct atom_value *v = &ref->value[i];
int deref = 0; int deref = 0;
const char *refname; const char *refname;
const char *formatp;
struct branch *branch = NULL; struct branch *branch = NULL;


v->handler = append_atom; v->handler = append_atom;
@ -1216,12 +1240,10 @@ static void populate_value(struct ref_array_item *ref)
name++; name++;
} }


if (starts_with(name, "refname")) { if (starts_with(name, "refname"))
refname = ref->refname; refname = get_refname(atom, ref);
if (ref->kind & FILTER_REFS_DETACHED_HEAD) else if (starts_with(name, "symref"))
refname = get_head_description(); refname = get_symref(atom, ref);
} else if (starts_with(name, "symref"))
refname = ref->symref ? ref->symref : "";
else if (starts_with(name, "upstream")) { else if (starts_with(name, "upstream")) {
const char *branch_name; const char *branch_name;
/* only local branches may have an upstream */ /* only local branches may have an upstream */
@ -1297,21 +1319,6 @@ static void populate_value(struct ref_array_item *ref)
} else } else
continue; continue;


formatp = strchr(name, ':');
if (formatp) {
const char *arg;

formatp++;
if (!strcmp(formatp, "short"))
refname = shorten_unambiguous_ref(refname,
warn_ambiguous_refs);
else if (skip_prefix(formatp, "strip=", &arg))
refname = strip_ref_components(refname, arg);
else
die(_("unknown %.*s format %s"),
(int)(formatp - name), name, formatp);
}

if (!deref) if (!deref)
v->s = refname; v->s = refname;
else else

9
t/t6300-for-each-ref.sh

@ -624,4 +624,13 @@ test_expect_success 'Verify usage of %(symref:short) atom' '
test_cmp expected actual test_cmp expected actual
' '


cat >expected <<EOF
master
EOF

test_expect_success 'Verify usage of %(symref:strip) atom' '
git for-each-ref --format="%(symref:strip=2)" refs/heads/sym > actual &&
test_cmp expected actual
'

test_done test_done

Loading…
Cancel
Save