Skip to content

Commit 58311c6

Browse files
peffgitster
authored andcommitted
pretty: support normalization options for %(trailers)
The interpret-trailers command recently learned some options to make its output easier to parse (for a caller whose only interested in picking out the trailer values). But it's not very efficient for asking for the trailers of many commits in a single invocation. We already have "%(trailers)" to do that, but it doesn't know about unfolding or omitting non-trailers. Let's plumb those options through, so you can have the best of both. Signed-off-by: Jeff King <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent cc1735c commit 58311c6

File tree

4 files changed

+79
-6
lines changed

4 files changed

+79
-6
lines changed

Documentation/pretty-formats.txt

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,10 @@ endif::git-rev-list[]
201201
- '%><(<N>)', '%><|(<N>)': similar to '% <(<N>)', '%<|(<N>)'
202202
respectively, but padding both sides (i.e. the text is centered)
203203
- %(trailers): display the trailers of the body as interpreted by
204-
linkgit:git-interpret-trailers[1]
204+
linkgit:git-interpret-trailers[1]. If the `:only` option is given,
205+
omit non-trailer lines from the trailer block. If the `:unfold`
206+
option is given, behave as if interpret-trailer's `--unfold` option
207+
was given. E.g., `%(trailers:only:unfold)` to do both.
205208

206209
NOTE: Some placeholders may depend on other options given to the
207210
revision traversal engine. For example, the `%g*` reflog options will

pretty.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1044,6 +1044,7 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
10441044
const struct commit *commit = c->commit;
10451045
const char *msg = c->message;
10461046
struct commit_list *p;
1047+
const char *arg;
10471048
int ch;
10481049

10491050
/* these are independent of the commit */
@@ -1262,10 +1263,18 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
12621263
return 1;
12631264
}
12641265

1265-
if (starts_with(placeholder, "(trailers)")) {
1266+
if (skip_prefix(placeholder, "(trailers", &arg)) {
12661267
struct process_trailer_options opts = PROCESS_TRAILER_OPTIONS_INIT;
1267-
format_trailers_from_commit(sb, msg + c->subject_off, &opts);
1268-
return strlen("(trailers)");
1268+
while (*arg == ':') {
1269+
if (skip_prefix(arg, ":only", &arg))
1270+
opts.only_trailers = 1;
1271+
else if (skip_prefix(arg, ":unfold", &arg))
1272+
opts.unfold = 1;
1273+
}
1274+
if (*arg == ')') {
1275+
format_trailers_from_commit(sb, msg + c->subject_off, &opts);
1276+
return arg - placeholder + 1;
1277+
}
12691278
}
12701279

12711280
return 0; /* unknown placeholder */

t/t4205-log-pretty-formats.sh

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -543,6 +543,10 @@ Signed-off-by: A U Thor
543543
544544
EOF
545545

546+
unfold () {
547+
perl -0pe 's/\n\s+/ /'
548+
}
549+
546550
test_expect_success 'set up trailer tests' '
547551
echo "Some contents" >trailerfile &&
548552
git add trailerfile &&
@@ -565,4 +569,33 @@ test_expect_success 'pretty format %(trailers) shows trailers' '
565569
test_cmp expect actual
566570
'
567571

572+
test_expect_success '%(trailers:only) shows only "key: value" trailers' '
573+
git log --no-walk --pretty="%(trailers:only)" >actual &&
574+
{
575+
grep -v patch.description <trailers &&
576+
echo
577+
} >expect &&
578+
test_cmp expect actual
579+
'
580+
581+
test_expect_success '%(trailers:unfold) unfolds trailers' '
582+
git log --no-walk --pretty="%(trailers:unfold)" >actual &&
583+
{
584+
unfold <trailers &&
585+
echo
586+
} >expect &&
587+
test_cmp expect actual
588+
'
589+
590+
test_expect_success ':only and :unfold work together' '
591+
git log --no-walk --pretty="%(trailers:only:unfold)" >actual &&
592+
git log --no-walk --pretty="%(trailers:unfold:only)" >reverse &&
593+
test_cmp actual reverse &&
594+
{
595+
grep -v patch.description <trailers | unfold &&
596+
echo
597+
} >expect &&
598+
test_cmp expect actual
599+
'
600+
568601
test_done

trailer.c

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1095,8 +1095,36 @@ static void format_trailer_info(struct strbuf *out,
10951095
const struct trailer_info *info,
10961096
const struct process_trailer_options *opts)
10971097
{
1098-
strbuf_add(out, info->trailer_start,
1099-
info->trailer_end - info->trailer_start);
1098+
int i;
1099+
1100+
/* If we want the whole block untouched, we can take the fast path. */
1101+
if (!opts->only_trailers && !opts->unfold) {
1102+
strbuf_add(out, info->trailer_start,
1103+
info->trailer_end - info->trailer_start);
1104+
return;
1105+
}
1106+
1107+
for (i = 0; i < info->trailer_nr; i++) {
1108+
char *trailer = info->trailers[i];
1109+
int separator_pos = find_separator(trailer, separators);
1110+
1111+
if (separator_pos >= 1) {
1112+
struct strbuf tok = STRBUF_INIT;
1113+
struct strbuf val = STRBUF_INIT;
1114+
1115+
parse_trailer(&tok, &val, NULL, trailer, separator_pos);
1116+
if (opts->unfold)
1117+
unfold_value(&val);
1118+
1119+
strbuf_addf(out, "%s: %s\n", tok.buf, val.buf);
1120+
strbuf_release(&tok);
1121+
strbuf_release(&val);
1122+
1123+
} else if (!opts->only_trailers) {
1124+
strbuf_addstr(out, trailer);
1125+
}
1126+
}
1127+
11001128
}
11011129

11021130
void format_trailers_from_commit(struct strbuf *out, const char *msg,

0 commit comments

Comments
 (0)