git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v4 8/8] pretty: support normalization options for %(trailers)

From
Jeff King <peff@peff.net>
Date
Aug 15, 2017, 10:25 UTC
Message-ID
<20170815102527.5rblspnpao67srtq@sigill.intra.peff.net>
In-Reply-To
<20170815102254.knccmhgralfijwli@sigill.intra.peff.net>

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>
---
 Documentation/pretty-formats.txt |  5 ++++-
 pretty.c                         | 15 ++++++++++++---
 t/t4205-log-pretty-formats.sh    | 33 +++++++++++++++++++++++++++++++++
 trailer.c                        | 32 ++++++++++++++++++++++++++++++--
 4 files changed, 79 insertions(+), 6 deletions(-)
diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt
index 973d19606b..d433d50f81 100644
--- a/Documentation/pretty-formats.txt
+++ b/Documentation/pretty-formats.txt
@@ -205,7 +205,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 99b309bb15..94eab5c89e 100644
--- a/pretty.c
+++ b/pretty.c
@@ -1064,6 +1064,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 */
@@ -1282,10 +1283,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 2d2b997ccc..5220d498e5 100644
--- a/trailer.c
+++ b/trailer.c
@@ -1096,8 +1096,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,
-- 
2.14.1.352.ge5efb0d3f3
Previous: Jeff King
Message 68 of 68 in “make interpret-trailers useful for parsing”
  1. 0/5 make interpret-trailers useful for parsingJeff King, Aug 9, 2017
  2. 1/5 trailer: put process_trailers() options into a structJeff King, Aug 9, 2017
  3. 2/5 interpret-trailers: add an option to show only the trailersJeff King, Aug 9, 2017
  4. Stefan BellerAug 9, 2017
  5. Stefan BellerAug 9, 2017
  6. Jonathan TanAug 9, 2017
  7. Jeff KingAug 10, 2017
  8. 3/5 interpret-trailers: add an option to show only existing trailersJeff King, Aug 9, 2017
  9. Stefan BellerAug 9, 2017
  10. Jeff KingAug 10, 2017
  11. Stefan BellerAug 10, 2017
  12. Jeff KingAug 10, 2017
  13. Stefan BellerAug 10, 2017
  14. Junio C HamanoAug 10, 2017
  15. Jonathan TanAug 9, 2017
  16. Jeff KingAug 10, 2017
  17. 4/5 interpret-trailers: add an option to normalize outputJeff King, Aug 9, 2017
  18. 5/5 interpret-trailers: add --parse convenience optionJeff King, Aug 9, 2017
  19. Stefan BellerAug 9, 2017
  20. Jeff KingAug 10, 2017
  21. Junio C HamanoAug 9, 2017
  22. Jacob KellerAug 10, 2017
  23. Jeff KingAug 10, 2017
  24. Junio C HamanoAug 10, 2017
  25. Jacob KellerAug 13, 2017
  26. Jeff KingAug 10, 2017
  27. 1/5 trailer: put process_trailers() options into a structJeff King, Aug 10, 2017
  28. 2/5 interpret-trailers: add an option to show only the trailersJeff King, Aug 10, 2017
  29. 3/5 interpret-trailers: add an option to show only existing trailersJeff King, Aug 10, 2017
  30. 4/5 interpret-trailers: add an option to normalize outputJeff King, Aug 10, 2017
  31. Stefan BellerAug 10, 2017
  32. Jeff KingAug 10, 2017
  33. Christian CouderAug 10, 2017
  34. Jeff KingAug 10, 2017
  35. Christian CouderAug 10, 2017
  36. Stefan BellerAug 10, 2017
  37. Christian CouderAug 10, 2017
  38. Jeff KingAug 10, 2017
  39. Ramsay JonesAug 10, 2017
  40. Jeff KingAug 10, 2017
  41. Ramsay JonesAug 10, 2017
  42. Christian CouderAug 11, 2017
  43. Jeff KingAug 11, 2017
  44. Christian CouderAug 11, 2017
  45. 5/5 interpret-trailers: add --parse convenience optionJeff King, Aug 10, 2017
  46. Jeff KingAug 10, 2017
  47. 1/5 trailer: put process_trailers() options into a structJeff King, Aug 10, 2017
  48. 2/5 interpret-trailers: add an option to show only the trailersJeff King, Aug 10, 2017
  49. Stefan BellerAug 10, 2017
  50. Jeff KingAug 10, 2017
  51. Junio C HamanoAug 10, 2017
  52. 3/5 interpret-trailers: add an option to show only existing trailersJeff King, Aug 10, 2017
  53. 4/5 interpret-trailers: add an option to normalize outputJeff King, Aug 10, 2017
  54. 5/5 interpret-trailers: add --parse convenience optionJeff King, Aug 10, 2017
  55. Stefan BellerAug 10, 2017
  56. Junio C HamanoAug 10, 2017
  57. 0/8 trailer parsing via interpret-trailers and %(trailers)Jeff King, Aug 15, 2017
  58. 1/8 trailer: put process_trailers() options into a structJeff King, Aug 15, 2017
  59. 2/8 interpret-trailers: add an option to show only the trailersJeff King, Aug 15, 2017
  60. 3/8 interpret-trailers: add an option to show only existing trailersJeff King, Aug 15, 2017
  61. 4/8 interpret-trailers: add an option to unfold valuesJeff King, Aug 15, 2017
  62. 5/8 interpret-trailers: add --parse convenience optionJeff King, Aug 15, 2017
  63. Martin ÅgrenAug 15, 2017
  64. Jeff KingAug 16, 2017
  65. Martin ÅgrenAug 17, 2017
  66. 6/8 pretty: move trailer formatting to trailer.cJeff King, Aug 15, 2017
  67. 7/8 t4205: refactor %(trailers) testsJeff King, Aug 15, 2017
  68. 8/8 pretty: support normalization options for %(trailers)Jeff King, Aug 15, 2017

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.