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

[PATCH v3 6/9] trailer: find the end of the log message

From
LGLinus Arver via GitGitGadget <gitgitgadget@gmail.com>
Date
Sep 22, 2023, 19:50 UTC
Message-ID
<ab8a6ced1435580ad3e8585e464e447d40805232.1695412245.git.gitgitgadget@gmail.com>
In-Reply-To
<pull.1563.v3.git.1695412245.gitgitgadget@gmail.com>
From: Linus Arver <linusa@google.com>

Previously, trailer_info_get() computed the trailer block end position by

(1) checking for the opts->no_divider flag and optionally calling
    find_patch_start() to find the "patch start" location (patch_start), and
(2) calling find_trailer_end() to find the end of the trailer block
    using patch_start as a guide, saving the return value into
    "trailer_end".

The logic in (1) was awkward because the variable "patch_start" is misleading if there is no patch in the input. The logic in (2) was misleading because it could be the case that no trailers are in the input (yet we are setting a "trailer_end" variable before even searching for trailers, which happens later in find_trailer_start()). The name "find_trailer_end" was misleading because that function did not look for any trailer block itself --- instead it just computed the end position of the log message in the input where the end of the trailer block (if it exists) would be (because trailer blocks must always come after the end of the log message).

Combine the logic in (1) and (2) together into find_patch_start() by renaming it to find_end_of_log_message(). The end of the log message is the starting point which find_trailer_start() needs to start searching backward to parse individual trailers (if any).

Helped-by: Junio C Hamano <gitster@pobox.com>
Signed-off-by: Linus Arver <linusa@google.com>
---
 trailer.c | 61 ++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 38 insertions(+), 23 deletions(-)
diff --git a/trailer.c b/trailer.c
index 185b3e2707f..9da89df9d8a 100644
--- a/trailer.c
+++ b/trailer.c
@@ -812,21 +812,47 @@ static ssize_t last_line(const char *buf, size_t len)
 }
 
 /*
- * Return the position of the start of the patch or the length of str if there
- * is no patch in the message.
+ * Find the end of the log message as an offset from the start of the input
+ * (where callers of this function are interested in looking for a trailers
+ * block in the same input). We have to consider two categories of content that
+ * can come at the end of the input which we want to ignore (because they don't
+ * belong in the log message):
+ *
+ * (1) the "patch part" which begins with a "---" divider and has patch
+ * information (like the output of git-format-patch), and
+ *
+ * (2) any trailing comment lines, blank lines like in the output of "git
+ * commit -v", or stuff below the "cut" (scissor) line.
+ *
+ * As a formula, the situation looks like this:
+ *
+ *     INPUT = LOG MESSAGE + IGNORED
+ *
+ * where IGNORED can be either of the two categories described above. It may be
+ * that there is nothing to ignore. Now it may be the case that the LOG MESSAGE
+ * contains a trailer block, but that's not the concern of this function.
  */
-static size_t find_patch_start(const char *str)
+static size_t find_end_of_log_message(const char *input, int no_divider)
 {
+	size_t end;
+
 	const char *s;
 
-	for (s = str; *s; s = next_line(s)) {
+	/* Assume the naive end of the input is already what we want. */
+	end = strlen(input);
+
+	/* Optionally skip over any patch part ("---" line and below). */
+	for (s = input; *s; s = next_line(s)) {
 		const char *v;
 
-		if (skip_prefix(s, "---", &v) && isspace(*v))
-			return s - str;
+		if (!no_divider && skip_prefix(s, "---", &v) && isspace(*v)) {
+			end = s - input;
+			break;
+		}
 	}
 
-	return s - str;
+	/* Skip over other ignorable bits. */
+	return end - ignored_log_message_bytes(input, end);
 }
 
 /*
@@ -928,12 +954,6 @@ continue_outer_loop:
 	return len;
 }
 
-/* Return the position of the end of the trailers. */
-static size_t find_trailer_end(const char *buf, size_t len)
-{
-	return len - ignored_log_message_bytes(buf, len);
-}
-
 static int ends_with_blank_line(const char *buf, size_t len)
 {
 	ssize_t ll = last_line(buf, len);
@@ -1104,7 +1124,7 @@ void process_trailers(const char *file,
 void trailer_info_get(struct trailer_info *info, const char *str,
 		      const struct process_trailer_options *opts)
 {
-	int patch_start, trailer_end, trailer_start;
+	int end_of_log_message, trailer_start;
 	struct strbuf **trailer_lines, **ptr;
 	char **trailer_strings = NULL;
 	size_t nr = 0, alloc = 0;
@@ -1112,16 +1132,11 @@ void trailer_info_get(struct trailer_info *info, const char *str,
 
 	ensure_configured();
 
-	if (opts->no_divider)
-		patch_start = strlen(str);
-	else
-		patch_start = find_patch_start(str);
-
-	trailer_end = find_trailer_end(str, patch_start);
-	trailer_start = find_trailer_start(str, trailer_end);
+	end_of_log_message = find_end_of_log_message(str, opts->no_divider);
+	trailer_start = find_trailer_start(str, end_of_log_message);
 
 	trailer_lines = strbuf_split_buf(str + trailer_start,
-					 trailer_end - trailer_start,
+					 end_of_log_message - trailer_start,
 					 '\n',
 					 0);
 	for (ptr = trailer_lines; *ptr; ptr++) {
@@ -1144,7 +1159,7 @@ void trailer_info_get(struct trailer_info *info, const char *str,
 	info->blank_line_before_trailer = ends_with_blank_line(str,
 							       trailer_start);
 	info->trailer_start = str + trailer_start;
-	info->trailer_end = str + trailer_end;
+	info->trailer_end = str + end_of_log_message;
 	info->trailers = trailer_strings;
 	info->trailer_nr = nr;
 }
-- 
gitgitgadget
Previous: Linus Arver via GitGitGadgetNext: Linus Arver via GitGitGadget
Message 50 of 72 in “Trailer readability cleanups”
  1. 0/5 Trailer readability cleanupsLinus Arver via GitGitGadget, Aug 5, 2023
  2. 1/5 trailer: separate public from internal portion of trailer_iteratorLinus Arver via GitGitGadget, Aug 5, 2023
  3. Glen ChooAug 7, 2023
  4. Phillip WoodAug 8, 2023
  5. Linus ArverAug 10, 2023
  6. Linus ArverAug 10, 2023
  7. 2/5 trailer: split process_input_file into separate piecesLinus Arver via GitGitGadget, Aug 5, 2023
  8. Glen ChooAug 7, 2023
  9. Linus ArverAug 11, 2023
  10. 4/5 trailer: teach find_patch_start about --no-dividerLinus Arver via GitGitGadget, Aug 5, 2023
  11. Glen ChooAug 7, 2023
  12. Linus ArverAug 11, 2023
  13. Glen ChooAug 11, 2023
  14. 3/5 trailer: split process_command_line_args into separate functionsLinus Arver via GitGitGadget, Aug 5, 2023
  15. Glen ChooAug 7, 2023
  16. Linus ArverAug 11, 2023
  17. Linus ArverAug 11, 2023
  18. Glen ChooAug 11, 2023
  19. 5/5 trailer: rename *_DEFAULT enums to *_UNSPECIFIEDLinus Arver via GitGitGadget, Aug 5, 2023
  20. Glen ChooAug 7, 2023
  21. Linus ArverAug 11, 2023
  22. 0/6 Trailer readability cleanupsLinus Arver via GitGitGadget, Sep 9, 2023
  23. 1/6 trailer: separate public from internal portion of trailer_iteratorLinus Arver via GitGitGadget, Sep 9, 2023
  24. Junio C HamanoSep 11, 2023
  25. 2/6 trailer: split process_input_file into separate piecesLinus Arver via GitGitGadget, Sep 9, 2023
  26. Junio C HamanoSep 11, 2023
  27. 3/6 trailer: split process_command_line_args into separate functionsLinus Arver via GitGitGadget, Sep 9, 2023
  28. 4/6 trailer: teach find_patch_start about --no-dividerLinus Arver via GitGitGadget, Sep 9, 2023
  29. Junio C HamanoSep 11, 2023
  30. Linus ArverSep 14, 2023
  31. Junio C HamanoSep 14, 2023
  32. Linus ArverSep 14, 2023
  33. 6/6 trailer: use offsets for trailer_start/trailer_endLinus Arver via GitGitGadget, Sep 9, 2023
  34. Junio C HamanoSep 11, 2023
  35. Linus ArverSep 14, 2023
  36. Linus ArverSep 14, 2023
  37. 5/6 trailer: rename *_DEFAULT enums to *_UNSPECIFIEDLinus Arver via GitGitGadget, Sep 9, 2023
  38. Junio C HamanoSep 11, 2023
  39. Linus ArverSep 14, 2023
  40. Junio C HamanoSep 14, 2023
  41. Linus ArverSep 22, 2023
  42. Junio C HamanoSep 22, 2023
  43. Linus ArverSep 26, 2023
  44. 0/9 Trailer readability cleanupsLinus Arver via GitGitGadget, Sep 22, 2023
  45. 1/9 trailer: separate public from internal portion of trailer_iteratorLinus Arver via GitGitGadget, Sep 22, 2023
  46. 2/9 trailer: split process_input_file into separate piecesLinus Arver via GitGitGadget, Sep 22, 2023
  47. 3/9 trailer: split process_command_line_args into separate functionsLinus Arver via GitGitGadget, Sep 22, 2023
  48. 4/9 trailer: rename *_DEFAULT enums to *_UNSPECIFIEDLinus Arver via GitGitGadget, Sep 22, 2023
  49. 5/9 commit: ignore_non_trailer computes number of bytes to ignoreLinus Arver via GitGitGadget, Sep 22, 2023
  50. 6/9 trailer: find the end of the log messageLinus Arver via GitGitGadget, Sep 22, 2023
  51. 9/9 trailer: make stack variable names match field namesLinus Arver via GitGitGadget, Sep 22, 2023
  52. 7/9 trailer: use offsets for trailer_start/trailer_endLinus Arver via GitGitGadget, Sep 22, 2023
  53. 8/9 trailer: only use trailer_block_* variables if trailers were foundLinus Arver via GitGitGadget, Sep 22, 2023
  54. Junio C HamanoSep 22, 2023
  55. Linus ArverSep 22, 2023
  56. Junio C HamanoSep 23, 2023
  57. Linus ArverSep 26, 2023
  58. 0/4 Trailer readability cleanupsLinus Arver via GitGitGadget, Sep 26, 2023
  59. 1/4 commit: ignore_non_trailer computes number of bytes to ignoreLinus Arver via GitGitGadget, Sep 26, 2023
  60. 2/4 trailer: find the end of the log messageLinus Arver via GitGitGadget, Sep 26, 2023
  61. Jonathan TanSep 28, 2023
  62. Linus ArverOct 20, 2023
  63. Junio C HamanoOct 20, 2023
  64. 3/4 trailer: use offsets for trailer_start/trailer_endLinus Arver via GitGitGadget, Sep 26, 2023
  65. 4/4 trailer: only use trailer_block_* variables if trailers were foundLinus Arver via GitGitGadget, Sep 26, 2023
  66. 0/3 Trailer readability cleanupsLinus Arver via GitGitGadget, Oct 20, 2023
  67. 1/3 commit: ignore_non_trailer computes number of bytes to ignoreLinus Arver via GitGitGadget, Oct 20, 2023
  68. 2/3 trailer: find the end of the log messageLinus Arver via GitGitGadget, Oct 20, 2023
  69. Junio C HamanoOct 20, 2023
  70. Linus ArverDec 29, 2023
  71. Linus ArverDec 29, 2023
  72. 3/3 trailer: use offsets for trailer_start/trailer_endLinus Arver via GitGitGadget, Oct 20, 2023

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.