Merge branch 'jp/tag-trailer'
"git tag" learned the "--trailer" option to futz with the trailers in the same way as "git commit" does. * jp/tag-trailer: builtin/tag: add --trailer option builtin/commit: refactor --trailer logic builtin/commit: use ARGV macro to collect trailersmaint
commit
f9d4eaf86c
|
@ -10,6 +10,7 @@ SYNOPSIS
|
||||||
--------
|
--------
|
||||||
[verse]
|
[verse]
|
||||||
'git tag' [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] [-e]
|
'git tag' [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] [-e]
|
||||||
|
[(--trailer <token>[(=|:)<value>])...]
|
||||||
<tagname> [<commit> | <object>]
|
<tagname> [<commit> | <object>]
|
||||||
'git tag' -d <tagname>...
|
'git tag' -d <tagname>...
|
||||||
'git tag' [-n[<num>]] -l [--contains <commit>] [--no-contains <commit>]
|
'git tag' [-n[<num>]] -l [--contains <commit>] [--no-contains <commit>]
|
||||||
|
@ -31,8 +32,8 @@ creates a 'tag' object, and requires a tag message. Unless
|
||||||
`-m <msg>` or `-F <file>` is given, an editor is started for the user to type
|
`-m <msg>` or `-F <file>` is given, an editor is started for the user to type
|
||||||
in the tag message.
|
in the tag message.
|
||||||
|
|
||||||
If `-m <msg>` or `-F <file>` is given and `-a`, `-s`, and `-u <key-id>`
|
If `-m <msg>` or `-F <file>` or `--trailer <token>[=<value>]` is given
|
||||||
are absent, `-a` is implied.
|
and `-a`, `-s`, and `-u <key-id>` are absent, `-a` is implied.
|
||||||
|
|
||||||
Otherwise, a tag reference that points directly at the given object
|
Otherwise, a tag reference that points directly at the given object
|
||||||
(i.e., a lightweight tag) is created.
|
(i.e., a lightweight tag) is created.
|
||||||
|
@ -178,6 +179,17 @@ This option is only applicable when listing tags without annotation lines.
|
||||||
Implies `-a` if none of `-a`, `-s`, or `-u <key-id>`
|
Implies `-a` if none of `-a`, `-s`, or `-u <key-id>`
|
||||||
is given.
|
is given.
|
||||||
|
|
||||||
|
--trailer <token>[(=|:)<value>]::
|
||||||
|
Specify a (<token>, <value>) pair that should be applied as a
|
||||||
|
trailer. (e.g. `git tag --trailer "Custom-Key: value"`
|
||||||
|
will add a "Custom-Key" trailer to the tag message.)
|
||||||
|
The `trailer.*` configuration variables
|
||||||
|
(linkgit:git-interpret-trailers[1]) can be used to define if
|
||||||
|
a duplicated trailer is omitted, where in the run of trailers
|
||||||
|
each trailer would appear, and other details.
|
||||||
|
The trailers can be extracted in `git tag --list`, using
|
||||||
|
`--format="%(trailers)"` placeholder.
|
||||||
|
|
||||||
-e::
|
-e::
|
||||||
--edit::
|
--edit::
|
||||||
The message taken from file with `-F` and command line with
|
The message taken from file with `-F` and command line with
|
||||||
|
|
|
@ -37,6 +37,7 @@
|
||||||
#include "commit-reach.h"
|
#include "commit-reach.h"
|
||||||
#include "commit-graph.h"
|
#include "commit-graph.h"
|
||||||
#include "pretty.h"
|
#include "pretty.h"
|
||||||
|
#include "trailer.h"
|
||||||
|
|
||||||
static const char * const builtin_commit_usage[] = {
|
static const char * const builtin_commit_usage[] = {
|
||||||
N_("git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]\n"
|
N_("git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]\n"
|
||||||
|
@ -141,14 +142,6 @@ static struct strbuf message = STRBUF_INIT;
|
||||||
|
|
||||||
static enum wt_status_format status_format = STATUS_FORMAT_UNSPECIFIED;
|
static enum wt_status_format status_format = STATUS_FORMAT_UNSPECIFIED;
|
||||||
|
|
||||||
static int opt_pass_trailer(const struct option *opt, const char *arg, int unset)
|
|
||||||
{
|
|
||||||
BUG_ON_OPT_NEG(unset);
|
|
||||||
|
|
||||||
strvec_pushl(opt->value, "--trailer", arg, NULL);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int opt_parse_porcelain(const struct option *opt, const char *arg, int unset)
|
static int opt_parse_porcelain(const struct option *opt, const char *arg, int unset)
|
||||||
{
|
{
|
||||||
enum wt_status_format *value = (enum wt_status_format *)opt->value;
|
enum wt_status_format *value = (enum wt_status_format *)opt->value;
|
||||||
|
@ -1037,14 +1030,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix,
|
||||||
fclose(s->fp);
|
fclose(s->fp);
|
||||||
|
|
||||||
if (trailer_args.nr) {
|
if (trailer_args.nr) {
|
||||||
struct child_process run_trailer = CHILD_PROCESS_INIT;
|
if (amend_file_with_trailers(git_path_commit_editmsg(), &trailer_args))
|
||||||
|
|
||||||
strvec_pushl(&run_trailer.args, "interpret-trailers",
|
|
||||||
"--in-place", "--no-divider",
|
|
||||||
git_path_commit_editmsg(), NULL);
|
|
||||||
strvec_pushv(&run_trailer.args, trailer_args.v);
|
|
||||||
run_trailer.git_cmd = 1;
|
|
||||||
if (run_command(&run_trailer))
|
|
||||||
die(_("unable to pass trailers to --trailers"));
|
die(_("unable to pass trailers to --trailers"));
|
||||||
strvec_clear(&trailer_args);
|
strvec_clear(&trailer_args);
|
||||||
}
|
}
|
||||||
|
@ -1672,7 +1658,7 @@ int cmd_commit(int argc, const char **argv, const char *prefix)
|
||||||
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, "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_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_BOOL(0, "reset-author", &renew_authorship, N_("the commit is authored by me now (used with -C/-c/--amend)")),
|
||||||
OPT_CALLBACK_F(0, "trailer", &trailer_args, N_("trailer"), N_("add custom trailer(s)"), PARSE_OPT_NONEG, opt_pass_trailer),
|
OPT_PASSTHRU_ARGV(0, "trailer", &trailer_args, N_("trailer"), N_("add custom trailer(s)"), PARSE_OPT_NONEG),
|
||||||
OPT_BOOL('s', "signoff", &signoff, N_("add a Signed-off-by trailer")),
|
OPT_BOOL('s', "signoff", &signoff, N_("add a Signed-off-by trailer")),
|
||||||
OPT_FILENAME('t', "template", &template_file, N_("use specified template file")),
|
OPT_FILENAME('t', "template", &template_file, N_("use specified template file")),
|
||||||
OPT_BOOL('e', "edit", &edit_flag, N_("force edit of commit")),
|
OPT_BOOL('e', "edit", &edit_flag, N_("force edit of commit")),
|
||||||
|
|
|
@ -28,9 +28,11 @@
|
||||||
#include "date.h"
|
#include "date.h"
|
||||||
#include "write-or-die.h"
|
#include "write-or-die.h"
|
||||||
#include "object-file-convert.h"
|
#include "object-file-convert.h"
|
||||||
|
#include "trailer.h"
|
||||||
|
|
||||||
static const char * const git_tag_usage[] = {
|
static const char * const git_tag_usage[] = {
|
||||||
N_("git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] [-e]\n"
|
N_("git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] [-e]\n"
|
||||||
|
" [(--trailer <token>[(=|:)<value>])...]\n"
|
||||||
" <tagname> [<commit> | <object>]"),
|
" <tagname> [<commit> | <object>]"),
|
||||||
N_("git tag -d <tagname>..."),
|
N_("git tag -d <tagname>..."),
|
||||||
N_("git tag [-n[<num>]] -l [--contains <commit>] [--no-contains <commit>]\n"
|
N_("git tag [-n[<num>]] -l [--contains <commit>] [--no-contains <commit>]\n"
|
||||||
|
@ -290,10 +292,12 @@ static const char message_advice_nested_tag[] =
|
||||||
static void create_tag(const struct object_id *object, const char *object_ref,
|
static void create_tag(const struct object_id *object, const char *object_ref,
|
||||||
const char *tag,
|
const char *tag,
|
||||||
struct strbuf *buf, struct create_tag_options *opt,
|
struct strbuf *buf, struct create_tag_options *opt,
|
||||||
struct object_id *prev, struct object_id *result, char *path)
|
struct object_id *prev, struct object_id *result,
|
||||||
|
struct strvec *trailer_args, char *path)
|
||||||
{
|
{
|
||||||
enum object_type type;
|
enum object_type type;
|
||||||
struct strbuf header = STRBUF_INIT;
|
struct strbuf header = STRBUF_INIT;
|
||||||
|
int should_edit;
|
||||||
|
|
||||||
type = oid_object_info(the_repository, object, NULL);
|
type = oid_object_info(the_repository, object, NULL);
|
||||||
if (type <= OBJ_NONE)
|
if (type <= OBJ_NONE)
|
||||||
|
@ -313,13 +317,15 @@ static void create_tag(const struct object_id *object, const char *object_ref,
|
||||||
tag,
|
tag,
|
||||||
git_committer_info(IDENT_STRICT));
|
git_committer_info(IDENT_STRICT));
|
||||||
|
|
||||||
if (!opt->message_given || opt->use_editor) {
|
should_edit = opt->use_editor || !opt->message_given;
|
||||||
|
if (should_edit || trailer_args->nr) {
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
/* write the template message before editing: */
|
/* write the template message before editing: */
|
||||||
fd = xopen(path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
|
fd = xopen(path, O_CREAT | O_TRUNC | O_WRONLY, 0600);
|
||||||
|
|
||||||
if (opt->message_given) {
|
if (opt->message_given && buf->len) {
|
||||||
|
strbuf_complete(buf, '\n');
|
||||||
write_or_die(fd, buf->buf, buf->len);
|
write_or_die(fd, buf->buf, buf->len);
|
||||||
strbuf_reset(buf);
|
strbuf_reset(buf);
|
||||||
} else if (!is_null_oid(prev)) {
|
} else if (!is_null_oid(prev)) {
|
||||||
|
@ -338,11 +344,20 @@ static void create_tag(const struct object_id *object, const char *object_ref,
|
||||||
}
|
}
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
|
if (trailer_args->nr && amend_file_with_trailers(path, trailer_args))
|
||||||
|
die(_("unable to pass trailers to --trailers"));
|
||||||
|
|
||||||
|
if (should_edit) {
|
||||||
if (launch_editor(path, buf, NULL)) {
|
if (launch_editor(path, buf, NULL)) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
_("Please supply the message using either -m or -F option.\n"));
|
_("Please supply the message using either -m or -F option.\n"));
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
} else if (trailer_args->nr) {
|
||||||
|
strbuf_reset(buf);
|
||||||
|
if (strbuf_read_file(buf, path, 0) < 0)
|
||||||
|
die_errno(_("failed to read '%s'"), path);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (opt->cleanup_mode != CLEANUP_NONE)
|
if (opt->cleanup_mode != CLEANUP_NONE)
|
||||||
|
@ -463,6 +478,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
|
||||||
struct ref_sorting *sorting;
|
struct ref_sorting *sorting;
|
||||||
struct string_list sorting_options = STRING_LIST_INIT_DUP;
|
struct string_list sorting_options = STRING_LIST_INIT_DUP;
|
||||||
struct ref_format format = REF_FORMAT_INIT;
|
struct ref_format format = REF_FORMAT_INIT;
|
||||||
|
struct strvec trailer_args = STRVEC_INIT;
|
||||||
int icase = 0;
|
int icase = 0;
|
||||||
int edit_flag = 0;
|
int edit_flag = 0;
|
||||||
struct option options[] = {
|
struct option options[] = {
|
||||||
|
@ -479,6 +495,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
|
||||||
OPT_CALLBACK_F('m', "message", &msg, N_("message"),
|
OPT_CALLBACK_F('m', "message", &msg, N_("message"),
|
||||||
N_("tag message"), PARSE_OPT_NONEG, parse_msg_arg),
|
N_("tag message"), PARSE_OPT_NONEG, parse_msg_arg),
|
||||||
OPT_FILENAME('F', "file", &msgfile, N_("read message from file")),
|
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_BOOL('e', "edit", &edit_flag, N_("force edit of tag message")),
|
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_BOOL('s', "sign", &opt.sign, N_("annotated and GPG-signed tag")),
|
||||||
OPT_CLEANUP(&cleanup_arg),
|
OPT_CLEANUP(&cleanup_arg),
|
||||||
|
@ -548,7 +566,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
|
||||||
opt.sign = 1;
|
opt.sign = 1;
|
||||||
set_signing_key(keyid);
|
set_signing_key(keyid);
|
||||||
}
|
}
|
||||||
create_tag_object = (opt.sign || annotate || msg.given || msgfile);
|
create_tag_object = (opt.sign || annotate || msg.given || msgfile ||
|
||||||
|
edit_flag || trailer_args.nr);
|
||||||
|
|
||||||
if ((create_tag_object || force) && (cmdmode != 0))
|
if ((create_tag_object || force) && (cmdmode != 0))
|
||||||
usage_with_options(git_tag_usage, options);
|
usage_with_options(git_tag_usage, options);
|
||||||
|
@ -654,7 +673,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
|
||||||
opt.sign = 1;
|
opt.sign = 1;
|
||||||
path = git_pathdup("TAG_EDITMSG");
|
path = git_pathdup("TAG_EDITMSG");
|
||||||
create_tag(&object, object_ref, tag, &buf, &opt, &prev, &object,
|
create_tag(&object, object_ref, tag, &buf, &opt, &prev, &object,
|
||||||
path);
|
&trailer_args, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
transaction = ref_transaction_begin(&err);
|
transaction = ref_transaction_begin(&err);
|
||||||
|
@ -686,6 +705,7 @@ cleanup:
|
||||||
strbuf_release(&reflog_msg);
|
strbuf_release(&reflog_msg);
|
||||||
strbuf_release(&msg.buf);
|
strbuf_release(&msg.buf);
|
||||||
strbuf_release(&err);
|
strbuf_release(&err);
|
||||||
|
strvec_clear(&trailer_args);
|
||||||
free(msgfile);
|
free(msgfile);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
114
t/t7004-tag.sh
114
t/t7004-tag.sh
|
@ -668,6 +668,115 @@ test_expect_success \
|
||||||
test_cmp expect actual
|
test_cmp expect actual
|
||||||
'
|
'
|
||||||
|
|
||||||
|
# trailers
|
||||||
|
|
||||||
|
test_expect_success 'create tag with -m and --trailer' '
|
||||||
|
get_tag_header tag-with-inline-message-and-trailers $commit commit $time >expect &&
|
||||||
|
cat >>expect <<-\EOF &&
|
||||||
|
create tag with trailers
|
||||||
|
|
||||||
|
my-trailer: here
|
||||||
|
alt-trailer: there
|
||||||
|
EOF
|
||||||
|
git tag -m "create tag with trailers" \
|
||||||
|
--trailer my-trailer=here \
|
||||||
|
--trailer alt-trailer=there \
|
||||||
|
tag-with-inline-message-and-trailers &&
|
||||||
|
get_tag_msg tag-with-inline-message-and-trailers >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'list tag extracting trailers' '
|
||||||
|
cat >expect <<-\EOF &&
|
||||||
|
my-trailer: here
|
||||||
|
alt-trailer: there
|
||||||
|
|
||||||
|
EOF
|
||||||
|
git tag --list --format="%(trailers)" tag-with-inline-message-and-trailers >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'create tag with -F and --trailer' '
|
||||||
|
echo "create tag from message file using --trailer" >messagefilewithnotrailers &&
|
||||||
|
get_tag_header tag-with-file-message-and-trailers $commit commit $time >expect &&
|
||||||
|
cat >>expect <<-\EOF &&
|
||||||
|
create tag from message file using --trailer
|
||||||
|
|
||||||
|
my-trailer: here
|
||||||
|
alt-trailer: there
|
||||||
|
EOF
|
||||||
|
git tag -F messagefilewithnotrailers \
|
||||||
|
--trailer my-trailer=here \
|
||||||
|
--trailer alt-trailer=there \
|
||||||
|
tag-with-file-message-and-trailers &&
|
||||||
|
get_tag_msg tag-with-file-message-and-trailers >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'create tag with -m and --trailer and --edit' '
|
||||||
|
write_script fakeeditor <<-\EOF &&
|
||||||
|
sed -e "1s/^/EDITED: /g" <"$1" >"$1-"
|
||||||
|
mv "$1-" "$1"
|
||||||
|
EOF
|
||||||
|
get_tag_header tag-with-edited-inline-message-and-trailers $commit commit $time >expect &&
|
||||||
|
cat >>expect <<-\EOF &&
|
||||||
|
EDITED: create tag with trailers
|
||||||
|
|
||||||
|
my-trailer: here
|
||||||
|
alt-trailer: there
|
||||||
|
EOF
|
||||||
|
GIT_EDITOR=./fakeeditor git tag --edit \
|
||||||
|
-m "create tag with trailers" \
|
||||||
|
--trailer my-trailer=here \
|
||||||
|
--trailer alt-trailer=there \
|
||||||
|
tag-with-edited-inline-message-and-trailers &&
|
||||||
|
get_tag_msg tag-with-edited-inline-message-and-trailers >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'create tag with -F and --trailer and --edit' '
|
||||||
|
echo "create tag from message file using --trailer" >messagefilewithnotrailers &&
|
||||||
|
get_tag_header tag-with-edited-file-message-and-trailers $commit commit $time >expect &&
|
||||||
|
cat >>expect <<-\EOF &&
|
||||||
|
EDITED: create tag from message file using --trailer
|
||||||
|
|
||||||
|
my-trailer: here
|
||||||
|
alt-trailer: there
|
||||||
|
EOF
|
||||||
|
GIT_EDITOR=./fakeeditor git tag --edit \
|
||||||
|
-F messagefilewithnotrailers \
|
||||||
|
--trailer my-trailer=here \
|
||||||
|
--trailer alt-trailer=there \
|
||||||
|
tag-with-edited-file-message-and-trailers &&
|
||||||
|
get_tag_msg tag-with-edited-file-message-and-trailers >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'create annotated tag and force editor when only --trailer is given' '
|
||||||
|
write_script fakeeditor <<-\EOF &&
|
||||||
|
echo "add a line" >"$1-"
|
||||||
|
cat <"$1" >>"$1-"
|
||||||
|
mv "$1-" "$1"
|
||||||
|
EOF
|
||||||
|
get_tag_header tag-with-trailers-and-no-message $commit commit $time >expect &&
|
||||||
|
cat >>expect <<-\EOF &&
|
||||||
|
add a line
|
||||||
|
|
||||||
|
my-trailer: here
|
||||||
|
alt-trailer: there
|
||||||
|
EOF
|
||||||
|
GIT_EDITOR=./fakeeditor git tag \
|
||||||
|
--trailer my-trailer=here \
|
||||||
|
--trailer alt-trailer=there \
|
||||||
|
tag-with-trailers-and-no-message &&
|
||||||
|
get_tag_msg tag-with-trailers-and-no-message >actual &&
|
||||||
|
test_cmp expect actual
|
||||||
|
'
|
||||||
|
|
||||||
|
test_expect_success 'bad editor causes panic when only --trailer is given' '
|
||||||
|
test_must_fail env GIT_EDITOR=false git tag --trailer my-trailer=here tag-will-not-exist
|
||||||
|
'
|
||||||
|
|
||||||
# listing messages for annotated non-signed tags:
|
# listing messages for annotated non-signed tags:
|
||||||
|
|
||||||
test_expect_success \
|
test_expect_success \
|
||||||
|
@ -810,6 +919,11 @@ test_expect_success 'git tag --format with ahead-behind' '
|
||||||
refs/tags/tag-lines 0 1 !
|
refs/tags/tag-lines 0 1 !
|
||||||
refs/tags/tag-one-line 0 1 !
|
refs/tags/tag-one-line 0 1 !
|
||||||
refs/tags/tag-right 0 0 !
|
refs/tags/tag-right 0 0 !
|
||||||
|
refs/tags/tag-with-edited-file-message-and-trailers 0 1 !
|
||||||
|
refs/tags/tag-with-edited-inline-message-and-trailers 0 1 !
|
||||||
|
refs/tags/tag-with-file-message-and-trailers 0 1 !
|
||||||
|
refs/tags/tag-with-inline-message-and-trailers 0 1 !
|
||||||
|
refs/tags/tag-with-trailers-and-no-message 0 1 !
|
||||||
refs/tags/tag-zero-lines 0 1 !
|
refs/tags/tag-zero-lines 0 1 !
|
||||||
EOF
|
EOF
|
||||||
git tag -l --format="%(refname) %(ahead-behind:HEAD) !" >actual 2>err &&
|
git tag -l --format="%(refname) %(ahead-behind:HEAD) !" >actual 2>err &&
|
||||||
|
|
12
trailer.c
12
trailer.c
|
@ -1170,3 +1170,15 @@ void trailer_iterator_release(struct trailer_iterator *iter)
|
||||||
strbuf_release(&iter->val);
|
strbuf_release(&iter->val);
|
||||||
strbuf_release(&iter->key);
|
strbuf_release(&iter->key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int amend_file_with_trailers(const char *path, const struct strvec *trailer_args)
|
||||||
|
{
|
||||||
|
struct child_process run_trailer = CHILD_PROCESS_INIT;
|
||||||
|
|
||||||
|
run_trailer.git_cmd = 1;
|
||||||
|
strvec_pushl(&run_trailer.args, "interpret-trailers",
|
||||||
|
"--in-place", "--no-divider",
|
||||||
|
path, NULL);
|
||||||
|
strvec_pushv(&run_trailer.args, trailer_args->v);
|
||||||
|
return run_command(&run_trailer);
|
||||||
|
}
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
#include "strbuf.h"
|
#include "strbuf.h"
|
||||||
|
|
||||||
|
struct strvec;
|
||||||
|
|
||||||
enum trailer_where {
|
enum trailer_where {
|
||||||
WHERE_DEFAULT,
|
WHERE_DEFAULT,
|
||||||
WHERE_END,
|
WHERE_END,
|
||||||
|
@ -158,4 +160,11 @@ int trailer_iterator_advance(struct trailer_iterator *iter);
|
||||||
*/
|
*/
|
||||||
void trailer_iterator_release(struct trailer_iterator *iter);
|
void trailer_iterator_release(struct trailer_iterator *iter);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Augment a file to add trailers to it by running git-interpret-trailers.
|
||||||
|
* This calls run_command() and its return value is the same (i.e. 0 for
|
||||||
|
* success, various non-zero for other errors). See run-command.h.
|
||||||
|
*/
|
||||||
|
int amend_file_with_trailers(const char *path, const struct strvec *trailer_args);
|
||||||
|
|
||||||
#endif /* TRAILER_H */
|
#endif /* TRAILER_H */
|
||||||
|
|
Loading…
Reference in New Issue