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>
Karthik Nayak committed
Jan 10, 2017 at 14:19 UTC
a7984101846ccfb8837526a8d79dda5b8c461d84
3 files changed
+54
-33
Documentation/git-for-each-ref.txt
+5
@@ -170,6 +170,11 @@ if::
170
the value between the %(if:...) and %(then) atoms with the
171
given string.
172
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
+
178
In addition to the above, for commit and tag objects, the header
179
field names (`tree`, `parent`, `object`, `type`, and `tag`) can
180
be used to specify the value in the header field.
ref-filter.c
+40
-33
@@ -187,6 +187,11 @@ static void objectname_atom_parser(struct used_atom *atom, const char *arg)
187
die(_("unrecognized %%(objectname) argument: %s"), arg);
188
}
189
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
+
195
static align_type parse_align_position(const char *s)
196
{
197
if (!strcmp(s, "right"))
@@ -257,7 +262,7 @@ static struct {
262
cmp_type cmp_type;
263
void (*parser)(struct used_atom *atom, const char *arg);
264
} valid_atom[] = {
260
- { "refname" },
265
+ { "refname" , FIELD_STR, refname_atom_parser },
266
{ "objecttype" },
267
{ "objectsize", FIELD_ULONG },
268
{ "objectname", FIELD_STR, objectname_atom_parser },
@@ -287,7 +292,7 @@ static struct {
292
{ "contents", FIELD_STR, contents_atom_parser },
293
{ "upstream", FIELD_STR, remote_ref_atom_parser },
294
{ "push", FIELD_STR, remote_ref_atom_parser },
290
- { "symref" },
295
+ { "symref", FIELD_STR, refname_atom_parser },
296
{ "flag" },
297
{ "HEAD" },
298
{ "color", FIELD_STR, color_atom_parser },
@@ -1082,21 +1087,16 @@ static inline char *copy_advance(char *dst, const char *src)
1087
return dst;
1088
}
1089
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)
1091
{
1087
- char *end;
1088
- long nr = strtol(nr_arg, &end, 10);
1089
- long remaining = nr;
1092
+ long remaining = len;
1093
const char *start = refname;
1094
1092
- if (nr < 1 || *end != '\0')
1093
- die(_(":strip= requires a positive integer argument"));
1094
-
1095
while (remaining) {
1096
switch (*start++) {
1097
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);
1100
case '/':
1101
remaining--;
1102
break;
@@ -1105,6 +1105,16 @@ static const char *strip_ref_components(const char *refname, const char *nr_arg)
1105
return start;
1106
}
1107
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
+
1118
static void fill_remote_ref_details(struct used_atom *atom, const char *refname,
1119
struct branch *branch, const char **s)
1120
{
@@ -1177,6 +1187,21 @@ char *get_head_description(void)
1187
return strbuf_detach(&desc, NULL);
1188
}
1189
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
+
1205
/*
1206
* Parse the object referred by ref, and grab needed value.
1207
*/
@@ -1205,7 +1230,6 @@ static void populate_value(struct ref_array_item *ref)
1230
struct atom_value *v = &ref->value[i];
1231
int deref = 0;
1232
const char *refname;
1208
- const char *formatp;
1233
struct branch *branch = NULL;
1234
1235
v->handler = append_atom;
@@ -1216,12 +1240,10 @@ static void populate_value(struct ref_array_item *ref)
1240
name++;
1241
}
1242
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);
1247
else if (starts_with(name, "upstream")) {
1248
const char *branch_name;
1249
/* only local branches may have an upstream */
@@ -1297,21 +1319,6 @@ static void populate_value(struct ref_array_item *ref)
1319
} else
1320
continue;
1321
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
-
1322
if (!deref)
1323
v->s = refname;
1324
else
t/t6300-for-each-ref.sh
+9
@@ -624,4 +624,13 @@ test_expect_success 'Verify usage of %(symref:short) atom' '
624
test_cmp expected actual
625
'
626
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
+
636
test_done