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

[PATCH v4 2/8] interpret-trailers: add an option to show only the trailers

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

In theory it's easy for any reader who wants to parse trailers to do so. But there are a lot of subtle corner cases around what counts as a trailer, when the trailer block begins and ends, etc. Since interpret-trailers already has our parsing logic, let's let callers ask it to just output the trailers.

They still have to parse the "key: value" lines, but at least they can ignore all of the other corner cases.

Signed-off-by: Jeff King <peff@peff.net>
---
 Documentation/git-interpret-trailers.txt |  3 +++
 builtin/interpret-trailers.c             |  1 +
 t/t7513-interpret-trailers.sh            | 39 ++++++++++++++++++++++++++++++++
 trailer.c                                | 23 +++++++++++--------
 trailer.h                                |  1 +
 5 files changed, 58 insertions(+), 9 deletions(-)
diff --git a/Documentation/git-interpret-trailers.txt b/Documentation/git-interpret-trailers.txt
index 31cdeaecdf..295dffbd21 100644
--- a/Documentation/git-interpret-trailers.txt
+++ b/Documentation/git-interpret-trailers.txt
@@ -80,6 +80,9 @@ OPTIONS
 	trailer to the input messages. See the description of this
 	command.
 
+--only-trailers::
+	Output only the trailers, not any other parts of the input.
+
 CONFIGURATION VARIABLES
 -----------------------
 
diff --git a/builtin/interpret-trailers.c b/builtin/interpret-trailers.c
index bb0d7b937a..afb12c11bc 100644
--- a/builtin/interpret-trailers.c
+++ b/builtin/interpret-trailers.c
@@ -24,6 +24,7 @@ int cmd_interpret_trailers(int argc, const char **argv, const char *prefix)
 	struct option options[] = {
 		OPT_BOOL(0, "in-place", &opts.in_place, N_("edit files in place")),
 		OPT_BOOL(0, "trim-empty", &opts.trim_empty, N_("trim empty trailers")),
+		OPT_BOOL(0, "only-trailers", &opts.only_trailers, N_("output only the trailers")),
 		OPT_STRING_LIST(0, "trailer", &trailers, N_("trailer"),
 				N_("trailer(s) to add")),
 		OPT_END()
diff --git a/t/t7513-interpret-trailers.sh b/t/t7513-interpret-trailers.sh
index 0c6f91c433..90d30037b7 100755
--- a/t/t7513-interpret-trailers.sh
+++ b/t/t7513-interpret-trailers.sh
@@ -1275,4 +1275,43 @@ test_expect_success 'with cut line' '
 	test_cmp expected actual
 '
 
+test_expect_success 'only trailers' '
+	git config trailer.sign.command "echo config-value" &&
+	cat >expected <<-\EOF &&
+		existing: existing-value
+		sign: config-value
+		added: added-value
+	EOF
+	git interpret-trailers \
+		--trailer added:added-value \
+		--only-trailers >actual <<-\EOF &&
+		my subject
+
+		my body
+
+		existing: existing-value
+	EOF
+	test_cmp expected actual
+'
+
+test_expect_success 'only-trailers omits non-trailer in middle of block' '
+	git config trailer.sign.command "echo config-value" &&
+	cat >expected <<-\EOF &&
+		Signed-off-by: nobody <nobody@nowhere>
+		Signed-off-by: somebody <somebody@somewhere>
+		sign: config-value
+	EOF
+	git interpret-trailers --only-trailers >actual <<-\EOF &&
+		subject
+
+		it is important that the trailers below are signed-off-by
+		so that they meet the "25% trailers Git knows about" heuristic
+
+		Signed-off-by: nobody <nobody@nowhere>
+		this is not a trailer
+		Signed-off-by: somebody <somebody@somewhere>
+	EOF
+	test_cmp expected actual
+'
+
 test_done
diff --git a/trailer.c b/trailer.c
index e21a0d1629..22146002e9 100644
--- a/trailer.c
+++ b/trailer.c
@@ -164,13 +164,15 @@ static void print_tok_val(FILE *outfile, const char *tok, const char *val)
 		fprintf(outfile, "%s%c %s\n", tok, separators[0], val);
 }
 
-static void print_all(FILE *outfile, struct list_head *head, int trim_empty)
+static void print_all(FILE *outfile, struct list_head *head,
+		      const struct process_trailer_options *opts)
 {
 	struct list_head *pos;
 	struct trailer_item *item;
 	list_for_each(pos, head) {
 		item = list_entry(pos, struct trailer_item, list);
-		if (!trim_empty || strlen(item->value) > 0)
+		if ((!opts->trim_empty || strlen(item->value) > 0) &&
+		    (!opts->only_trailers || item->token))
 			print_tok_val(outfile, item->token, item->value);
 	}
 }
@@ -887,7 +889,8 @@ static int ends_with_blank_line(const char *buf, size_t len)
 
 static int process_input_file(FILE *outfile,
 			      const char *str,
-			      struct list_head *head)
+			      struct list_head *head,
+			      const struct process_trailer_options *opts)
 {
 	struct trailer_info info;
 	struct strbuf tok = STRBUF_INIT;
@@ -897,9 +900,10 @@ static int process_input_file(FILE *outfile,
 	trailer_info_get(&info, str);
 
 	/* Print lines before the trailers as is */
-	fwrite(str, 1, info.trailer_start - str, outfile);
+	if (!opts->only_trailers)
+		fwrite(str, 1, info.trailer_start - str, outfile);
 
-	if (!info.blank_line_before_trailer)
+	if (!opts->only_trailers && !info.blank_line_before_trailer)
 		fprintf(outfile, "\n");
 
 	for (i = 0; i < info.trailer_nr; i++) {
@@ -914,7 +918,7 @@ static int process_input_file(FILE *outfile,
 			add_trailer_item(head,
 					 strbuf_detach(&tok, NULL),
 					 strbuf_detach(&val, NULL));
-		} else {
+		} else if (!opts->only_trailers) {
 			strbuf_addstr(&val, trailer);
 			strbuf_strip_suffix(&val, "\n");
 			add_trailer_item(head,
@@ -986,18 +990,19 @@ void process_trailers(const char *file,
 		outfile = create_in_place_tempfile(file);
 
 	/* Print the lines before the trailers */
-	trailer_end = process_input_file(outfile, sb.buf, &head);
+	trailer_end = process_input_file(outfile, sb.buf, &head, opts);
 
 	process_command_line_args(&arg_head, trailers);
 
 	process_trailers_lists(&head, &arg_head);
 
-	print_all(outfile, &head, opts->trim_empty);
+	print_all(outfile, &head, opts);
 
 	free_all(&head);
 
 	/* Print the lines after the trailers as is */
-	fwrite(sb.buf + trailer_end, 1, sb.len - trailer_end, outfile);
+	if (!opts->only_trailers)
+		fwrite(sb.buf + trailer_end, 1, sb.len - trailer_end, outfile);
 
 	if (opts->in_place)
 		if (rename_tempfile(&trailers_tempfile, file))
diff --git a/trailer.h b/trailer.h
index 9da00bedec..3cf35ced00 100644
--- a/trailer.h
+++ b/trailer.h
@@ -25,6 +25,7 @@ struct trailer_info {
 struct process_trailer_options {
 	int in_place;
 	int trim_empty;
+	int only_trailers;
 };
 
 #define PROCESS_TRAILER_OPTIONS_INIT {0}
-- 
2.14.1.352.ge5efb0d3f3
Previous: Jeff KingNext: Jeff King
Message 59 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.