From: Phillip Wood <phillip.wood123@gmail.com>
To: Git Mailing List <git@vger.kernel.org>, Li Chen <me@linux.beauty>
Cc: Kristoffer Haugsbakk <kristofferhaugsbakk@fastmail.com>,
Junio C Hamano <gitster@pobox.com>,
Phillip Wood <phillip.wood@dunelm.org.uk>
Subject: [PATCH v8 0/6] rebase: support --trailer
Date: Fri, 6 Mar 2026 14:53:26 +0000 [thread overview]
Message-ID: <cover.1772808594.git.phillip.wood@dunelm.org.uk> (raw)
In-Reply-To: <20260224070552.148591-1-me@linux.beauty>
From: Phillip Wood <phillip.wood@dunelm.org.uk>
This series adds support for creating trailers when rebasing, along
the lines of "git commit --trailer". Patches 1-3 refactor and libify
the code to add trailers to a buffer, patches 4,5 update "git commit
--trailer" and "git tag --trailer" to use the new code and the last
patch adds support for "git rebase --trailer".
Thanks to Li for working on this series, the main change in this
hopefully final iteration is that more code is shared between "git
interpret-trailers" and the builtin commands that add trailers via
a --trailer option, see the range-diff for patches 2-4.
Changes since V7:
- Patch 1: Added missing sign-off.
- Patch 2: New, refactor create_in_place_tempfile() in preparation for
moving it.
- Patch 3: Move create_in_place_tempfile() in addition to
process_trailers().
- Patch 4: Use the libified create_in_place_tempfile(), initialize
trailer config earlier and validate --trailer args for
"git commit" and "git tag". Library code now calls error()
rather than die()
- Patch 5: Unchanged, apart from the effect of previous patches
- Patch 6: Small doc fixes, initialize trailer_config() when continuing
a rebase that was started with --trailer. Report errors when
reading trailer state file.
Li Chen (5):
interpret-trailers: factor trailer rewriting
trailer: libify a couple of functions
trailer: append trailers without fork/exec
commit, tag: parse --trailer with OPT_STRVEC
rebase: support --trailer
Phillip Wood (1):
interpret-trailers: refactor create_in_place_tempfile()
Documentation/git-rebase.adoc | 8 ++
builtin/commit.c | 6 +-
builtin/interpret-trailers.c | 91 ++++-------------
builtin/rebase.c | 19 ++++
builtin/tag.c | 7 +-
sequencer.c | 52 +++++++++-
sequencer.h | 3 +
t/meson.build | 1 +
t/t3440-rebase-trailer.sh | 147 +++++++++++++++++++++++++++
trailer.c | 184 ++++++++++++++++++++++++++++++++--
trailer.h | 36 ++++++-
11 files changed, 463 insertions(+), 91 deletions(-)
create mode 100755 t/t3440-rebase-trailer.sh
Range-diff:
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>
-
- ## 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
--
2.52.0.362.g884e03848a9
next prev parent reply other threads:[~2026-03-06 14:54 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
2026-03-06 14:55 ` Phillip Wood
2026-03-06 14:53 ` Phillip Wood [this message]
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=cover.1772808594.git.phillip.wood@dunelm.org.uk \
--to=phillip.wood123@gmail.com \
--cc=git@vger.kernel.org \
--cc=gitster@pobox.com \
--cc=kristofferhaugsbakk@fastmail.com \
--cc=me@linux.beauty \
--cc=phillip.wood@dunelm.org.uk \
--cc=phillip.wood@dunlem.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