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>
This commit is contained in:

committed by
Junio C Hamano

parent
b180e6fe19
commit
a798410184
@ -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
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
|
||||||
|
@ -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
|
||||||
|
Reference in New Issue
Block a user