{"thread":{"id":"29102","subject":"[PATCH, v5] git-tag: introduce --cleanup option","startedAt":"2011-12-07T03:01:45Z","lastAt":"2011-12-09T18:04:41Z","messageCount":2,"participants":["Kirill A. Shutemov","Junio C Hamano"],"isPatch":true,"patchVersion":5,"patchTotal":null},"messages":[{"id":"180443","messageId":"1323226905-31418-1-git-send-email-kirill@shutemov.name","threadId":"29102","inReplyTo":null,"subject":"[PATCH, v5] git-tag: introduce --cleanup option","fromName":"Kirill A. Shutemov","fromEmail":"kirill@shutemov.name","sentAt":"2011-12-07T03:01:45Z","receivedAt":"2011-12-07T03:01:45Z","isPatch":true,"sender":{"key":"kirill@shutemov.name","avatar":"https://avatars.githubusercontent.com/u/588661?v=4"},"body":"From: \"Kirill A. Shutemov\" <kirill@shutemov.name>\n\nNormally git tag strips tag message lines starting with '#', trailing\nspaces from every line and empty lines from the beginning and end.\n\n--cleanup allows to select different cleanup modes for tag message.\nIt provides the same interface as --cleanup option in git-commit.\n\nSigned-off-by: Kirill A. Shutemov <kirill@shutemov.name>\n---\n Documentation/git-tag.txt |    7 +++++\n builtin/tag.c             |   67 +++++++++++++++++++++++++++++++++++---------\n 2 files changed, 60 insertions(+), 14 deletions(-)\n\ndiff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt\nindex c83cb13..622a019 100644\n--- a/Documentation/git-tag.txt\n+++ b/Documentation/git-tag.txt\n@@ -99,6 +99,13 @@ OPTIONS\n \tImplies `-a` if none of `-a`, `-s`, or `-u <key-id>`\n \tis given.\n \n+--cleanup=<mode>::\n+\tThis option sets how the tag message is cleaned up.\n+\tThe  '<mode>' can be one of 'verbatim', 'whitespace' and 'strip'.  The\n+\t'strip' mode is default. The 'verbatim' mode does not change message at\n+\tall, 'whitespace' removes just leading/trailing whitespace lines and\n+\t'strip' removes both whitespace and commentary.\n+\n <tagname>::\n \tThe name of the tag to create, delete, or describe.\n \tThe new tag name must pass all checks defined by\ndiff --git a/builtin/tag.c b/builtin/tag.c\nindex 9b6fd95..51a4184 100644\n--- a/builtin/tag.c\n+++ b/builtin/tag.c\n@@ -268,6 +268,15 @@ static const char tag_template[] =\n \tN_(\"\\n\"\n \t\"#\\n\"\n \t\"# Write a tag message\\n\"\n+\t\"# Lines starting with '#' will be ignored.\\n\"\n+\t\"#\\n\");\n+\n+static const char tag_template_nocleanup[] =\n+\tN_(\"\\n\"\n+\t\"#\\n\"\n+\t\"# Write a tag message\\n\"\n+\t\"# Lines starting with '#' will be kept; you may remove them\"\n+\t\" yourself if you want to.\\n\"\n \t\"#\\n\");\n \n static void set_signingkey(const char *value)\n@@ -319,8 +328,18 @@ static int build_tag_object(struct strbuf *buf, int sign, unsigned char *result)\n \treturn 0;\n }\n \n+struct create_tag_options {\n+\tunsigned int message_given:1;\n+\tunsigned int sign;\n+\tenum {\n+\t\tCLEANUP_NONE,\n+\t\tCLEANUP_SPACE,\n+\t\tCLEANUP_ALL\n+\t} cleanup_mode;\n+};\n+\n static void create_tag(const unsigned char *object, const char *tag,\n-\t\t       struct strbuf *buf, int message, int sign,\n+\t\t       struct strbuf *buf, struct create_tag_options *opt,\n \t\t       unsigned char *prev, unsigned char *result)\n {\n \tenum object_type type;\n@@ -345,7 +364,7 @@ static void create_tag(const unsigned char *object, const char *tag,\n \tif (header_len > sizeof(header_buf) - 1)\n \t\tdie(_(\"tag header too big.\"));\n \n-\tif (!message) {\n+\tif (!opt->message_given) {\n \t\tint fd;\n \n \t\t/* write the template message before editing: */\n@@ -356,8 +375,12 @@ static void create_tag(const unsigned char *object, const char *tag,\n \n \t\tif (!is_null_sha1(prev))\n \t\t\twrite_tag_body(fd, prev);\n+\t\telse if (opt->cleanup_mode == CLEANUP_ALL)\n+\t\t\twrite_or_die(fd, _(tag_template),\n+\t\t\t\t\tstrlen(_(tag_template)));\n \t\telse\n-\t\t\twrite_or_die(fd, _(tag_template), strlen(_(tag_template)));\n+\t\t\twrite_or_die(fd, _(tag_template_nocleanup),\n+\t\t\t\t\tstrlen(_(tag_template_nocleanup)));\n \t\tclose(fd);\n \n \t\tif (launch_editor(path, buf, NULL)) {\n@@ -367,14 +390,15 @@ static void create_tag(const unsigned char *object, const char *tag,\n \t\t}\n \t}\n \n-\tstripspace(buf, 1);\n+\tif (opt->cleanup_mode != CLEANUP_NONE)\n+\t\tstripspace(buf, opt->cleanup_mode == CLEANUP_ALL);\n \n-\tif (!message && !buf->len)\n+\tif (!opt->message_given && !buf->len)\n \t\tdie(_(\"no tag message?\"));\n \n \tstrbuf_insert(buf, 0, header_buf, header_len);\n \n-\tif (build_tag_object(buf, sign, result) < 0) {\n+\tif (build_tag_object(buf, opt->sign, result) < 0) {\n \t\tif (path)\n \t\t\tfprintf(stderr, _(\"The tag message has been left in %s\\n\"),\n \t\t\t\tpath);\n@@ -422,9 +446,10 @@ int cmd_tag(int argc, const char **argv, const char *prefix)\n \tunsigned char object[20], prev[20];\n \tconst char *object_ref, *tag;\n \tstruct ref_lock *lock;\n-\n-\tint annotate = 0, sign = 0, force = 0, lines = -1,\n-\t\tlist = 0, delete = 0, verify = 0;\n+\tstruct create_tag_options opt;\n+\tchar *cleanup_arg = NULL;\n+\tint annotate = 0, force = 0, lines = -1, list = 0,\n+\t    delete = 0, verify = 0;\n \tconst char *msgfile = NULL, *keyid = NULL;\n \tstruct msg_arg msg = { 0, STRBUF_INIT };\n \tstruct commit_list *with_commit = NULL;\n@@ -442,7 +467,9 @@ int cmd_tag(int argc, const char **argv, const char *prefix)\n \t\tOPT_CALLBACK('m', \"message\", &msg, \"message\",\n \t\t\t     \"tag message\", parse_msg_arg),\n \t\tOPT_FILENAME('F', \"file\", &msgfile, \"read message from file\"),\n-\t\tOPT_BOOLEAN('s', \"sign\", &sign, \"annotated and GPG-signed tag\"),\n+\t\tOPT_BOOLEAN('s', \"sign\", &opt.sign, \"annotated and GPG-signed tag\"),\n+\t\tOPT_STRING(0, \"cleanup\", &cleanup_arg, \"mode\",\n+\t\t\t\"how to strip spaces and #comments from message\"),\n \t\tOPT_STRING('u', \"local-user\", &keyid, \"key-id\",\n \t\t\t\t\t\"use another key to sign the tag\"),\n \t\tOPT__FORCE(&force, \"replace the tag if exists\"),\n@@ -459,13 +486,15 @@ int cmd_tag(int argc, const char **argv, const char *prefix)\n \n \tgit_config(git_tag_config, NULL);\n \n+\tmemset(&opt, 0, sizeof(opt));\n+\n \targc = parse_options(argc, argv, prefix, options, git_tag_usage, 0);\n \n \tif (keyid) {\n-\t\tsign = 1;\n+\t\topt.sign = 1;\n \t\tset_signingkey(keyid);\n \t}\n-\tif (sign)\n+\tif (opt.sign)\n \t\tannotate = 1;\n \tif (argc == 0 && !(delete || verify))\n \t\tlist = 1;\n@@ -523,9 +552,19 @@ int cmd_tag(int argc, const char **argv, const char *prefix)\n \telse if (!force)\n \t\tdie(_(\"tag '%s' already exists\"), tag);\n \n+\topt.message_given = msg.given || msgfile;\n+\n+\tif (!cleanup_arg || !strcmp(cleanup_arg, \"strip\"))\n+\t\topt.cleanup_mode = CLEANUP_ALL;\n+\telse if (!strcmp(cleanup_arg, \"verbatim\"))\n+\t\topt.cleanup_mode = CLEANUP_NONE;\n+\telse if (!strcmp(cleanup_arg, \"whitespace\"))\n+\t\topt.cleanup_mode = CLEANUP_SPACE;\n+\telse\n+\t\tdie(_(\"Invalid cleanup mode %s\"), cleanup_arg);\n+\n \tif (annotate)\n-\t\tcreate_tag(object, tag, &buf, msg.given || msgfile,\n-\t\t\t   sign, prev, object);\n+\t\tcreate_tag(object, tag, &buf, &opt, prev, object);\n \n \tlock = lock_any_ref_for_update(ref.buf, prev, 0);\n \tif (!lock)\n-- \n1.7.7.3\n"},{"id":"180705","messageId":"7viplpebnm.fsf@alter.siamese.dyndns.org","threadId":"29102","inReplyTo":"1323226905-31418-1-git-send-email-kirill@shutemov.name","subject":"Re: [PATCH, v5] git-tag: introduce --cleanup option","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-12-09T18:04:41Z","receivedAt":"2011-12-09T18:04:41Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Looks sane; thanks, will queue.\n"}]}