From a4fd4c523444f6b7d11b7af4dc6d790ac4fd8ec5 Mon Sep 17 00:00:00 2001 From: Li Chen Date: Fri, 6 Mar 2026 14:53:29 +0000 Subject: [PATCH] trailer: libify a couple of functions Move create_in_place_tempfile() and process_trailers() from builtin/interpret-trailers.c into trailer.c and expose it via trailer.h. This reverts most of ae0ec2e0e0b (trailer: move interpret_trailers() to interpret-trailers.c, 2024-03-01) and lets other call sites reuse the same trailer rewriting logic. Signed-off-by: Li Chen Signed-off-by: Phillip Wood Signed-off-by: Junio C Hamano --- builtin/interpret-trailers.c | 71 +----------------------------------- trailer.c | 70 +++++++++++++++++++++++++++++++++++ trailer.h | 16 ++++++++ 3 files changed, 87 insertions(+), 70 deletions(-) diff --git a/builtin/interpret-trailers.c b/builtin/interpret-trailers.c index 033c2e4671..acaf42b2d9 100644 --- a/builtin/interpret-trailers.c +++ b/builtin/interpret-trailers.c @@ -93,39 +93,6 @@ static int parse_opt_parse(const struct option *opt, const char *arg, return 0; } - -static struct tempfile *create_in_place_tempfile(const char *file) -{ - struct tempfile *tempfile = NULL; - struct stat st; - struct strbuf filename_template = STRBUF_INIT; - const char *tail; - - if (stat(file, &st)) { - error_errno(_("could not stat %s"), file); - return NULL; - } - if (!S_ISREG(st.st_mode)) { - error(_("file %s is not a regular file"), file); - return NULL; - } - if (!(st.st_mode & S_IWUSR)) { - error(_("file %s is not writable by user"), file); - return NULL; - } - /* Create temporary file in the same directory as the original */ - tail = find_last_dir_sep(file); - if (tail) - strbuf_add(&filename_template, file, tail - file + 1); - strbuf_addstr(&filename_template, "git-interpret-trailers-XXXXXX"); - - tempfile = mks_tempfile_m(filename_template.buf, st.st_mode); - - strbuf_release(&filename_template); - - return tempfile; -} - static void read_input_file(struct strbuf *sb, const char *file) { if (file) { @@ -138,42 +105,6 @@ static void read_input_file(struct strbuf *sb, const char *file) strbuf_complete_line(sb); } -static void process_trailers(const struct process_trailer_options *opts, - struct list_head *new_trailer_head, - struct strbuf *input, struct strbuf *out) -{ - LIST_HEAD(head); - struct trailer_block *trailer_block; - - trailer_block = parse_trailers(opts, input->buf, &head); - - /* Print the lines before the trailer block */ - if (!opts->only_trailers) - strbuf_add(out, input->buf, trailer_block_start(trailer_block)); - - if (!opts->only_trailers && !blank_line_before_trailer_block(trailer_block)) - strbuf_addch(out, '\n'); - - if (!opts->only_input) { - LIST_HEAD(config_head); - LIST_HEAD(arg_head); - parse_trailers_from_config(&config_head); - parse_trailers_from_command_line_args(&arg_head, new_trailer_head); - list_splice(&config_head, &arg_head); - process_trailers_lists(&head, &arg_head); - } - - /* Print trailer block. */ - format_trailers(opts, &head, out); - free_trailers(&head); - - /* Print the lines after the trailer block as is. */ - if (!opts->only_trailers) - strbuf_add(out, input->buf + trailer_block_end(trailer_block), - input->len - trailer_block_end(trailer_block)); - trailer_block_release(trailer_block); -} - static void interpret_trailers(const struct process_trailer_options *opts, struct list_head *new_trailer_head, const char *file) @@ -188,7 +119,7 @@ static void interpret_trailers(const struct process_trailer_options *opts, read_input_file(&input, file); if (opts->in_place) { - tempfile = create_in_place_tempfile(file); + tempfile = trailer_create_in_place_tempfile(file); if (!tempfile) die(NULL); fd = tempfile->fd; diff --git a/trailer.c b/trailer.c index 911a81ed99..163018483a 100644 --- a/trailer.c +++ b/trailer.c @@ -9,6 +9,8 @@ #include "commit.h" #include "trailer.h" #include "list.h" +#include "tempfile.h" + /* * Copyright (c) 2013, 2014 Christian Couder */ @@ -1224,6 +1226,38 @@ void trailer_iterator_release(struct trailer_iterator *iter) strbuf_release(&iter->key); } +struct tempfile *trailer_create_in_place_tempfile(const char *file) +{ + struct tempfile *tempfile = NULL; + struct stat st; + struct strbuf filename_template = STRBUF_INIT; + const char *tail; + + if (stat(file, &st)) { + error_errno(_("could not stat %s"), file); + return NULL; + } + if (!S_ISREG(st.st_mode)) { + error(_("file %s is not a regular file"), file); + return NULL; + } + if (!(st.st_mode & S_IWUSR)) { + error(_("file %s is not writable by user"), file); + return NULL; + } + /* Create temporary file in the same directory as the original */ + tail = find_last_dir_sep(file); + if (tail) + strbuf_add(&filename_template, file, tail - file + 1); + strbuf_addstr(&filename_template, "git-interpret-trailers-XXXXXX"); + + tempfile = mks_tempfile_m(filename_template.buf, st.st_mode); + + strbuf_release(&filename_template); + + return tempfile; +} + int amend_file_with_trailers(const char *path, const struct strvec *trailer_args) { struct child_process run_trailer = CHILD_PROCESS_INIT; @@ -1235,3 +1269,39 @@ int amend_file_with_trailers(const char *path, const struct strvec *trailer_args strvec_pushv(&run_trailer.args, trailer_args->v); return run_command(&run_trailer); } + +void process_trailers(const struct process_trailer_options *opts, + struct list_head *new_trailer_head, + struct strbuf *input, struct strbuf *out) +{ + LIST_HEAD(head); + struct trailer_block *trailer_block; + + trailer_block = parse_trailers(opts, input->buf, &head); + + /* Print the lines before the trailer block */ + if (!opts->only_trailers) + strbuf_add(out, input->buf, trailer_block_start(trailer_block)); + + if (!opts->only_trailers && !blank_line_before_trailer_block(trailer_block)) + strbuf_addch(out, '\n'); + + if (!opts->only_input) { + LIST_HEAD(config_head); + LIST_HEAD(arg_head); + parse_trailers_from_config(&config_head); + parse_trailers_from_command_line_args(&arg_head, new_trailer_head); + list_splice(&config_head, &arg_head); + process_trailers_lists(&head, &arg_head); + } + + /* Print trailer block. */ + format_trailers(opts, &head, out); + free_trailers(&head); + + /* Print the lines after the trailer block as is. */ + if (!opts->only_trailers) + strbuf_add(out, input->buf + trailer_block_end(trailer_block), + input->len - trailer_block_end(trailer_block)); + trailer_block_release(trailer_block); +} diff --git a/trailer.h b/trailer.h index 4740549586..7fd2564e03 100644 --- a/trailer.h +++ b/trailer.h @@ -202,4 +202,20 @@ void trailer_iterator_release(struct trailer_iterator *iter); */ int amend_file_with_trailers(const char *path, const struct strvec *trailer_args); +/* + * Create a tempfile ""git-interpret-trailers-XXXXXX" in the same + * directory as file. + */ +struct tempfile *trailer_create_in_place_tempfile(const char *file); + +/* + * Rewrite the contents of input by processing its trailer block according to + * opts and (optionally) appending trailers from new_trailer_head. + * + * The rewritten message is appended to out (callers should strbuf_reset() + * first if needed). + */ +void process_trailers(const struct process_trailer_options *opts, + struct list_head *new_trailer_head, + struct strbuf *input, struct strbuf *out); #endif /* TRAILER_H */