As noted in a previous commit which added "keyonly" it's needlessly hard to use the "log" machinery to produce machine-readable output for %(trailers). with the combination of the existing "separator" and this new "key_value_separator" this becomes trivial, as seen by the test being added here. Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@xxxxxxxxx> --- Documentation/pretty-formats.txt | 4 ++++ pretty.c | 9 +++++++++ t/t4205-log-pretty-formats.sh | 22 ++++++++++++++++++++++ trailer.c | 8 ++++++-- 4 files changed, 41 insertions(+), 2 deletions(-) diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt index d080f0d2476..369d243eae9 100644 --- a/Documentation/pretty-formats.txt +++ b/Documentation/pretty-formats.txt @@ -286,6 +286,10 @@ multiple times the last occurance wins. `%(trailers:only,unfold=true)` unfolds and shows all trailer lines. ** 'keyonly[=bool]': only show the key part of the trailer. ** 'valueonly[=bool]': only show the value part of the trailer. +** 'key_value_separator=<SEP>': specify a separator inserted between + trailer lines. When this option is not given each trailer key-value + pair separated by ": ". Otherwise it shares the same semantics as + 'separator=<SEP>' above. NOTE: Some placeholders may depend on other options given to the revision traversal engine. For example, the `%g*` reflog options will diff --git a/pretty.c b/pretty.c index d989a6ae712..dea77f2621a 100644 --- a/pretty.c +++ b/pretty.c @@ -1421,6 +1421,7 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */ struct process_trailer_options opts = PROCESS_TRAILER_OPTIONS_INIT; struct string_list filter_list = STRING_LIST_INIT_NODUP; struct strbuf sepbuf = STRBUF_INIT; + struct strbuf kvsepbuf = STRBUF_INIT; size_t ret = 0; opts.no_divider = 1; @@ -1454,6 +1455,14 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */ strbuf_expand(&sepbuf, fmt, strbuf_expand_literal_cb, NULL); free(fmt); opts.separator = &sepbuf; + } else if (match_placeholder_arg_value(arg, "key_value_separator", &arg, &argval, &arglen)) { + char *fmt; + + strbuf_reset(&kvsepbuf); + fmt = xstrndup(argval, arglen); + strbuf_expand(&kvsepbuf, fmt, strbuf_expand_literal_cb, NULL); + free(fmt); + opts.key_value_separator = &kvsepbuf; } else if (!match_placeholder_bool_arg(arg, "only", &arg, &opts.only_trailers) && !match_placeholder_bool_arg(arg, "unfold", &arg, &opts.unfold) && !match_placeholder_bool_arg(arg, "keyonly", &arg, &opts.key_only) && diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh index e1100082b34..47b3f7d67c4 100755 --- a/t/t4205-log-pretty-formats.sh +++ b/t/t4205-log-pretty-formats.sh @@ -765,6 +765,28 @@ test_expect_success 'pretty format %(trailers:separator) changes separator' ' test_cmp expect actual ' +test_expect_success 'pretty format %(trailers:key_value_separator) changes key-value separator' ' + git log --no-walk --pretty=format:"X%(trailers:key_value_separator=%x00,unfold)X" >actual && + ( + printf "XSigned-off-by\0A U Thor <author@xxxxxxxxxxx>\n" && + printf "Acked-by\0A U Thor <author@xxxxxxxxxxx>\n" && + printf "[ v2 updated patch description ]\n" && + printf "Signed-off-by\0A U Thor <author@xxxxxxxxxxx>\nX" + ) >expect && + test_cmp expect actual +' + +test_expect_success 'pretty format %(trailers:separator,key_value_separator) changes both separators' ' + git log --no-walk --pretty=format:"%(trailers:separator=%x00,key_value_separator=%x00%x00,unfold)" >actual && + ( + printf "Signed-off-by\0\0A U Thor <author@xxxxxxxxxxx>\0" && + printf "Acked-by\0\0A U Thor <author@xxxxxxxxxxx>\0" && + printf "[ v2 updated patch description ]\0" && + printf "Signed-off-by\0\0A U Thor <author@xxxxxxxxxxx>" + ) >expect && + test_cmp expect actual +' + test_expect_success 'pretty format %(trailers) combining separator/key/keyonly/valueonly' ' git commit --allow-empty -F - <<-\EOF && Important fix diff --git a/trailer.c b/trailer.c index da95e1f3c66..70a560647c1 100644 --- a/trailer.c +++ b/trailer.c @@ -1233,8 +1233,12 @@ static void format_trailer_info(struct strbuf *out, strbuf_addbuf(out, opts->separator); if (!opts->value_only) strbuf_addstr(out, tok.buf); - if (!opts->key_only && !opts->value_only) - strbuf_addstr(out, ": "); + if (!opts->key_only && !opts->value_only) { + if (opts->key_value_separator) + strbuf_addbuf(out, opts->key_value_separator); + else + strbuf_addstr(out, ": "); + } if (!opts->key_only) strbuf_addbuf(out, &val); if (!opts->separator) -- 2.29.2.222.g5d2a92d10f8