809
}
810
811
/*
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.
831
*/
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)
833
{
834
+ size_t end;
835
const char *s;
836
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)) {
845
const char *v;
846
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
+ }
851
}
852
826
- return s - str;
853
+ /* Skip over other ignorable bits. */
854
+ return end - ignored_log_message_bytes(input, end);
855
}
856
857
/*
953
return len;
954
}
955
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
-
956
static int ends_with_blank_line(const char *buf, size_t len)
957
{
958
ssize_t ll = last_line(buf, len);
1123
void trailer_info_get(struct trailer_info *info, const char *str,
1124
const struct process_trailer_options *opts)
1125
{
1104
- int patch_start, trailer_end, trailer_start;
1126
+ int end_of_log_message, trailer_start;
1127
struct strbuf **trailer_lines, **ptr;
1128
char **trailer_strings = NULL;
1129
size_t nr = 0, alloc = 0;
1131
1132
ensure_configured();
1133
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);
1136
1137
trailer_lines = strbuf_split_buf(str + trailer_start,
1121
- trailer_end - trailer_start,
1138
+ end_of_log_message - trailer_start,
1139
'\n',
1140
0);
1141
for (ptr = trailer_lines; *ptr; ptr++) {
1158
info->blank_line_before_trailer = ends_with_blank_line(str,
1159
trailer_start);
1160
info->trailer_start = str + trailer_start;
1144
- info->trailer_end = str + trailer_end;
1161
+ info->trailer_end = str + end_of_log_message;
1162
info->trailers = trailer_strings;
1163
info->trailer_nr = nr;
1164
}