diff options
| author | Junio C Hamano <gitster@pobox.com> | 2026-03-19 09:54:56 -0700 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2026-03-19 09:54:56 -0700 |
| commit | accd0e107bb36cbcdb158f8bb19d5bae589294a9 (patch) | |
| tree | 9c127dab3844830d92aaf884a0f1037d11d5a3c3 /builtin | |
| parent | a7a079c2c4bc7b269229a6ea6c147b6b2d5b2684 (diff) | |
| parent | e4f9d6b0ab2e1903765258991a6265599d0007ce (diff) | |
| download | git-accd0e107bb36cbcdb158f8bb19d5bae589294a9.tar.xz | |
Merge branch 'lc/rebase-trailer'
"git rebase" learns "--trailer" command to drive the
interpret-trailers machinery.
* lc/rebase-trailer:
rebase: support --trailer
commit, tag: parse --trailer with OPT_STRVEC
trailer: append trailers without fork/exec
trailer: libify a couple of functions
interpret-trailers: refactor create_in_place_tempfile()
interpret-trailers: factor trailer rewriting
Diffstat (limited to 'builtin')
| -rw-r--r-- | builtin/commit.c | 6 | ||||
| -rw-r--r-- | builtin/interpret-trailers.c | 87 | ||||
| -rw-r--r-- | builtin/rebase.c | 19 | ||||
| -rw-r--r-- | builtin/tag.c | 7 |
4 files changed, 45 insertions, 74 deletions
diff --git a/builtin/commit.c b/builtin/commit.c index 7b23c1f883..02a04f68be 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -1720,7 +1720,8 @@ int cmd_commit(int argc, OPT_STRING(0, "fixup", &fixup_message, N_("[(amend|reword):]commit"), N_("use autosquash formatted message to fixup or amend/reword specified commit")), OPT_STRING(0, "squash", &squash_message, N_("commit"), N_("use autosquash formatted message to squash specified commit")), OPT_BOOL(0, "reset-author", &renew_authorship, N_("the commit is authored by me now (used with -C/-c/--amend)")), - OPT_PASSTHRU_ARGV(0, "trailer", &trailer_args, N_("trailer"), N_("add custom trailer(s)"), PARSE_OPT_NONEG), + OPT_STRVEC(0, "trailer", &trailer_args, N_("trailer"), + N_("add custom trailer(s)")), OPT_BOOL('s', "signoff", &signoff, N_("add a Signed-off-by trailer")), OPT_FILENAME('t', "template", &template_file, N_("use specified template file")), OPT_BOOL('e', "edit", &edit_flag, N_("force edit of commit")), @@ -1820,6 +1821,9 @@ 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; diff --git a/builtin/interpret-trailers.c b/builtin/interpret-trailers.c index 41b0750e5a..acaf42b2d9 100644 --- a/builtin/interpret-trailers.c +++ b/builtin/interpret-trailers.c @@ -93,37 +93,6 @@ static int parse_opt_parse(const struct option *opt, const char *arg, return 0; } -static struct tempfile *trailers_tempfile; - -static FILE *create_in_place_tempfile(const char *file) -{ - struct stat st; - struct strbuf filename_template = STRBUF_INIT; - const char *tail; - FILE *outfile; - - if (stat(file, &st)) - die_errno(_("could not stat %s"), file); - if (!S_ISREG(st.st_mode)) - die(_("file %s is not a regular file"), file); - if (!(st.st_mode & S_IWUSR)) - die(_("file %s is not writable by user"), file); - - /* Create temporary file in the same directory as the original */ - tail = strrchr(file, '/'); - if (tail) - strbuf_add(&filename_template, file, tail - file + 1); - strbuf_addstr(&filename_template, "git-interpret-trailers-XXXXXX"); - - trailers_tempfile = xmks_tempfile_m(filename_template.buf, st.st_mode); - strbuf_release(&filename_template); - outfile = fdopen_tempfile(trailers_tempfile, "w"); - if (!outfile) - die_errno(_("could not open temporary file")); - - return outfile; -} - static void read_input_file(struct strbuf *sb, const char *file) { if (file) { @@ -140,55 +109,31 @@ static void interpret_trailers(const struct process_trailer_options *opts, struct list_head *new_trailer_head, const char *file) { - LIST_HEAD(head); - struct strbuf sb = STRBUF_INIT; - struct strbuf trailer_block_sb = STRBUF_INIT; - struct trailer_block *trailer_block; - FILE *outfile = stdout; + struct strbuf input = STRBUF_INIT; + struct strbuf out = STRBUF_INIT; + struct tempfile *tempfile = NULL; + int fd = 1; trailer_config_init(); - read_input_file(&sb, file); + read_input_file(&input, file); - if (opts->in_place) - outfile = create_in_place_tempfile(file); - - trailer_block = parse_trailers(opts, sb.buf, &head); - - /* Print the lines before the trailer block */ - if (!opts->only_trailers) - fwrite(sb.buf, 1, trailer_block_start(trailer_block), outfile); - - if (!opts->only_trailers && !blank_line_before_trailer_block(trailer_block)) - fprintf(outfile, "\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); + if (opts->in_place) { + tempfile = trailer_create_in_place_tempfile(file); + if (!tempfile) + die(NULL); + fd = tempfile->fd; } + process_trailers(opts, new_trailer_head, &input, &out); - /* Print trailer block. */ - format_trailers(opts, &head, &trailer_block_sb); - free_trailers(&head); - fwrite(trailer_block_sb.buf, 1, trailer_block_sb.len, outfile); - strbuf_release(&trailer_block_sb); - - /* Print the lines after the trailer block as is. */ - if (!opts->only_trailers) - fwrite(sb.buf + trailer_block_end(trailer_block), 1, - sb.len - trailer_block_end(trailer_block), outfile); - trailer_block_release(trailer_block); - + if (write_in_full(fd, out.buf, out.len) < 0) + die_errno(_("could not write to temporary file '%s'"), file); if (opts->in_place) - if (rename_tempfile(&trailers_tempfile, file)) + if (rename_tempfile(&tempfile, file)) die_errno(_("could not rename temporary file to %s"), file); - strbuf_release(&sb); + strbuf_release(&input); + strbuf_release(&out); } int cmd_interpret_trailers(int argc, diff --git a/builtin/rebase.c b/builtin/rebase.c index 8c1316db38..a1c7d78196 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -36,6 +36,7 @@ #include "reset.h" #include "trace2.h" #include "hook.h" +#include "trailer.h" static char const * const builtin_rebase_usage[] = { N_("git rebase [-i] [options] [--exec <cmd>] " @@ -113,6 +114,7 @@ struct rebase_options { enum action action; char *reflog_action; int signoff; + struct strvec trailer_args; int allow_rerere_autoupdate; int keep_empty; int autosquash; @@ -143,6 +145,7 @@ struct rebase_options { .flags = REBASE_NO_QUIET, \ .git_am_opts = STRVEC_INIT, \ .exec = STRING_LIST_INIT_NODUP, \ + .trailer_args = STRVEC_INIT, \ .git_format_patch_opt = STRBUF_INIT, \ .fork_point = -1, \ .reapply_cherry_picks = -1, \ @@ -166,6 +169,7 @@ static void rebase_options_release(struct rebase_options *opts) free(opts->strategy); string_list_clear(&opts->strategy_opts, 0); strbuf_release(&opts->git_format_patch_opt); + strvec_clear(&opts->trailer_args); } static struct replay_opts get_replay_opts(const struct rebase_options *opts) @@ -177,6 +181,10 @@ static struct replay_opts get_replay_opts(const struct rebase_options *opts) sequencer_init_config(&replay); replay.signoff = opts->signoff; + + for (size_t i = 0; i < opts->trailer_args.nr; i++) + strvec_push(&replay.trailer_args, opts->trailer_args.v[i]); + replay.allow_ff = !(opts->flags & REBASE_FORCE); if (opts->allow_rerere_autoupdate) replay.allow_rerere_auto = opts->allow_rerere_autoupdate; @@ -1134,6 +1142,8 @@ int cmd_rebase(int argc, .flags = PARSE_OPT_NOARG, .defval = REBASE_DIFFSTAT, }, + OPT_STRVEC(0, "trailer", &options.trailer_args, N_("trailer"), + N_("add custom trailer(s)")), OPT_BOOL(0, "signoff", &options.signoff, N_("add a Signed-off-by trailer to each commit")), OPT_BOOL(0, "committer-date-is-author-date", @@ -1287,6 +1297,12 @@ int cmd_rebase(int argc, builtin_rebase_options, builtin_rebase_usage, 0); + if (options.trailer_args.nr) { + if (validate_trailer_args(&options.trailer_args)) + die(NULL); + options.flags |= REBASE_FORCE; + } + if (preserve_merges_selected) die(_("--preserve-merges was replaced by --rebase-merges\n" "Note: Your `pull.rebase` configuration may also be set to 'preserve',\n" @@ -1544,6 +1560,9 @@ int cmd_rebase(int argc, if (options.root && !options.onto_name) imply_merge(&options, "--root without --onto"); + if (options.trailer_args.nr) + imply_merge(&options, "--trailer"); + if (isatty(2) && options.flags & REBASE_NO_QUIET) strbuf_addstr(&options.git_format_patch_opt, " --progress"); diff --git a/builtin/tag.c b/builtin/tag.c index aeb04c487f..e0f05f94fd 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -499,8 +499,8 @@ int cmd_tag(int argc, OPT_CALLBACK_F('m', "message", &msg, N_("message"), N_("tag message"), PARSE_OPT_NONEG, parse_msg_arg), OPT_FILENAME('F', "file", &msgfile, N_("read message from file")), - OPT_PASSTHRU_ARGV(0, "trailer", &trailer_args, N_("trailer"), - N_("add custom trailer(s)"), PARSE_OPT_NONEG), + OPT_STRVEC(0, "trailer", &trailer_args, N_("trailer"), + N_("add custom trailer(s)")), OPT_BOOL('e', "edit", &edit_flag, N_("force edit of tag message")), OPT_BOOL('s', "sign", &opt.sign, N_("annotated and GPG-signed tag")), OPT_CLEANUP(&cleanup_arg), @@ -568,6 +568,9 @@ 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; |
