Skip to content

Commit b62bbd3

Browse files
committed
Merge branch 'ab/trailers-extra-format'
The "--format=%(trailers)" mechanism gets enhanced to make it easier to design output for machine consumption. * ab/trailers-extra-format: pretty format %(trailers): add a "key_value_separator" pretty format %(trailers): add a "keyonly" pretty-format %(trailers): fix broken standalone "valueonly" pretty format %(trailers) doc: avoid repetition pretty format %(trailers) test: split a long line
2 parents c977ff4 + 058761f commit b62bbd3

File tree

5 files changed

+141
-19
lines changed

5 files changed

+141
-19
lines changed

Documentation/pretty-formats.txt

Lines changed: 20 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -252,7 +252,15 @@ endif::git-rev-list[]
252252
interpreted by
253253
linkgit:git-interpret-trailers[1]. The
254254
`trailers` string may be followed by a colon
255-
and zero or more comma-separated options:
255+
and zero or more comma-separated options.
256+
If any option is provided multiple times the
257+
last occurance wins.
258+
+
259+
The boolean options accept an optional value `[=<BOOL>]`. The values
260+
`true`, `false`, `on`, `off` etc. are all accepted. See the "boolean"
261+
sub-section in "EXAMPLES" in linkgit:git-config[1]. If a boolean
262+
option is given with no value, it's enabled.
263+
+
256264
** 'key=<K>': only show trailers with specified key. Matching is done
257265
case-insensitively and trailing colon is optional. If option is
258266
given multiple times trailer lines matching any of the keys are
@@ -261,27 +269,25 @@ endif::git-rev-list[]
261269
desired it can be disabled with `only=false`. E.g.,
262270
`%(trailers:key=Reviewed-by)` shows trailer lines with key
263271
`Reviewed-by`.
264-
** 'only[=val]': select whether non-trailer lines from the trailer
265-
block should be included. The `only` keyword may optionally be
266-
followed by an equal sign and one of `true`, `on`, `yes` to omit or
267-
`false`, `off`, `no` to show the non-trailer lines. If option is
268-
given without value it is enabled. If given multiple times the last
269-
value is used.
272+
** 'only[=<BOOL>]': select whether non-trailer lines from the trailer
273+
block should be included.
270274
** 'separator=<SEP>': specify a separator inserted between trailer
271275
lines. When this option is not given each trailer line is
272276
terminated with a line feed character. The string SEP may contain
273277
the literal formatting codes described above. To use comma as
274278
separator one must use `%x2C` as it would otherwise be parsed as
275-
next option. If separator option is given multiple times only the
276-
last one is used. E.g., `%(trailers:key=Ticket,separator=%x2C )`
279+
next option. E.g., `%(trailers:key=Ticket,separator=%x2C )`
277280
shows all trailer lines whose key is "Ticket" separated by a comma
278281
and a space.
279-
** 'unfold[=val]': make it behave as if interpret-trailer's `--unfold`
280-
option was given. In same way as to for `only` it can be followed
281-
by an equal sign and explicit value. E.g.,
282+
** 'unfold[=<BOOL>]': make it behave as if interpret-trailer's `--unfold`
283+
option was given. E.g.,
282284
`%(trailers:only,unfold=true)` unfolds and shows all trailer lines.
283-
** 'valueonly[=val]': skip over the key part of the trailer line and only
284-
show the value part. Also this optionally allows explicit value.
285+
** 'keyonly[=<BOOL>]': only show the key part of the trailer.
286+
** 'valueonly[=<BOOL>]': only show the value part of the trailer.
287+
** 'key_value_separator=<SEP>': specify a separator inserted between
288+
trailer lines. When this option is not given each trailer key-value
289+
pair is separated by ": ". Otherwise it shares the same semantics
290+
as 'separator=<SEP>' above.
285291

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

pretty.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1418,6 +1418,7 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
14181418
struct process_trailer_options opts = PROCESS_TRAILER_OPTIONS_INIT;
14191419
struct string_list filter_list = STRING_LIST_INIT_NODUP;
14201420
struct strbuf sepbuf = STRBUF_INIT;
1421+
struct strbuf kvsepbuf = STRBUF_INIT;
14211422
size_t ret = 0;
14221423

14231424
opts.no_divider = 1;
@@ -1449,8 +1450,17 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
14491450
strbuf_expand(&sepbuf, fmt, strbuf_expand_literal_cb, NULL);
14501451
free(fmt);
14511452
opts.separator = &sepbuf;
1453+
} else if (match_placeholder_arg_value(arg, "key_value_separator", &arg, &argval, &arglen)) {
1454+
char *fmt;
1455+
1456+
strbuf_reset(&kvsepbuf);
1457+
fmt = xstrndup(argval, arglen);
1458+
strbuf_expand(&kvsepbuf, fmt, strbuf_expand_literal_cb, NULL);
1459+
free(fmt);
1460+
opts.key_value_separator = &kvsepbuf;
14521461
} else if (!match_placeholder_bool_arg(arg, "only", &arg, &opts.only_trailers) &&
14531462
!match_placeholder_bool_arg(arg, "unfold", &arg, &opts.unfold) &&
1463+
!match_placeholder_bool_arg(arg, "keyonly", &arg, &opts.key_only) &&
14541464
!match_placeholder_bool_arg(arg, "valueonly", &arg, &opts.value_only))
14551465
break;
14561466
}

t/t4205-log-pretty-formats.sh

Lines changed: 97 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,12 @@ test_expect_success 'pretty format %(trailers) shows trailers' '
605605
test_cmp expect actual
606606
'
607607

608+
test_expect_success 'pretty format %(trailers:) enables no options' '
609+
git log --no-walk --pretty="%(trailers:)" >actual &&
610+
# "expect" the same as the test above
611+
test_cmp expect actual
612+
'
613+
608614
test_expect_success '%(trailers:only) shows only "key: value" trailers' '
609615
git log --no-walk --pretty="%(trailers:only)" >actual &&
610616
{
@@ -709,19 +715,101 @@ test_expect_success '%(trailers:key) without value is error' '
709715
test_cmp expect actual
710716
'
711717

718+
test_expect_success '%(trailers:keyonly) shows only keys' '
719+
git log --no-walk --pretty="format:%(trailers:keyonly)" >actual &&
720+
test_write_lines \
721+
"Signed-off-by" \
722+
"Acked-by" \
723+
"[ v2 updated patch description ]" \
724+
"Signed-off-by" >expect &&
725+
test_cmp expect actual
726+
'
727+
728+
test_expect_success '%(trailers:key=foo,keyonly) shows only key' '
729+
git log --no-walk --pretty="format:%(trailers:key=Acked-by,keyonly)" >actual &&
730+
echo "Acked-by" >expect &&
731+
test_cmp expect actual
732+
'
733+
712734
test_expect_success '%(trailers:key=foo,valueonly) shows only value' '
713735
git log --no-walk --pretty="format:%(trailers:key=Acked-by,valueonly)" >actual &&
714736
echo "A U Thor <[email protected]>" >expect &&
715737
test_cmp expect actual
716738
'
717739

740+
test_expect_success '%(trailers:valueonly) shows only values' '
741+
git log --no-walk --pretty="format:%(trailers:valueonly)" >actual &&
742+
test_write_lines \
743+
"A U Thor <[email protected]>" \
744+
"A U Thor <[email protected]>" \
745+
"[ v2 updated patch description ]" \
746+
"A U Thor" \
747+
" <[email protected]>" >expect &&
748+
test_cmp expect actual
749+
'
750+
751+
test_expect_success '%(trailers:key=foo,keyonly,valueonly) shows nothing' '
752+
git log --no-walk --pretty="format:%(trailers:key=Acked-by,keyonly,valueonly)" >actual &&
753+
echo >expect &&
754+
test_cmp expect actual
755+
'
756+
718757
test_expect_success 'pretty format %(trailers:separator) changes separator' '
758+
git log --no-walk --pretty=format:"X%(trailers:separator=%x00)X" >actual &&
759+
(
760+
printf "XSigned-off-by: A U Thor <[email protected]>\0" &&
761+
printf "Acked-by: A U Thor <[email protected]>\0" &&
762+
printf "[ v2 updated patch description ]\0" &&
763+
printf "Signed-off-by: A U Thor\n <[email protected]>X"
764+
) >expect &&
765+
test_cmp expect actual
766+
'
767+
768+
test_expect_success 'pretty format %(trailers:separator=X,unfold) changes separator' '
719769
git log --no-walk --pretty=format:"X%(trailers:separator=%x00,unfold)X" >actual &&
720-
printf "XSigned-off-by: A U Thor <[email protected]>\0Acked-by: A U Thor <[email protected]>\0[ v2 updated patch description ]\0Signed-off-by: A U Thor <[email protected]>X" >expect &&
770+
(
771+
printf "XSigned-off-by: A U Thor <[email protected]>\0" &&
772+
printf "Acked-by: A U Thor <[email protected]>\0" &&
773+
printf "[ v2 updated patch description ]\0" &&
774+
printf "Signed-off-by: A U Thor <[email protected]>X"
775+
) >expect &&
776+
test_cmp expect actual
777+
'
778+
779+
test_expect_success 'pretty format %(trailers:key_value_separator) changes key-value separator' '
780+
git log --no-walk --pretty=format:"X%(trailers:key_value_separator=%x00)X" >actual &&
781+
(
782+
printf "XSigned-off-by\0A U Thor <[email protected]>\n" &&
783+
printf "Acked-by\0A U Thor <[email protected]>\n" &&
784+
printf "[ v2 updated patch description ]\n" &&
785+
printf "Signed-off-by\0A U Thor\n <[email protected]>\nX"
786+
) >expect &&
787+
test_cmp expect actual
788+
'
789+
790+
test_expect_success 'pretty format %(trailers:key_value_separator,unfold) changes key-value separator' '
791+
git log --no-walk --pretty=format:"X%(trailers:key_value_separator=%x00,unfold)X" >actual &&
792+
(
793+
printf "XSigned-off-by\0A U Thor <[email protected]>\n" &&
794+
printf "Acked-by\0A U Thor <[email protected]>\n" &&
795+
printf "[ v2 updated patch description ]\n" &&
796+
printf "Signed-off-by\0A U Thor <[email protected]>\nX"
797+
) >expect &&
798+
test_cmp expect actual
799+
'
800+
801+
test_expect_success 'pretty format %(trailers:separator,key_value_separator) changes both separators' '
802+
git log --no-walk --pretty=format:"%(trailers:separator=%x00,key_value_separator=%x00%x00,unfold)" >actual &&
803+
(
804+
printf "Signed-off-by\0\0A U Thor <[email protected]>\0" &&
805+
printf "Acked-by\0\0A U Thor <[email protected]>\0" &&
806+
printf "[ v2 updated patch description ]\0" &&
807+
printf "Signed-off-by\0\0A U Thor <[email protected]>"
808+
) >expect &&
721809
test_cmp expect actual
722810
'
723811

724-
test_expect_success 'pretty format %(trailers) combining separator/key/valueonly' '
812+
test_expect_success 'pretty format %(trailers) combining separator/key/keyonly/valueonly' '
725813
git commit --allow-empty -F - <<-\EOF &&
726814
Important fix
727815
@@ -748,6 +836,13 @@ test_expect_success 'pretty format %(trailers) combining separator/key/valueonly
748836
"Does not close any tickets" \
749837
"Another fix #567, #890" \
750838
"Important fix #1234" >expect &&
839+
test_cmp expect actual &&
840+
841+
git log --pretty="%s% (trailers:separator=%x2c%x20,key=Closes,keyonly)" HEAD~3.. >actual &&
842+
test_write_lines \
843+
"Does not close any tickets" \
844+
"Another fix Closes, Closes" \
845+
"Important fix Closes" >expect &&
751846
test_cmp expect actual
752847
'
753848

trailer.c

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1131,7 +1131,9 @@ static void format_trailer_info(struct strbuf *out,
11311131
size_t i;
11321132

11331133
/* If we want the whole block untouched, we can take the fast path. */
1134-
if (!opts->only_trailers && !opts->unfold && !opts->filter && !opts->separator) {
1134+
if (!opts->only_trailers && !opts->unfold && !opts->filter &&
1135+
!opts->separator && !opts->key_only && !opts->value_only &&
1136+
!opts->key_value_separator) {
11351137
strbuf_add(out, info->trailer_start,
11361138
info->trailer_end - info->trailer_start);
11371139
return;
@@ -1153,8 +1155,15 @@ static void format_trailer_info(struct strbuf *out,
11531155
if (opts->separator && out->len != origlen)
11541156
strbuf_addbuf(out, opts->separator);
11551157
if (!opts->value_only)
1156-
strbuf_addf(out, "%s: ", tok.buf);
1157-
strbuf_addbuf(out, &val);
1158+
strbuf_addbuf(out, &tok);
1159+
if (!opts->key_only && !opts->value_only) {
1160+
if (opts->key_value_separator)
1161+
strbuf_addbuf(out, opts->key_value_separator);
1162+
else
1163+
strbuf_addstr(out, ": ");
1164+
}
1165+
if (!opts->key_only)
1166+
strbuf_addbuf(out, &val);
11581167
if (!opts->separator)
11591168
strbuf_addch(out, '\n');
11601169
}

trailer.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,10 @@ struct process_trailer_options {
7171
int only_input;
7272
int unfold;
7373
int no_divider;
74+
int key_only;
7475
int value_only;
7576
const struct strbuf *separator;
77+
const struct strbuf *key_value_separator;
7678
int (*filter)(const struct strbuf *, void *);
7779
void *filter_data;
7880
};

0 commit comments

Comments
 (0)