From: Li Chen <me@linux.beauty>
To: "phillipwood" <phillip.wood@dunelm.org.uk>
Cc: "git" <git@vger.kernel.org>, "Junio C Hamano" <gitster@pobox.com>,
"Kristoffer Haugsbakk" <kristofferhaugsbakk@fastmail.com>
Subject: Re: [PATCH v7 0/5] rebase: support --trailer
Date: Thu, 05 Mar 2026 21:49:28 +0800 [thread overview]
Message-ID: <19cbe42b2cd.bb6e3883730656.6495265672263159010@linux.beauty> (raw)
In-Reply-To: <dbaf6ea5-8a08-42c0-8184-16dcf40207dd@gmail.com>
Hi Phillip,
---- On Wed, 04 Mar 2026 22:29:42 +0800 Phillip Wood <phillip.wood123@gmail.com> wrote ---
> Hi Li
>
> On 24/02/2026 07:05, Li Chen wrote:
> > Apologies for the long delay in sending v7.
> >
> > v7 is based on origin/master at v2.53.0-154-g7c02d39fc2.
> >
> > This series routes trailer insertion through an in-process path, removing the
> > fork/exec to builtin/interpret-trailers.
> >
> > The first four commits refactor trailer rewriting in builtin/interpret-trailers
> > and trailer.c so callers can reuse a single in-process helper (used by git
> > interpret-trailers, git commit and git tag). The final commit adds git rebase
> > --trailer, currently supported with the merge backend only (rejecting apply-only
> > scenarios and validating input early).
>
> This all looks pretty good. The main thing I think we want to change is
> sharing the code that creates the temporary file in patch 3. I've push a
> version that does that and fixes my other small comments to
> https://github.com/phillipwood/git/commits/refs/heads/rebase-trailers-v8
> The range diff is below. If you're happy I can post that as a hopefully
> final v8. Of course if you want to work on it yourself you're very
> welcome to do that.
These changes all look good to me! Thank you very much for your patience and work! Please help
post this as v8.
Regards,
Li
>
> 1: b2685e34c22 ! 1: 0d08b361995 interpret-trailers: factor trailer rewriting
> @@ Commit message
> This separation makes it easier to move the helper into trailer.c in the
> next commit.
>
> + Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
> Signed-off-by: Li Chen <me@linux.beauty>
>
> ## builtin/interpret-trailers.c ##
> @@ builtin/interpret-trailers.c: static void read_input_file(struct strbuf *sb, const char *file)
> -: ----------- > 2: 5a4d03ab375 interpret-trailers: refactor create_in_place_tempfile()
> 2: 1bac3025045 ! 3: ab7e232a95d trailer: move process_trailers to trailer.h
> @@ Metadata
> Author: Li Chen <me@linux.beauty>
>
> ## Commit message ##
> - trailer: move process_trailers to trailer.h
> -
> - Move process_trailers() from builtin/interpret-trailers.c into trailer.c
> - and expose it via trailer.h.
> -
> - This lets other call sites reuse the same trailer rewriting logic.
> + 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 <me@linux.beauty>
> + Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
>
> ## builtin/interpret-trailers.c ##
> +@@ builtin/interpret-trailers.c: 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) {
> @@ builtin/interpret-trailers.c: static void read_input_file(struct strbuf *sb, const char *file)
> strbuf_complete_line(sb);
> }
> @@ builtin/interpret-trailers.c: static void read_input_file(struct strbuf *sb, con
> static void interpret_trailers(const struct process_trailer_options *opts,
> struct list_head *new_trailer_head,
> const char *file)
> +@@ builtin/interpret-trailers.c: 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;
>
> ## trailer.c ##
> +@@
> + #include "commit.h"
> + #include "trailer.h"
> + #include "list.h"
> ++#include "tempfile.h"
> ++
> + /*
> + * Copyright (c) 2013, 2014 Christian Couder <chriscool@tuxfamily.org>
> + */
> +@@ trailer.c: 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;
> @@ trailer.c: 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);
> @@ trailer.h: 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);
> 3: 3114f0dbb57 ! 4: 1f24917eb64 trailer: append trailers without fork/exec
> @@ Commit message
>
> Update amend_file_with_trailers() to use the in-process helper and
> rewrite the target file via tempfile+rename, preserving the previous
> - in-place semantics.
> + in-place semantics. As the trailers are no longer added in a separate
> + process and trailer_config_init() die()s on missing config values it
> + is called early on in cmd_commit() and cmd_tag() so that they die()
> + early before writing the message file. The trailer arguments are now
> + also sanity checked.
>
> Keep existing callers unchanged by continuing to accept argv-style
> --trailer=<trailer> entries and stripping the prefix before feeding the
> in-process implementation.
>
> Signed-off-by: Li Chen <me@linux.beauty>
> + Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
> -
> - ## builtin/interpret-trailers.c ##
> -@@ builtin/interpret-trailers.c: static void interpret_trailers(const struct process_trailer_options *opts,
> - struct strbuf out = STRBUF_INIT;
> - FILE *outfile = stdout;
> -
> -- trailer_config_init();
> --
> - read_input_file(&input, file);
> -
> - if (opts->in_place)
> -@@ builtin/interpret-trailers.c: int cmd_interpret_trailers(int argc,
> - git_interpret_trailers_usage,
> - options);
> -
> -+ trailer_config_init();
> -+
> - if (argc) {
> - int i;
> - for (i = 0; i < argc; i++)
> + Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
> +
> + ## builtin/commit.c ##
> +@@ builtin/commit.c: int cmd_commit(int argc,
> + argc = parse_and_validate_options(argc, argv, builtin_commit_options,
> + builtin_commit_usage,
> + prefix, current_head, &s);
> ++ if (trailer_args.nr)
> ++ trailer_config_init();
> ++
> + if (verbose == -1)
> + verbose = (config_commit_verbose < 0) ? 0 : config_commit_verbose;
> +
> +
> + ## builtin/tag.c ##
> +@@ builtin/tag.c: int cmd_tag(int argc,
> + if (cmdmode == 'l')
> + setup_auto_pager("tag", 1);
> +
> ++ if (trailer_args.nr)
> ++ trailer_config_init();
> ++
> + if (opt.sign == -1)
> + opt.sign = cmdmode ? 0 : config_sign_tag > 0;
> +
>
> ## trailer.c ##
> @@
> #include "string-list.h"
> #include "run-command.h"
> #include "commit.h"
> +#include "strvec.h"
> -+#include "tempfile.h"
> #include "trailer.h"
> #include "list.h"
> -+
> - /*
> - * Copyright (c) 2013, 2014 Christian Couder <chriscool@tuxfamily.org>
> - */
> + #include "tempfile.h"
> @@ trailer.c: void parse_trailers_from_command_line_args(struct list_head *arg_head,
> free(cl_separators);
> }
>
> -+void validate_trailer_args(const struct strvec *cli_args)
> ++int validate_trailer_args(const struct strvec *cli_args)
> +{
> + char *cl_separators;
> ++ int ret = 0;
> +
> + trailer_config_init();
> +
> @@ trailer.c: void parse_trailers_from_command_line_args(struct list_head *arg_head
> + const char *txt = cli_args->v[i];
> + ssize_t separator_pos;
> +
> -+ if (!*txt)
> -+ die(_("empty --trailer argument"));
> -+
> ++ if (!*txt) {
> ++ ret = error(_("empty --trailer argument"));
> ++ goto out;
> ++ }
> + separator_pos = find_separator(txt, cl_separators);
> -+ if (separator_pos == 0)
> -+ die(_("invalid trailer '%s': missing key before separator"),
> -+ txt);
> ++ if (separator_pos == 0) {
> ++ ret = error(_("invalid trailer '%s': missing key before separator"),
> ++ txt);
> ++ goto out;
> ++ }
> + }
> -+
> ++out:
> + free(cl_separators);
> ++ return ret;
> +}
> +
> static const char *next_line(const char *str)
> {
> const char *nl = strchrnul(str, '\n');
> -@@ trailer.c: void trailer_iterator_release(struct trailer_iterator *iter)
> - strbuf_release(&iter->key);
> +@@ trailer.c: struct tempfile *trailer_create_in_place_tempfile(const char *file)
> + return tempfile;
> }
>
> -int amend_file_with_trailers(const char *path, const struct strvec *trailer_args)
> @@ trailer.c: void trailer_iterator_release(struct trailer_iterator *iter)
> - path, NULL);
> - strvec_pushv(&run_trailer.args, trailer_args->v);
> - return run_command(&run_trailer);
> -+static void new_trailer_items_clear(struct list_head *items)
> -+{
> -+ while (!list_empty(items)) {
> -+ struct new_trailer_item *item =
> -+ list_first_entry(items, struct new_trailer_item, list);
> -+ list_del(&item->list);
> -+ free(item);
> -+ }
> -+}
> -+
> -+void amend_strbuf_with_trailers(struct strbuf *buf,
> ++int amend_strbuf_with_trailers(struct strbuf *buf,
> + const struct strvec *trailer_args)
> +{
> + struct process_trailer_options opts = PROCESS_TRAILER_OPTIONS_INIT;
> + LIST_HEAD(new_trailer_head);
> + struct strbuf out = STRBUF_INIT;
> + size_t i;
> ++ int ret = 0;
> +
> + opts.no_divider = 1;
> +
> + for (i = 0; i < trailer_args->nr; i++) {
> + const char *text = trailer_args->v[i];
> + struct new_trailer_item *item;
> +
> -+ if (!*text)
> -+ die(_("empty --trailer argument"));
> ++ if (!*text) {
> ++ ret = error(_("empty --trailer argument"));
> ++ goto out;
> ++ }
> + item = xcalloc(1, sizeof(*item));
> -+ item->text = text;
> ++ item->text = xstrdup(text);
> + list_add_tail(&item->list, &new_trailer_head);
> + }
> +
> -+ trailer_config_init();
> + process_trailers(&opts, &new_trailer_head, buf, &out);
> +
> + strbuf_swap(buf, &out);
> ++out:
> + strbuf_release(&out);
> ++ free_trailers(&new_trailer_head);
> +
> -+ new_trailer_items_clear(&new_trailer_head);
> ++ return ret;
> +}
> +
> +static int write_file_in_place(const char *path, const struct strbuf *buf)
> +{
> -+ struct stat st;
> -+ struct strbuf filename_template = STRBUF_INIT;
> -+ const char *tail;
> -+ struct tempfile *tempfile;
> -+ FILE *outfile;
> -+
> -+ if (stat(path, &st))
> -+ return error_errno(_("could not stat %s"), path);
> -+ if (!S_ISREG(st.st_mode))
> -+ return error(_("file %s is not a regular file"), path);
> -+ if (!(st.st_mode & S_IWUSR))
> -+ return error(_("file %s is not writable by user"), path);
> -+
> -+ /* Create temporary file in the same directory as the original */
> -+ tail = strrchr(path, '/');
> -+ if (tail)
> -+ strbuf_add(&filename_template, path, tail - path + 1);
> -+ strbuf_addstr(&filename_template, "git-interpret-trailers-XXXXXX");
> -+
> -+ tempfile = mks_tempfile_sm(filename_template.buf, 0, st.st_mode);
> -+ strbuf_release(&filename_template);
> ++ struct tempfile *tempfile = trailer_create_in_place_tempfile(path);
> + if (!tempfile)
> -+ return error_errno(_("could not create temporary file"));
> -+
> -+ outfile = fdopen_tempfile(tempfile, "w");
> -+ if (!outfile) {
> -+ int saved_errno = errno;
> -+ delete_tempfile(&tempfile);
> -+ errno = saved_errno;
> -+ return error_errno(_("could not open temporary file"));
> -+ }
> -+
> -+ if (buf->len && fwrite(buf->buf, 1, buf->len, outfile) < buf->len) {
> -+ int saved_errno = errno;
> -+ delete_tempfile(&tempfile);
> -+ errno = saved_errno;
> ++ return -1;
> ++
> ++ if (write_in_full(tempfile->fd, buf->buf, buf->len) < 0)
> + return error_errno(_("could not write to temporary file"));
> -+ }
> +
> + if (rename_tempfile(&tempfile, path))
> + return error_errno(_("could not rename temporary file to %s"), path);
> @@ trailer.c: void trailer_iterator_release(struct trailer_iterator *iter)
> + * in-process implementation.
> + */
> + skip_prefix(txt, "--trailer=", &txt);
> -+ if (!*txt)
> -+ die(_("empty --trailer argument"));
> ++ if (!*txt) {
> ++ ret = error(_("empty --trailer argument"));
> ++ goto out;
> ++ }
> + strvec_push(&stripped_trailer_args, txt);
> + }
> +
> ++ if (validate_trailer_args(&stripped_trailer_args)) {
> ++ ret = -1;
> ++ goto out;
> ++ }
> + if (strbuf_read_file(&buf, path, 0) < 0)
> + ret = error_errno(_("could not read '%s'"), path);
> + else
> + amend_strbuf_with_trailers(&buf, &stripped_trailer_args);
> +
> + if (!ret)
> + ret = write_file_in_place(path, &buf);
> -+
> ++out:
> + strvec_clear(&stripped_trailer_args);
> + strbuf_release(&buf);
> + return ret;
> @@ trailer.h: void parse_trailers_from_config(struct list_head *config_head);
> void parse_trailers_from_command_line_args(struct list_head *arg_head,
> struct list_head *new_trailer_head);
>
> -+void validate_trailer_args(const struct strvec *cli_args);
> ++int validate_trailer_args(const struct strvec *cli_args);
> +
> void process_trailers_lists(struct list_head *head,
> struct list_head *arg_head);
> @@ trailer.h: int trailer_iterator_advance(struct trailer_iterator *iter);
> + * Each element of trailer_args should be in the same format as the value
> + * accepted by --trailer=<trailer> (i.e., without the --trailer= prefix).
> + */
> -+void amend_strbuf_with_trailers(struct strbuf *buf,
> ++int amend_strbuf_with_trailers(struct strbuf *buf,
> + const struct strvec *trailer_args);
> +
> +/*
> @@ trailer.h: int trailer_iterator_advance(struct trailer_iterator *iter);
> */
> int amend_file_with_trailers(const char *path, const struct strvec *trailer_args);
>
> -+/*
> -+ * 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);
> 4: 147595a9317 ! 5: 3c1fa9e8579 commit, tag: parse --trailer with OPT_STRVEC
> @@ Commit message
> amend_file_with_trailers().
>
> Signed-off-by: Li Chen <me@linux.beauty>
>
> ## builtin/commit.c ##
> @@ builtin/commit.c: int cmd_commit(int argc,
> @@ trailer.c: int amend_file_with_trailers(const char *path,
> - * in-process implementation.
> - */
> - skip_prefix(txt, "--trailer=", &txt);
> -- if (!*txt)
> -- die(_("empty --trailer argument"));
> +- if (!*txt) {
> +- ret = error(_("empty --trailer argument"));
> +- goto out;
> +- }
> - strvec_push(&stripped_trailer_args, txt);
> - }
> -
> +- if (validate_trailer_args(&stripped_trailer_args)) {
> ++ if (validate_trailer_args(trailer_args)) {
> + ret = -1;
> + goto out;
> + }
> if (strbuf_read_file(&buf, path, 0) < 0)
> ret = error_errno(_("could not read '%s'"), path);
> else
> @@ trailer.c: int amend_file_with_trailers(const char *path,
>
> if (!ret)
> ret = write_file_in_place(path, &buf);
> -
> + out:
> - strvec_clear(&stripped_trailer_args);
> strbuf_release(&buf);
> return ret;
> }
>
> ## trailer.h ##
> -@@ trailer.h: void amend_strbuf_with_trailers(struct strbuf *buf,
> +@@ trailer.h: int amend_strbuf_with_trailers(struct strbuf *buf,
> /*
> * Augment a file by appending trailers specified in trailer_args.
> *
> 5: 864cf5f8eb6 ! 6: 99654d80547 rebase: support --trailer
> @@ Commit message
> non-interactive and interactive rebases.
>
> Signed-off-by: Li Chen <me@linux.beauty>
> + Signed-off-by: Phillip Wood <phillip.wood@dunelm.org.uk>
>
> ## Documentation/git-rebase.adoc ##
> @@ Documentation/git-rebase.adoc: See also INCOMPATIBLE OPTIONS below.
> @@ Documentation/git-rebase.adoc: See also INCOMPATIBLE OPTIONS below.
> +--trailer=<trailer>::
> + Append the given trailer to every rebased commit message, processed
> + via linkgit:git-interpret-trailers[1]. This option implies
> -+ `--force-rebase` so that fast-forwarded commits are also rewritten.
> ++ `--force-rebase`.
> ++
> +See also INCOMPATIBLE OPTIONS below.
> +
> -i::
> --interactive::
> Make a list of the commits which are about to be rebased. Let the
> +@@ Documentation/git-rebase.adoc: are incompatible with the following options:
> + * --[no-]reapply-cherry-picks when used without --keep-base
> + * --update-refs
> + * --root when used without --onto
> ++ * --trailer
> +
> + In addition, the following pairs of options are incompatible:
> +
>
> ## builtin/rebase.c ##
> @@
> @@ builtin/rebase.c: int cmd_rebase(int argc,
> builtin_rebase_usage, 0);
>
> + if (options.trailer_args.nr) {
> -+ validate_trailer_args(&options.trailer_args);
> ++ if (validate_trailer_args(&options.trailer_args))
> ++ die(NULL);
> + options.flags |= REBASE_FORCE;
> + }
> +
> @@ sequencer.c: void replay_opts_release(struct replay_opts *opts)
> free(opts->ctx);
> }
> @@ sequencer.c: static int append_squash_message(struct strbuf *buf, const char *body,
> + if (is_fixup_flag(command, flag) && !seen_squash(ctx)) {
> + /*
> + * We're replacing the commit message so we need to
> +- * append the Signed-off-by: trailer if the user
> +- * requested '--signoff'.
> ++ * append any trailers if the user requested
> ++ * '--signoff' or '--trailer'.
> + */
> if (opts->signoff)
> append_signoff(buf, 0, 0);
>
> @@ sequencer.c: static int do_pick_commit(struct repository *r,
> if (is_rebase_i(opts) && write_author_script(msg.message) < 0)
> res = -1;
> else if (!opts->strategy ||
> +@@ sequencer.c: static void read_strategy_opts(struct replay_opts *opts, struct strbuf *buf)
> + parse_strategy_opts(opts, buf->buf);
> + }
> +
> ++static int read_trailers(struct replay_opts *opts, struct strbuf *buf)
> ++{
> ++ ssize_t len;
> ++
> ++ strbuf_reset(buf);
> ++ len = strbuf_read_file(buf, rebase_path_trailer(), 0);
> ++ if (len > 0) {
> ++ char *p = buf->buf, *nl;
> ++
> ++ trailer_config_init();
> ++
> ++ while ((nl = strchr(p, '\n'))) {
> ++ *nl = '\0';
> ++ if (!*p)
> ++ return error(_("trailers file contains empty line"));
> ++ strvec_push(&opts->trailer_args, p);
> ++ p = nl + 1;
> ++ }
> ++ } else if (!len) {
> ++ return error(_("trailers file is empty"));
> ++ } else if (errno != ENOENT) {
> ++ return error(_("cannot read trailers files"));
> ++ }
> ++
> ++ return 0;
> ++}
> ++
> + static int read_populate_opts(struct replay_opts *opts)
> + {
> + struct replay_ctx *ctx = opts->ctx;
> @@ sequencer.c: static int read_populate_opts(struct replay_opts *opts)
> + opts->keep_redundant_commits = 1;
>
> read_strategy_opts(opts, &buf);
> ++
> ++ if (read_trailers(opts, &buf)) {
> ++ ret = -1;
> ++ goto done_rebase_i;
> ++ }
> strbuf_reset(&buf);
> -+ if (strbuf_read_file(&buf, rebase_path_trailer(), 0) >= 0) {
> -+ char *p = buf.buf, *nl;
> -+
> -+ while ((nl = strchr(p, '\n'))) {
> -+ *nl = '\0';
> -+ if (!*p)
> -+ BUG("rebase-merge/trailer has an empty line");
> -+ strvec_push(&opts->trailer_args, p);
> -+ p = nl + 1;
> -+ }
> -+ strbuf_reset(&buf);
> -+ }
>
> if (read_oneliner(&ctx->current_fixups,
> - rebase_path_current_fixups(),
> @@ sequencer.c: int write_basic_state(struct replay_opts *opts, const char *head_name,
> write_file(rebase_path_reschedule_failed_exec(), "%s", "");
> else
>
>
next prev parent reply other threads:[~2026-03-05 13:49 UTC|newest]
Thread overview: 32+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-02-24 7:05 [PATCH v7 0/5] rebase: support --trailer Li Chen
2026-02-24 7:05 ` [PATCH v7 1/5] interpret-trailers: factor trailer rewriting Li Chen
2026-03-02 14:56 ` Phillip Wood
2026-03-02 15:00 ` Li Chen
2026-02-24 7:05 ` [PATCH v7 2/5] trailer: move process_trailers to trailer.h Li Chen
2026-03-02 14:56 ` phillip.wood123
2026-02-24 7:05 ` [PATCH v7 3/5] trailer: append trailers without fork/exec Li Chen
2026-03-02 14:56 ` Phillip Wood
2026-02-24 7:05 ` [PATCH v7 4/5] commit, tag: parse --trailer with OPT_STRVEC Li Chen
2026-03-02 14:56 ` Phillip Wood
2026-02-24 7:05 ` [PATCH v7 5/5] rebase: support --trailer Li Chen
2026-03-03 15:05 ` Phillip Wood
2026-03-03 20:36 ` Kristoffer Haugsbakk
2026-03-03 21:18 ` Junio C Hamano
2026-03-04 15:53 ` Phillip Wood
2026-03-04 17:22 ` Junio C Hamano
2026-02-26 16:52 ` [PATCH v7 0/5] " Junio C Hamano
2026-02-26 18:15 ` Phillip Wood
2026-02-26 21:12 ` Kristoffer Haugsbakk
2026-03-04 14:29 ` Phillip Wood
2026-03-05 13:49 ` Li Chen [this message]
2026-03-06 14:55 ` Phillip Wood
2026-03-06 14:53 ` [PATCH v8 0/6] " Phillip Wood
2026-03-06 14:53 ` [PATCH v8 1/6] interpret-trailers: factor trailer rewriting Phillip Wood
2026-03-06 21:04 ` Junio C Hamano
2026-03-09 10:36 ` Phillip Wood
2026-03-06 14:53 ` [PATCH v8 2/6] interpret-trailers: refactor create_in_place_tempfile() Phillip Wood
2026-03-06 21:05 ` Junio C Hamano
2026-03-06 14:53 ` [PATCH v8 3/6] trailer: libify a couple of functions Phillip Wood
2026-03-06 14:53 ` [PATCH v8 4/6] trailer: append trailers without fork/exec Phillip Wood
2026-03-06 14:53 ` [PATCH v8 5/6] commit, tag: parse --trailer with OPT_STRVEC Phillip Wood
2026-03-06 14:53 ` [PATCH v8 6/6] rebase: support --trailer Phillip Wood
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=19cbe42b2cd.bb6e3883730656.6495265672263159010@linux.beauty \
--to=me@linux.beauty \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=kristofferhaugsbakk@fastmail.com \
--cc=phillip.wood@dunelm.org.uk \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox