Merge branch 'la/trailer-cleanups'

Code clean-up.

* la/trailer-cleanups:
  trailer: use offsets for trailer_start/trailer_end
  trailer: find the end of the log message
  commit: ignore_non_trailer computes number of bytes to ignore
maint
Junio C Hamano 2024-01-02 13:51:29 -08:00
commit 59a29e1274
7 changed files with 61 additions and 45 deletions

View File

@ -900,7 +900,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
strbuf_stripspace(&sb, '\0'); strbuf_stripspace(&sb, '\0');


if (signoff) if (signoff)
append_signoff(&sb, ignore_non_trailer(sb.buf, sb.len), 0); append_signoff(&sb, ignored_log_message_bytes(sb.buf, sb.len), 0);


if (fwrite(sb.buf, 1, sb.len, s->fp) < sb.len) if (fwrite(sb.buf, 1, sb.len, s->fp) < sb.len)
die_errno(_("could not write commit template")); die_errno(_("could not write commit template"));

View File

@ -869,7 +869,7 @@ static void prepare_to_commit(struct commit_list *remoteheads)
_(no_scissors_editor_comment), comment_line_char); _(no_scissors_editor_comment), comment_line_char);
} }
if (signoff) if (signoff)
append_signoff(&msg, ignore_non_trailer(msg.buf, msg.len), 0); append_signoff(&msg, ignored_log_message_bytes(msg.buf, msg.len), 0);
write_merge_heads(remoteheads); write_merge_heads(remoteheads);
write_file_buf(git_path_merge_msg(the_repository), msg.buf, msg.len); write_file_buf(git_path_merge_msg(the_repository), msg.buf, msg.len);
if (run_commit_hook(0 < option_edit, get_index_file(), NULL, if (run_commit_hook(0 < option_edit, get_index_file(), NULL,

View File

@ -1783,7 +1783,7 @@ const char *find_commit_header(const char *msg, const char *key, size_t *out_len
* Returns the number of bytes from the tail to ignore, to be fed as * Returns the number of bytes from the tail to ignore, to be fed as
* the second parameter to append_signoff(). * the second parameter to append_signoff().
*/ */
size_t ignore_non_trailer(const char *buf, size_t len) size_t ignored_log_message_bytes(const char *buf, size_t len)
{ {
size_t boc = 0; size_t boc = 0;
size_t bol = 0; size_t bol = 0;

View File

@ -294,8 +294,8 @@ const char *find_header_mem(const char *msg, size_t len,
const char *find_commit_header(const char *msg, const char *key, const char *find_commit_header(const char *msg, const char *key,
size_t *out_len); size_t *out_len);


/* Find the end of the log message, the right place for a new trailer. */ /* Find the number of bytes to ignore from the end of a log message. */
size_t ignore_non_trailer(const char *buf, size_t len); size_t ignored_log_message_bytes(const char *buf, size_t len);


typedef int (*each_mergetag_fn)(struct commit *commit, struct commit_extra_header *extra, typedef int (*each_mergetag_fn)(struct commit *commit, struct commit_extra_header *extra,
void *cb_data); void *cb_data);

View File

@ -340,7 +340,7 @@ static int has_conforming_footer(struct strbuf *sb, struct strbuf *sob,
if (ignore_footer) if (ignore_footer)
sb->buf[sb->len - ignore_footer] = saved_char; sb->buf[sb->len - ignore_footer] = saved_char;


if (info.trailer_start == info.trailer_end) if (info.trailer_block_start == info.trailer_block_end)
return 0; return 0;


for (i = 0; i < info.trailer_nr; i++) for (i = 0; i < info.trailer_nr; i++)

View File

@ -817,28 +817,56 @@ 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 * Find the end of the log message as an offset from the start of the input
* is no patch in the message. * (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; 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);

if (no_divider)
return end;

/* Optionally skip over any patch part ("---" line and below). */
for (s = input; *s; s = next_line(s)) {
const char *v; const char *v;


if (skip_prefix(s, "---", &v) && isspace(*v)) if (skip_prefix(s, "---", &v) && isspace(*v)) {
return s - str; end = s - input;
break;
}
} }


return s - str; /* Skip over other ignorable bits. */
return end - ignored_log_message_bytes(input, end);
} }


/* /*
* Return the position of the first trailer line or len if there are no * Return the position of the first trailer line or len if there are no
* trailers. * trailers.
*/ */
static size_t find_trailer_start(const char *buf, size_t len) static size_t find_trailer_block_start(const char *buf, size_t len)
{ {
const char *s; const char *s;
ssize_t end_of_title, l; ssize_t end_of_title, l;
@ -933,12 +961,6 @@ continue_outer_loop:
return len; 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 - ignore_non_trailer(buf, len);
}

static int ends_with_blank_line(const char *buf, size_t len) static int ends_with_blank_line(const char *buf, size_t len)
{ {
ssize_t ll = last_line(buf, len); ssize_t ll = last_line(buf, len);
@ -1060,7 +1082,6 @@ void process_trailers(const char *file,
LIST_HEAD(head); LIST_HEAD(head);
struct strbuf sb = STRBUF_INIT; struct strbuf sb = STRBUF_INIT;
struct trailer_info info; struct trailer_info info;
size_t trailer_end;
FILE *outfile = stdout; FILE *outfile = stdout;


ensure_configured(); ensure_configured();
@ -1071,11 +1092,10 @@ void process_trailers(const char *file,
outfile = create_in_place_tempfile(file); outfile = create_in_place_tempfile(file);


parse_trailers(&info, sb.buf, &head, opts); parse_trailers(&info, sb.buf, &head, opts);
trailer_end = info.trailer_end - sb.buf;


/* Print the lines before the trailers */ /* Print the lines before the trailers */
if (!opts->only_trailers) if (!opts->only_trailers)
fwrite(sb.buf, 1, info.trailer_start - sb.buf, outfile); fwrite(sb.buf, 1, info.trailer_block_start, outfile);


if (!opts->only_trailers && !info.blank_line_before_trailer) if (!opts->only_trailers && !info.blank_line_before_trailer)
fprintf(outfile, "\n"); fprintf(outfile, "\n");
@ -1097,7 +1117,7 @@ void process_trailers(const char *file,


/* Print the lines after the trailers as is */ /* Print the lines after the trailers as is */
if (!opts->only_trailers) if (!opts->only_trailers)
fwrite(sb.buf + trailer_end, 1, sb.len - trailer_end, outfile); fwrite(sb.buf + info.trailer_block_end, 1, sb.len - info.trailer_block_end, outfile);


if (opts->in_place) if (opts->in_place)
if (rename_tempfile(&trailers_tempfile, file)) if (rename_tempfile(&trailers_tempfile, file))
@ -1109,7 +1129,7 @@ void process_trailers(const char *file,
void trailer_info_get(struct trailer_info *info, const char *str, void trailer_info_get(struct trailer_info *info, const char *str,
const struct process_trailer_options *opts) const struct process_trailer_options *opts)
{ {
int patch_start, trailer_end, trailer_start; size_t end_of_log_message = 0, trailer_block_start = 0;
struct strbuf **trailer_lines, **ptr; struct strbuf **trailer_lines, **ptr;
char **trailer_strings = NULL; char **trailer_strings = NULL;
size_t nr = 0, alloc = 0; size_t nr = 0, alloc = 0;
@ -1117,16 +1137,11 @@ void trailer_info_get(struct trailer_info *info, const char *str,


ensure_configured(); ensure_configured();


if (opts->no_divider) end_of_log_message = find_end_of_log_message(str, opts->no_divider);
patch_start = strlen(str); trailer_block_start = find_trailer_block_start(str, end_of_log_message);
else
patch_start = find_patch_start(str);


trailer_end = find_trailer_end(str, patch_start); trailer_lines = strbuf_split_buf(str + trailer_block_start,
trailer_start = find_trailer_start(str, trailer_end); end_of_log_message - trailer_block_start,

trailer_lines = strbuf_split_buf(str + trailer_start,
trailer_end - trailer_start,
'\n', '\n',
0); 0);
for (ptr = trailer_lines; *ptr; ptr++) { for (ptr = trailer_lines; *ptr; ptr++) {
@ -1147,9 +1162,9 @@ void trailer_info_get(struct trailer_info *info, const char *str,
strbuf_list_free(trailer_lines); strbuf_list_free(trailer_lines);


info->blank_line_before_trailer = ends_with_blank_line(str, info->blank_line_before_trailer = ends_with_blank_line(str,
trailer_start); trailer_block_start);
info->trailer_start = str + trailer_start; info->trailer_block_start = trailer_block_start;
info->trailer_end = str + trailer_end; info->trailer_block_end = end_of_log_message;
info->trailers = trailer_strings; info->trailers = trailer_strings;
info->trailer_nr = nr; info->trailer_nr = nr;
} }
@ -1164,6 +1179,7 @@ void trailer_info_release(struct trailer_info *info)


static void format_trailer_info(struct strbuf *out, static void format_trailer_info(struct strbuf *out,
const struct trailer_info *info, const struct trailer_info *info,
const char *msg,
const struct process_trailer_options *opts) const struct process_trailer_options *opts)
{ {
size_t origlen = out->len; size_t origlen = out->len;
@ -1173,8 +1189,8 @@ static void format_trailer_info(struct strbuf *out,
if (!opts->only_trailers && !opts->unfold && !opts->filter && if (!opts->only_trailers && !opts->unfold && !opts->filter &&
!opts->separator && !opts->key_only && !opts->value_only && !opts->separator && !opts->key_only && !opts->value_only &&
!opts->key_value_separator) { !opts->key_value_separator) {
strbuf_add(out, info->trailer_start, strbuf_add(out, msg + info->trailer_block_start,
info->trailer_end - info->trailer_start); info->trailer_block_end - info->trailer_block_start);
return; return;
} }


@ -1228,7 +1244,7 @@ void format_trailers_from_commit(struct strbuf *out, const char *msg,
struct trailer_info info; struct trailer_info info;


trailer_info_get(&info, msg, opts); trailer_info_get(&info, msg, opts);
format_trailer_info(out, &info, opts); format_trailer_info(out, &info, msg, opts);
trailer_info_release(&info); trailer_info_release(&info);
} }



View File

@ -32,16 +32,16 @@ int trailer_set_if_missing(enum trailer_if_missing *item, const char *value);
struct trailer_info { struct trailer_info {
/* /*
* True if there is a blank line before the location pointed to by * True if there is a blank line before the location pointed to by
* trailer_start. * trailer_block_start.
*/ */
int blank_line_before_trailer; int blank_line_before_trailer;


/* /*
* Pointers to the start and end of the trailer block found. If there * Offsets to the trailer block start and end positions in the input
* is no trailer block found, these 2 pointers point to the end of the * string. If no trailer block is found, these are both set to the
* input string. * "true" end of the input (find_end_of_log_message()).
*/ */
const char *trailer_start, *trailer_end; size_t trailer_block_start, trailer_block_end;


/* /*
* Array of trailers found. * Array of trailers found.