This new format placeholder allows displaying only a single
trailer. The formatting done is similar to what is done for
--decorate/%d using parentheses and comma separation.

It's intended use is for things like ticket references in trailers.

So with a commit with a message like:

 > Some good commit
 >
 > Ticket: XYZ-123

running:

 $ git log --pretty="%H %s% (trailer:Ticket)"

will give:

 > 123456789a Some good commit (Ticket: XYZ-123)

Signed-off-by: Anders Waldenborg <and...@0x63.nu>
---
 Documentation/pretty-formats.txt |  4 ++++
 pretty.c                         | 16 +++++++++++++
 t/t4205-log-pretty-formats.sh    | 40 ++++++++++++++++++++++++++++++++
 trailer.c                        | 18 ++++++++++++--
 trailer.h                        |  1 +
 5 files changed, 77 insertions(+), 2 deletions(-)

diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
index 6109ef09aa..a46d0c0717 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -211,6 +211,10 @@ endif::git-rev-list[]
   If the `unfold` option is given, behave as if interpret-trailer's
   `--unfold` option was given.  E.g., `%(trailers:only,unfold)` to do
   both.
+- %(trailer:<t>): display the specified trailer in parentheses (like
+  %d does for refnames). If there are multiple entries of that trailer
+  they are shown comma separated. If there are no matching trailers
+  nothing is displayed.
 
 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 8ca29e9281..61ae34ced4 100644
--- a/pretty.c
+++ b/pretty.c
@@ -1324,6 +1324,22 @@ static size_t format_commit_one(struct strbuf *sb, /* in 
UTF-8 */
                }
        }
 
+       if (skip_prefix(placeholder, "(trailer:", &arg)) {
+               struct process_trailer_options opts = 
PROCESS_TRAILER_OPTIONS_INIT;
+               opts.no_divider = 1;
+               opts.only_trailers = 1;
+               opts.unfold = 1;
+
+               const char *end = strchr(arg, ')');
+               if (!end)
+                       return 0;
+
+               opts.filter_trailer = xstrndup(arg, end - arg);
+               format_trailers_from_commit(sb, msg + c->subject_off, &opts);
+               free(opts.filter_trailer);
+               return end - placeholder + 1;
+       }
+
        return 0;       /* unknown placeholder */
 }
 
diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh
index 978a8a66ff..e929f820e7 100755
--- a/t/t4205-log-pretty-formats.sh
+++ b/t/t4205-log-pretty-formats.sh
@@ -598,6 +598,46 @@ test_expect_success ':only and :unfold work together' '
        test_cmp expect actual
 '
 
+test_expect_success 'pretty format %(trailer:foo) shows that trailer' '
+       git log --no-walk --pretty="%(trailer:Acked-By)" >actual &&
+       {
+               echo "(Acked-By: A U Thor <aut...@example.com>)"
+       } >expect &&
+       test_cmp expect actual
+'
+
+test_expect_success '%(trailer:nonexistant) becomes empty' '
+       git log --no-walk --pretty="x%(trailer:Nacked-By)x" >actual &&
+       {
+               echo "xx"
+       } >expect &&
+       test_cmp expect actual
+'
+
+test_expect_success '% (trailer:nonexistant) with space becomes empty' '
+       git log --no-walk --pretty="x% (trailer:Nacked-By)x" >actual &&
+       {
+               echo "xx"
+       } >expect &&
+       test_cmp expect actual
+'
+
+test_expect_success '% (trailer:foo) with space adds space before' '
+       git log --no-walk --pretty="x% (trailer:Acked-By)x" >actual &&
+       {
+               echo "x (Acked-By: A U Thor <aut...@example.com>)x"
+       } >expect &&
+       test_cmp expect actual
+'
+
+test_expect_success '%(trailer:foo) with multiple lines becomes comma 
separated and unwrapped' '
+       git log --no-walk --pretty="%(trailer:Signed-Off-By)" >actual &&
+       {
+               echo "(Signed-Off-By: A U Thor <aut...@example.com>, A U Thor 
<aut...@example.com>)"
+       } >expect &&
+       test_cmp expect actual
+'
+
 test_expect_success 'trailer parsing not fooled by --- line' '
        git commit --allow-empty -F - <<-\EOF &&
        this is the subject
diff --git a/trailer.c b/trailer.c
index 0796f326b3..d337bca8dd 100644
--- a/trailer.c
+++ b/trailer.c
@@ -1138,6 +1138,7 @@ static void format_trailer_info(struct strbuf *out,
                return;
        }
 
+       int printed_first = 0;
        for (i = 0; i < info->trailer_nr; i++) {
                char *trailer = info->trailers[i];
                ssize_t separator_pos = find_separator(trailer, separators);
@@ -1150,7 +1151,19 @@ static void format_trailer_info(struct strbuf *out,
                        if (opts->unfold)
                                unfold_value(&val);
 
-                       strbuf_addf(out, "%s: %s\n", tok.buf, val.buf);
+                       if (opts->filter_trailer) {
+                               if (!strcasecmp (tok.buf, 
opts->filter_trailer)) {
+                                       if (!printed_first) {
+                                               strbuf_addf(out, "(%s: ", 
opts->filter_trailer);
+                                               printed_first = 1;
+                                       } else {
+                                               strbuf_addstr(out, ", ");
+                                       }
+                                       strbuf_addstr(out, val.buf);
+                               }
+                       } else {
+                               strbuf_addf(out, "%s: %s\n", tok.buf, val.buf);
+                       }
                        strbuf_release(&tok);
                        strbuf_release(&val);
 
@@ -1158,7 +1171,8 @@ static void format_trailer_info(struct strbuf *out,
                        strbuf_addstr(out, trailer);
                }
        }
-
+       if (printed_first)
+               strbuf_addstr(out, ")");
 }
 
 void format_trailers_from_commit(struct strbuf *out, const char *msg,
diff --git a/trailer.h b/trailer.h
index b997739649..852c79d449 100644
--- a/trailer.h
+++ b/trailer.h
@@ -72,6 +72,7 @@ struct process_trailer_options {
        int only_input;
        int unfold;
        int no_divider;
+       char *filter_trailer;
 };
 
 #define PROCESS_TRAILER_OPTIONS_INIT {0}
-- 
2.17.1

Reply via email to