Skip to content

Commit 97e9d0b

Browse files
Linus Arvergitster
Linus Arver
authored andcommitted
trailer: find the end of the log message
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: Jonathan Tan <jonathantanmy@google.com> Helped-by: Junio C Hamano <gitster@pobox.com> Signed-off-by: Linus Arver <linusa@google.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
1 parent 7cb26a1 commit 97e9d0b

File tree

1 file changed

+40
-23
lines changed

1 file changed

+40
-23
lines changed

trailer.c

Lines changed: 40 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -809,21 +809,49 @@ static ssize_t last_line(const char *buf, size_t len)
809809
}
810810

811811
/*
812-
* Return the position of the start of the patch or the length of str if there
813-
* is no patch in the message.
812+
* Find the end of the log message as an offset from the start of the input
813+
* (where callers of this function are interested in looking for a trailers
814+
* block in the same input). We have to consider two categories of content that
815+
* can come at the end of the input which we want to ignore (because they don't
816+
* belong in the log message):
817+
*
818+
* (1) the "patch part" which begins with a "---" divider and has patch
819+
* information (like the output of git-format-patch), and
820+
*
821+
* (2) any trailing comment lines, blank lines like in the output of "git
822+
* commit -v", or stuff below the "cut" (scissor) line.
823+
*
824+
* As a formula, the situation looks like this:
825+
*
826+
* INPUT = LOG MESSAGE + IGNORED
827+
*
828+
* where IGNORED can be either of the two categories described above. It may be
829+
* that there is nothing to ignore. Now it may be the case that the LOG MESSAGE
830+
* contains a trailer block, but that's not the concern of this function.
814831
*/
815-
static size_t find_patch_start(const char *str)
832+
static size_t find_end_of_log_message(const char *input, int no_divider)
816833
{
834+
size_t end;
817835
const char *s;
818836

819-
for (s = str; *s; s = next_line(s)) {
837+
/* Assume the naive end of the input is already what we want. */
838+
end = strlen(input);
839+
840+
if (no_divider)
841+
return end;
842+
843+
/* Optionally skip over any patch part ("---" line and below). */
844+
for (s = input; *s; s = next_line(s)) {
820845
const char *v;
821846

822-
if (skip_prefix(s, "---", &v) && isspace(*v))
823-
return s - str;
847+
if (skip_prefix(s, "---", &v) && isspace(*v)) {
848+
end = s - input;
849+
break;
850+
}
824851
}
825852

826-
return s - str;
853+
/* Skip over other ignorable bits. */
854+
return end - ignored_log_message_bytes(input, end);
827855
}
828856

829857
/*
@@ -925,12 +953,6 @@ static size_t find_trailer_start(const char *buf, size_t len)
925953
return len;
926954
}
927955

928-
/* Return the position of the end of the trailers. */
929-
static size_t find_trailer_end(const char *buf, size_t len)
930-
{
931-
return len - ignored_log_message_bytes(buf, len);
932-
}
933-
934956
static int ends_with_blank_line(const char *buf, size_t len)
935957
{
936958
ssize_t ll = last_line(buf, len);
@@ -1101,24 +1123,19 @@ void process_trailers(const char *file,
11011123
void trailer_info_get(struct trailer_info *info, const char *str,
11021124
const struct process_trailer_options *opts)
11031125
{
1104-
int patch_start, trailer_end, trailer_start;
1126+
int end_of_log_message, trailer_start;
11051127
struct strbuf **trailer_lines, **ptr;
11061128
char **trailer_strings = NULL;
11071129
size_t nr = 0, alloc = 0;
11081130
char **last = NULL;
11091131

11101132
ensure_configured();
11111133

1112-
if (opts->no_divider)
1113-
patch_start = strlen(str);
1114-
else
1115-
patch_start = find_patch_start(str);
1116-
1117-
trailer_end = find_trailer_end(str, patch_start);
1118-
trailer_start = find_trailer_start(str, trailer_end);
1134+
end_of_log_message = find_end_of_log_message(str, opts->no_divider);
1135+
trailer_start = find_trailer_start(str, end_of_log_message);
11191136

11201137
trailer_lines = strbuf_split_buf(str + trailer_start,
1121-
trailer_end - trailer_start,
1138+
end_of_log_message - trailer_start,
11221139
'\n',
11231140
0);
11241141
for (ptr = trailer_lines; *ptr; ptr++) {
@@ -1141,7 +1158,7 @@ void trailer_info_get(struct trailer_info *info, const char *str,
11411158
info->blank_line_before_trailer = ends_with_blank_line(str,
11421159
trailer_start);
11431160
info->trailer_start = str + trailer_start;
1144-
info->trailer_end = str + trailer_end;
1161+
info->trailer_end = str + end_of_log_message;
11451162
info->trailers = trailer_strings;
11461163
info->trailer_nr = nr;
11471164
}

0 commit comments

Comments
 (0)