Skip to content

Commit a798410

Browse files
KarthikNayakgitster
authored andcommitted
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>
1 parent b180e6f commit a798410

3 files changed

Lines changed: 54 additions & 33 deletions

File tree

Documentation/git-for-each-ref.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,11 @@ if::
170170
the value between the %(if:...) and %(then) atoms with the
171171
given string.
172172

173+
symref::
174+
The ref which the given symbolic ref refers to. If not a
175+
symbolic ref, nothing is printed. Respects the `:short` and
176+
`:strip` options in the same way as `refname` above.
177+
173178
In addition to the above, for commit and tag objects, the header
174179
field names (`tree`, `parent`, `object`, `type`, and `tag`) can
175180
be used to specify the value in the header field.

ref-filter.c

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,11 @@ static void objectname_atom_parser(struct used_atom *atom, const char *arg)
187187
die(_("unrecognized %%(objectname) argument: %s"), arg);
188188
}
189189

190+
static void refname_atom_parser(struct used_atom *atom, const char *arg)
191+
{
192+
return refname_atom_parser_internal(&atom->u.refname, arg, atom->name);
193+
}
194+
190195
static align_type parse_align_position(const char *s)
191196
{
192197
if (!strcmp(s, "right"))
@@ -257,7 +262,7 @@ static struct {
257262
cmp_type cmp_type;
258263
void (*parser)(struct used_atom *atom, const char *arg);
259264
} valid_atom[] = {
260-
{ "refname" },
265+
{ "refname" , FIELD_STR, refname_atom_parser },
261266
{ "objecttype" },
262267
{ "objectsize", FIELD_ULONG },
263268
{ "objectname", FIELD_STR, objectname_atom_parser },
@@ -287,7 +292,7 @@ static struct {
287292
{ "contents", FIELD_STR, contents_atom_parser },
288293
{ "upstream", FIELD_STR, remote_ref_atom_parser },
289294
{ "push", FIELD_STR, remote_ref_atom_parser },
290-
{ "symref" },
295+
{ "symref", FIELD_STR, refname_atom_parser },
291296
{ "flag" },
292297
{ "HEAD" },
293298
{ "color", FIELD_STR, color_atom_parser },
@@ -1082,21 +1087,16 @@ static inline char *copy_advance(char *dst, const char *src)
10821087
return dst;
10831088
}
10841089

1085-
static const char *strip_ref_components(const char *refname, const char *nr_arg)
1090+
static const char *strip_ref_components(const char *refname, unsigned int len)
10861091
{
1087-
char *end;
1088-
long nr = strtol(nr_arg, &end, 10);
1089-
long remaining = nr;
1092+
long remaining = len;
10901093
const char *start = refname;
10911094

1092-
if (nr < 1 || *end != '\0')
1093-
die(_(":strip= requires a positive integer argument"));
1094-
10951095
while (remaining) {
10961096
switch (*start++) {
10971097
case '\0':
1098-
die(_("ref '%s' does not have %ld components to :strip"),
1099-
refname, nr);
1098+
die(_("ref '%s' does not have %ud components to :strip"),
1099+
refname, len);
11001100
case '/':
11011101
remaining--;
11021102
break;
@@ -1105,6 +1105,16 @@ static const char *strip_ref_components(const char *refname, const char *nr_arg)
11051105
return start;
11061106
}
11071107

1108+
static const char *show_ref(struct refname_atom *atom, const char *refname)
1109+
{
1110+
if (atom->option == R_SHORT)
1111+
return shorten_unambiguous_ref(refname, warn_ambiguous_refs);
1112+
else if (atom->option == R_STRIP)
1113+
return strip_ref_components(refname, atom->strip);
1114+
else
1115+
return refname;
1116+
}
1117+
11081118
static void fill_remote_ref_details(struct used_atom *atom, const char *refname,
11091119
struct branch *branch, const char **s)
11101120
{
@@ -1177,6 +1187,21 @@ char *get_head_description(void)
11771187
return strbuf_detach(&desc, NULL);
11781188
}
11791189

1190+
static const char *get_symref(struct used_atom *atom, struct ref_array_item *ref)
1191+
{
1192+
if (!ref->symref)
1193+
return "";
1194+
else
1195+
return show_ref(&atom->u.refname, ref->symref);
1196+
}
1197+
1198+
static const char *get_refname(struct used_atom *atom, struct ref_array_item *ref)
1199+
{
1200+
if (ref->kind & FILTER_REFS_DETACHED_HEAD)
1201+
return get_head_description();
1202+
return show_ref(&atom->u.refname, ref->refname);
1203+
}
1204+
11801205
/*
11811206
* Parse the object referred by ref, and grab needed value.
11821207
*/
@@ -1205,7 +1230,6 @@ static void populate_value(struct ref_array_item *ref)
12051230
struct atom_value *v = &ref->value[i];
12061231
int deref = 0;
12071232
const char *refname;
1208-
const char *formatp;
12091233
struct branch *branch = NULL;
12101234

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

1219-
if (starts_with(name, "refname")) {
1220-
refname = ref->refname;
1221-
if (ref->kind & FILTER_REFS_DETACHED_HEAD)
1222-
refname = get_head_description();
1223-
} else if (starts_with(name, "symref"))
1224-
refname = ref->symref ? ref->symref : "";
1243+
if (starts_with(name, "refname"))
1244+
refname = get_refname(atom, ref);
1245+
else if (starts_with(name, "symref"))
1246+
refname = get_symref(atom, ref);
12251247
else if (starts_with(name, "upstream")) {
12261248
const char *branch_name;
12271249
/* only local branches may have an upstream */
@@ -1297,21 +1319,6 @@ static void populate_value(struct ref_array_item *ref)
12971319
} else
12981320
continue;
12991321

1300-
formatp = strchr(name, ':');
1301-
if (formatp) {
1302-
const char *arg;
1303-
1304-
formatp++;
1305-
if (!strcmp(formatp, "short"))
1306-
refname = shorten_unambiguous_ref(refname,
1307-
warn_ambiguous_refs);
1308-
else if (skip_prefix(formatp, "strip=", &arg))
1309-
refname = strip_ref_components(refname, arg);
1310-
else
1311-
die(_("unknown %.*s format %s"),
1312-
(int)(formatp - name), name, formatp);
1313-
}
1314-
13151322
if (!deref)
13161323
v->s = refname;
13171324
else

t/t6300-for-each-ref.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -624,4 +624,13 @@ test_expect_success 'Verify usage of %(symref:short) atom' '
624624
test_cmp expected actual
625625
'
626626

627+
cat >expected <<EOF
628+
master
629+
EOF
630+
631+
test_expect_success 'Verify usage of %(symref:strip) atom' '
632+
git for-each-ref --format="%(symref:strip=2)" refs/heads/sym > actual &&
633+
test_cmp expected actual
634+
'
635+
627636
test_done

0 commit comments

Comments
 (0)