summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeff King <peff@peff.net>2017-08-15 06:25:27 -0400
committerJunio C Hamano <gitster@pobox.com>2017-08-15 11:13:58 -0700
commit58311c66fd316dff8f2c68a634ca0cf968227870 (patch)
tree64097b270164843eab9b680239a74f83a0586e45
parentcc1735c4a3cf3377289640ce1af6b4c4523bee11 (diff)
downloadgit-58311c66fd316dff8f2c68a634ca0cf968227870.tar.gz
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 <peff@peff.net> Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rw-r--r--Documentation/pretty-formats.txt5
-rw-r--r--pretty.c15
-rwxr-xr-xt/t4205-log-pretty-formats.sh33
-rw-r--r--trailer.c32
4 files changed, 79 insertions, 6 deletions
diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
index 4d6dac5770..efa67a716e 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -201,7 +201,10 @@ endif::git-rev-list[]
- '%><(<N>)', '%><|(<N>)': similar to '% <(<N>)', '%<|(<N>)'
respectively, but padding both sides (i.e. the text is centered)
- %(trailers): display the trailers of the body as interpreted by
- linkgit:git-interpret-trailers[1]
+ linkgit:git-interpret-trailers[1]. If the `:only` option is given,
+ omit non-trailer lines from the trailer block. If the `:unfold`
+ option is given, behave as if interpret-trailer's `--unfold` option
+ was given. E.g., `%(trailers:only:unfold)` to do both.
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 33054e22cd..0e23fe3c05 100644
--- a/pretty.c
+++ b/pretty.c
@@ -1044,6 +1044,7 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
const struct commit *commit = c->commit;
const char *msg = c->message;
struct commit_list *p;
+ const char *arg;
int ch;
/* these are independent of the commit */
@@ -1262,10 +1263,18 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */
return 1;
}
- if (starts_with(placeholder, "(trailers)")) {
+ if (skip_prefix(placeholder, "(trailers", &arg)) {
struct process_trailer_options opts = PROCESS_TRAILER_OPTIONS_INIT;
- format_trailers_from_commit(sb, msg + c->subject_off, &opts);
- return strlen("(trailers)");
+ while (*arg == ':') {
+ if (skip_prefix(arg, ":only", &arg))
+ opts.only_trailers = 1;
+ else if (skip_prefix(arg, ":unfold", &arg))
+ opts.unfold = 1;
+ }
+ if (*arg == ')') {
+ format_trailers_from_commit(sb, msg + c->subject_off, &opts);
+ return arg - placeholder + 1;
+ }
}
return 0; /* unknown placeholder */
diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh
index 83ea85eb45..ec5f530102 100755
--- a/t/t4205-log-pretty-formats.sh
+++ b/t/t4205-log-pretty-formats.sh
@@ -543,6 +543,10 @@ Signed-off-by: A U Thor
<author@example.com>
EOF
+unfold () {
+ perl -0pe 's/\n\s+/ /'
+}
+
test_expect_success 'set up trailer tests' '
echo "Some contents" >trailerfile &&
git add trailerfile &&
@@ -565,4 +569,33 @@ test_expect_success 'pretty format %(trailers) shows trailers' '
test_cmp expect actual
'
+test_expect_success '%(trailers:only) shows only "key: value" trailers' '
+ git log --no-walk --pretty="%(trailers:only)" >actual &&
+ {
+ grep -v patch.description <trailers &&
+ echo
+ } >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success '%(trailers:unfold) unfolds trailers' '
+ git log --no-walk --pretty="%(trailers:unfold)" >actual &&
+ {
+ unfold <trailers &&
+ echo
+ } >expect &&
+ test_cmp expect actual
+'
+
+test_expect_success ':only and :unfold work together' '
+ git log --no-walk --pretty="%(trailers:only:unfold)" >actual &&
+ git log --no-walk --pretty="%(trailers:unfold:only)" >reverse &&
+ test_cmp actual reverse &&
+ {
+ grep -v patch.description <trailers | unfold &&
+ echo
+ } >expect &&
+ test_cmp expect actual
+'
+
test_done
diff --git a/trailer.c b/trailer.c
index 07580af9c0..6ec5505dc4 100644
--- a/trailer.c
+++ b/trailer.c
@@ -1095,8 +1095,36 @@ static void format_trailer_info(struct strbuf *out,
const struct trailer_info *info,
const struct process_trailer_options *opts)
{
- strbuf_add(out, info->trailer_start,
- info->trailer_end - info->trailer_start);
+ int i;
+
+ /* If we want the whole block untouched, we can take the fast path. */
+ if (!opts->only_trailers && !opts->unfold) {
+ strbuf_add(out, info->trailer_start,
+ info->trailer_end - info->trailer_start);
+ return;
+ }
+
+ for (i = 0; i < info->trailer_nr; i++) {
+ char *trailer = info->trailers[i];
+ int separator_pos = find_separator(trailer, separators);
+
+ if (separator_pos >= 1) {
+ struct strbuf tok = STRBUF_INIT;
+ struct strbuf val = STRBUF_INIT;
+
+ parse_trailer(&tok, &val, NULL, trailer, separator_pos);
+ if (opts->unfold)
+ unfold_value(&val);
+
+ strbuf_addf(out, "%s: %s\n", tok.buf, val.buf);
+ strbuf_release(&tok);
+ strbuf_release(&val);
+
+ } else if (!opts->only_trailers) {
+ strbuf_addstr(out, trailer);
+ }
+ }
+
}
void format_trailers_from_commit(struct strbuf *out, const char *msg,