Skip to content

Commit 2871423

Browse files
committed
Merge branch 'hv/trailer-formatting'
The logic to handle "trailer" related placeholders in the "--format=" mechanisms in the "log" family and "for-each-ref" family is getting unified. * hv/trailer-formatting: ref-filter: use pretty.c logic for trailers pretty.c: capture invalid trailer argument pretty.c: refactor trailer logic to `format_set_trailers_options()` t6300: use function to test trailer options
2 parents 18aabfa + ee82a48 commit 2871423

File tree

5 files changed

+236
-103
lines changed

5 files changed

+236
-103
lines changed

Documentation/git-for-each-ref.txt

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -260,11 +260,9 @@ contents:lines=N::
260260
The first `N` lines of the message.
261261

262262
Additionally, the trailers as interpreted by linkgit:git-interpret-trailers[1]
263-
are obtained as `trailers` (or by using the historical alias
264-
`contents:trailers`). Non-trailer lines from the trailer block can be omitted
265-
with `trailers:only`. Whitespace-continuations can be removed from trailers so
266-
that each trailer appears on a line by itself with its full content with
267-
`trailers:unfold`. Both can be used together as `trailers:unfold,only`.
263+
are obtained as `trailers[:options]` (or by using the historical alias
264+
`contents:trailers[:options]`). For valid [:option] values see `trailers`
265+
section of linkgit:git-log[1].
268266

269267
For sorting purposes, fields with numeric values sort in numeric order
270268
(`objectsize`, `authordate`, `committerdate`, `creatordate`, `taggerdate`).

pretty.c

Lines changed: 59 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1149,6 +1149,63 @@ static int format_trailer_match_cb(const struct strbuf *key, void *ud)
11491149
return 0;
11501150
}
11511151

1152+
int format_set_trailers_options(struct process_trailer_options *opts,
1153+
struct string_list *filter_list,
1154+
struct strbuf *sepbuf,
1155+
struct strbuf *kvsepbuf,
1156+
const char **arg,
1157+
char **invalid_arg)
1158+
{
1159+
for (;;) {
1160+
const char *argval;
1161+
size_t arglen;
1162+
1163+
if (**arg == ')')
1164+
break;
1165+
1166+
if (match_placeholder_arg_value(*arg, "key", arg, &argval, &arglen)) {
1167+
uintptr_t len = arglen;
1168+
1169+
if (!argval)
1170+
return -1;
1171+
1172+
if (len && argval[len - 1] == ':')
1173+
len--;
1174+
string_list_append(filter_list, argval)->util = (char *)len;
1175+
1176+
opts->filter = format_trailer_match_cb;
1177+
opts->filter_data = filter_list;
1178+
opts->only_trailers = 1;
1179+
} else if (match_placeholder_arg_value(*arg, "separator", arg, &argval, &arglen)) {
1180+
char *fmt;
1181+
1182+
strbuf_reset(sepbuf);
1183+
fmt = xstrndup(argval, arglen);
1184+
strbuf_expand(sepbuf, fmt, strbuf_expand_literal_cb, NULL);
1185+
free(fmt);
1186+
opts->separator = sepbuf;
1187+
} else if (match_placeholder_arg_value(*arg, "key_value_separator", arg, &argval, &arglen)) {
1188+
char *fmt;
1189+
1190+
strbuf_reset(kvsepbuf);
1191+
fmt = xstrndup(argval, arglen);
1192+
strbuf_expand(kvsepbuf, fmt, strbuf_expand_literal_cb, NULL);
1193+
free(fmt);
1194+
opts->key_value_separator = kvsepbuf;
1195+
} else if (!match_placeholder_bool_arg(*arg, "only", arg, &opts->only_trailers) &&
1196+
!match_placeholder_bool_arg(*arg, "unfold", arg, &opts->unfold) &&
1197+
!match_placeholder_bool_arg(*arg, "keyonly", arg, &opts->key_only) &&
1198+
!match_placeholder_bool_arg(*arg, "valueonly", arg, &opts->value_only)) {
1199+
if (invalid_arg) {
1200+
size_t len = strcspn(*arg, ",)");
1201+
*invalid_arg = xstrndup(*arg, len);
1202+
}
1203+
return -1;
1204+
}
1205+
}
1206+
return 0;
1207+
}
1208+
11521209
static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
11531210
const char *placeholder,
11541211
void *context)
@@ -1429,45 +1486,8 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
14291486

14301487
if (*arg == ':') {
14311488
arg++;
1432-
for (;;) {
1433-
const char *argval;
1434-
size_t arglen;
1435-
1436-
if (match_placeholder_arg_value(arg, "key", &arg, &argval, &arglen)) {
1437-
uintptr_t len = arglen;
1438-
1439-
if (!argval)
1440-
goto trailer_out;
1441-
1442-
if (len && argval[len - 1] == ':')
1443-
len--;
1444-
string_list_append(&filter_list, argval)->util = (char *)len;
1445-
1446-
opts.filter = format_trailer_match_cb;
1447-
opts.filter_data = &filter_list;
1448-
opts.only_trailers = 1;
1449-
} else if (match_placeholder_arg_value(arg, "separator", &arg, &argval, &arglen)) {
1450-
char *fmt;
1451-
1452-
strbuf_reset(&sepbuf);
1453-
fmt = xstrndup(argval, arglen);
1454-
strbuf_expand(&sepbuf, fmt, strbuf_expand_literal_cb, NULL);
1455-
free(fmt);
1456-
opts.separator = &sepbuf;
1457-
} else if (match_placeholder_arg_value(arg, "key_value_separator", &arg, &argval, &arglen)) {
1458-
char *fmt;
1459-
1460-
strbuf_reset(&kvsepbuf);
1461-
fmt = xstrndup(argval, arglen);
1462-
strbuf_expand(&kvsepbuf, fmt, strbuf_expand_literal_cb, NULL);
1463-
free(fmt);
1464-
opts.key_value_separator = &kvsepbuf;
1465-
} else if (!match_placeholder_bool_arg(arg, "only", &arg, &opts.only_trailers) &&
1466-
!match_placeholder_bool_arg(arg, "unfold", &arg, &opts.unfold) &&
1467-
!match_placeholder_bool_arg(arg, "keyonly", &arg, &opts.key_only) &&
1468-
!match_placeholder_bool_arg(arg, "valueonly", &arg, &opts.value_only))
1469-
break;
1470-
}
1489+
if (format_set_trailers_options(&opts, &filter_list, &sepbuf, &kvsepbuf, &arg, NULL))
1490+
goto trailer_out;
14711491
}
14721492
if (*arg == ')') {
14731493
format_trailers_from_commit(sb, msg + c->subject_off, &opts);

pretty.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
struct commit;
88
struct strbuf;
9+
struct process_trailer_options;
910

1011
/* Commit formats */
1112
enum cmit_fmt {
@@ -142,4 +143,15 @@ int commit_format_is_empty(enum cmit_fmt);
142143
/* Make subject of commit message suitable for filename */
143144
void format_sanitized_subject(struct strbuf *sb, const char *msg, size_t len);
144145

146+
/*
147+
* Set values of fields in "struct process_trailer_options"
148+
* according to trailers arguments.
149+
*/
150+
int format_set_trailers_options(struct process_trailer_options *opts,
151+
struct string_list *filter_list,
152+
struct strbuf *sepbuf,
153+
struct strbuf *kvsepbuf,
154+
const char **arg,
155+
char **invalid_arg);
156+
145157
#endif /* PRETTY_H */

ref-filter.c

Lines changed: 20 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,12 @@ struct refname_atom {
6767
int lstrip, rstrip;
6868
};
6969

70+
static struct ref_trailer_buf {
71+
struct string_list filter_list;
72+
struct strbuf sepbuf;
73+
struct strbuf kvsepbuf;
74+
} ref_trailer_buf = {STRING_LIST_INIT_NODUP, STRBUF_INIT, STRBUF_INIT};
75+
7076
static struct expand_data {
7177
struct object_id oid;
7278
enum object_type type;
@@ -313,28 +319,26 @@ static int subject_atom_parser(const struct ref_format *format, struct used_atom
313319
static int trailers_atom_parser(const struct ref_format *format, struct used_atom *atom,
314320
const char *arg, struct strbuf *err)
315321
{
316-
struct string_list params = STRING_LIST_INIT_DUP;
317-
int i;
318-
319322
atom->u.contents.trailer_opts.no_divider = 1;
320323

321324
if (arg) {
322-
string_list_split(&params, arg, ',', -1);
323-
for (i = 0; i < params.nr; i++) {
324-
const char *s = params.items[i].string;
325-
if (!strcmp(s, "unfold"))
326-
atom->u.contents.trailer_opts.unfold = 1;
327-
else if (!strcmp(s, "only"))
328-
atom->u.contents.trailer_opts.only_trailers = 1;
329-
else {
330-
strbuf_addf(err, _("unknown %%(trailers) argument: %s"), s);
331-
string_list_clear(&params, 0);
332-
return -1;
333-
}
325+
const char *argbuf = xstrfmt("%s)", arg);
326+
char *invalid_arg = NULL;
327+
328+
if (format_set_trailers_options(&atom->u.contents.trailer_opts,
329+
&ref_trailer_buf.filter_list,
330+
&ref_trailer_buf.sepbuf,
331+
&ref_trailer_buf.kvsepbuf,
332+
&argbuf, &invalid_arg)) {
333+
if (!invalid_arg)
334+
strbuf_addf(err, _("expected %%(trailers:key=<value>)"));
335+
else
336+
strbuf_addf(err, _("unknown %%(trailers) argument: %s"), invalid_arg);
337+
free((char *)invalid_arg);
338+
return -1;
334339
}
335340
}
336341
atom->u.contents.option = C_TRAILERS;
337-
string_list_clear(&params, 0);
338342
return 0;
339343
}
340344

0 commit comments

Comments
 (0)