Merge branch 'ks/tag-cleanup'

* ks/tag-cleanup:
  git-tag: introduce --cleanup option

Conflicts:
	builtin/tag.c
This commit is contained in:
Junio C Hamano 2011-12-13 23:03:00 -08:00
commit b3f17ac3d6
2 changed files with 60 additions and 14 deletions

View File

@ -99,6 +99,13 @@ OPTIONS
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.
--cleanup=<mode>::
This option sets how the tag message is cleaned up.
The '<mode>' can be one of 'verbatim', 'whitespace' and 'strip'. The
'strip' mode is default. The 'verbatim' mode does not change message at
all, 'whitespace' removes just leading/trailing whitespace lines and
'strip' removes both whitespace and commentary.
<tagname>:: <tagname>::
The name of the tag to create, delete, or describe. The name of the tag to create, delete, or describe.
The new tag name must pass all checks defined by The new tag name must pass all checks defined by

View File

@ -214,6 +214,15 @@ static const char tag_template[] =
N_("\n" N_("\n"
"#\n" "#\n"
"# Write a tag message\n" "# Write a tag message\n"
"# Lines starting with '#' will be ignored.\n"
"#\n");
static const char tag_template_nocleanup[] =
N_("\n"
"#\n"
"# Write a tag message\n"
"# Lines starting with '#' will be kept; you may remove them"
" yourself if you want to.\n"
"#\n"); "#\n");
static int git_tag_config(const char *var, const char *value, void *cb) static int git_tag_config(const char *var, const char *value, void *cb)
@ -255,8 +264,18 @@ static int build_tag_object(struct strbuf *buf, int sign, unsigned char *result)
return 0; return 0;
} }
struct create_tag_options {
unsigned int message_given:1;
unsigned int sign;
enum {
CLEANUP_NONE,
CLEANUP_SPACE,
CLEANUP_ALL
} cleanup_mode;
};
static void create_tag(const unsigned char *object, const char *tag, static void create_tag(const unsigned char *object, const char *tag,
struct strbuf *buf, int message, int sign, struct strbuf *buf, struct create_tag_options *opt,
unsigned char *prev, unsigned char *result) unsigned char *prev, unsigned char *result)
{ {
enum object_type type; enum object_type type;
@ -281,7 +300,7 @@ static void create_tag(const unsigned char *object, const char *tag,
if (header_len > sizeof(header_buf) - 1) if (header_len > sizeof(header_buf) - 1)
die(_("tag header too big.")); die(_("tag header too big."));
if (!message) { if (!opt->message_given) {
int fd; int fd;
/* write the template message before editing: */ /* write the template message before editing: */
@ -292,8 +311,12 @@ static void create_tag(const unsigned char *object, const char *tag,
if (!is_null_sha1(prev)) if (!is_null_sha1(prev))
write_tag_body(fd, prev); write_tag_body(fd, prev);
else if (opt->cleanup_mode == CLEANUP_ALL)
write_or_die(fd, _(tag_template),
strlen(_(tag_template)));
else else
write_or_die(fd, _(tag_template), strlen(_(tag_template))); write_or_die(fd, _(tag_template_nocleanup),
strlen(_(tag_template_nocleanup)));
close(fd); close(fd);
if (launch_editor(path, buf, NULL)) { if (launch_editor(path, buf, NULL)) {
@ -303,14 +326,15 @@ static void create_tag(const unsigned char *object, const char *tag,
} }
} }
stripspace(buf, 1); if (opt->cleanup_mode != CLEANUP_NONE)
stripspace(buf, opt->cleanup_mode == CLEANUP_ALL);
if (!message && !buf->len) if (!opt->message_given && !buf->len)
die(_("no tag message?")); die(_("no tag message?"));
strbuf_insert(buf, 0, header_buf, header_len); strbuf_insert(buf, 0, header_buf, header_len);
if (build_tag_object(buf, sign, result) < 0) { if (build_tag_object(buf, opt->sign, result) < 0) {
if (path) if (path)
fprintf(stderr, _("The tag message has been left in %s\n"), fprintf(stderr, _("The tag message has been left in %s\n"),
path); path);
@ -358,9 +382,10 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
unsigned char object[20], prev[20]; unsigned char object[20], prev[20];
const char *object_ref, *tag; const char *object_ref, *tag;
struct ref_lock *lock; struct ref_lock *lock;
struct create_tag_options opt;
int annotate = 0, sign = 0, force = 0, lines = -1, char *cleanup_arg = NULL;
list = 0, delete = 0, verify = 0; int annotate = 0, force = 0, lines = -1, list = 0,
delete = 0, verify = 0;
const char *msgfile = NULL, *keyid = NULL; const char *msgfile = NULL, *keyid = NULL;
struct msg_arg msg = { 0, STRBUF_INIT }; struct msg_arg msg = { 0, STRBUF_INIT };
struct commit_list *with_commit = NULL; struct commit_list *with_commit = NULL;
@ -378,7 +403,9 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
OPT_CALLBACK('m', "message", &msg, "message", OPT_CALLBACK('m', "message", &msg, "message",
"tag message", parse_msg_arg), "tag message", parse_msg_arg),
OPT_FILENAME('F', "file", &msgfile, "read message from file"), OPT_FILENAME('F', "file", &msgfile, "read message from file"),
OPT_BOOLEAN('s', "sign", &sign, "annotated and GPG-signed tag"), OPT_BOOLEAN('s', "sign", &opt.sign, "annotated and GPG-signed tag"),
OPT_STRING(0, "cleanup", &cleanup_arg, "mode",
"how to strip spaces and #comments from message"),
OPT_STRING('u', "local-user", &keyid, "key-id", OPT_STRING('u', "local-user", &keyid, "key-id",
"use another key to sign the tag"), "use another key to sign the tag"),
OPT__FORCE(&force, "replace the tag if exists"), OPT__FORCE(&force, "replace the tag if exists"),
@ -395,13 +422,15 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
git_config(git_tag_config, NULL); git_config(git_tag_config, NULL);
memset(&opt, 0, sizeof(opt));
argc = parse_options(argc, argv, prefix, options, git_tag_usage, 0); argc = parse_options(argc, argv, prefix, options, git_tag_usage, 0);
if (keyid) { if (keyid) {
sign = 1; opt.sign = 1;
set_signing_key(keyid); set_signing_key(keyid);
} }
if (sign) if (opt.sign)
annotate = 1; annotate = 1;
if (argc == 0 && !(delete || verify)) if (argc == 0 && !(delete || verify))
list = 1; list = 1;
@ -459,9 +488,19 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
else if (!force) else if (!force)
die(_("tag '%s' already exists"), tag); die(_("tag '%s' already exists"), tag);
opt.message_given = msg.given || msgfile;
if (!cleanup_arg || !strcmp(cleanup_arg, "strip"))
opt.cleanup_mode = CLEANUP_ALL;
else if (!strcmp(cleanup_arg, "verbatim"))
opt.cleanup_mode = CLEANUP_NONE;
else if (!strcmp(cleanup_arg, "whitespace"))
opt.cleanup_mode = CLEANUP_SPACE;
else
die(_("Invalid cleanup mode %s"), cleanup_arg);
if (annotate) if (annotate)
create_tag(object, tag, &buf, msg.given || msgfile, create_tag(object, tag, &buf, &opt, prev, object);
sign, prev, object);
lock = lock_any_ref_for_update(ref.buf, prev, 0); lock = lock_any_ref_for_update(ref.buf, prev, 0);
if (!lock) if (!lock)