Merge branch 'js/mingw-gcc-stack-protect'
[gitweb.git] / builtin / tag.c
index ad97595fbfaa25c8ec44efec8ce5f946cf7de184..e0a4c25382846f801c43cd1093ffb0ffa63f975f 100644 (file)
 #include "ref-filter.h"
 
 static const char * const git_tag_usage[] = {
-       N_("git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>] <tagname> [<head>]"),
+       N_("git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>]\n"
+               "\t\t<tagname> [<head>]"),
        N_("git tag -d <tagname>..."),
-       N_("git tag -l [-n[<num>]] [--contains <commit>] [--no-contains <commit>] [--points-at <object>]"
-               "\n\t\t[--format=<format>] [--[no-]merged [<commit>]] [<pattern>...]"),
+       N_("git tag -l [-n[<num>]] [--contains <commit>] [--no-contains <commit>] [--points-at <object>]\n"
+               "\t\t[--format=<format>] [--[no-]merged [<commit>]] [<pattern>...]"),
        N_("git tag -v [--format=<format>] <tagname>..."),
        NULL
 };
 
 static unsigned int colopts;
 static int force_sign_annotate;
+static int config_sign_tag = -1; /* unspecified */
 
 static int list_tags(struct ref_filter *filter, struct ref_sorting *sorting,
                     struct ref_format *format)
@@ -143,6 +145,11 @@ static int git_tag_config(const char *var, const char *value, void *cb)
        int status;
        struct ref_sorting **sorting_tail = (struct ref_sorting **)cb;
 
+       if (!strcmp(var, "tag.gpgsign")) {
+               config_sign_tag = git_config_bool(var, value);
+               return 0;
+       }
+
        if (!strcmp(var, "tag.sort")) {
                if (!value)
                        return config_error_nonbool(var);
@@ -205,7 +212,14 @@ struct create_tag_options {
        } cleanup_mode;
 };
 
-static void create_tag(const struct object_id *object, const char *tag,
+static const char message_advice_nested_tag[] =
+       N_("You have created a nested tag. The object referred to by your new tag is\n"
+          "already a tag. If you meant to tag the object that it points to, use:\n"
+          "\n"
+          "\tgit tag -f %s %s^{}");
+
+static void create_tag(const struct object_id *object, const char *object_ref,
+                      const char *tag,
                       struct strbuf *buf, struct create_tag_options *opt,
                       struct object_id *prev, struct object_id *result)
 {
@@ -215,7 +229,10 @@ static void create_tag(const struct object_id *object, const char *tag,
 
        type = oid_object_info(the_repository, object, NULL);
        if (type <= OBJ_NONE)
-           die(_("bad object type."));
+               die(_("bad object type."));
+
+       if (type == OBJ_TAG && advice_nested_tag)
+               advise(_(message_advice_nested_tag), tag, object_ref);
 
        strbuf_addf(&header,
                    "object %s\n"
@@ -397,8 +414,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
                OPT_FILENAME('F', "file", &msgfile, N_("read message from file")),
                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_STRING(0, "cleanup", &cleanup_arg, N_("mode"),
-                       N_("how to strip spaces and #comments from message")),
+               OPT_CLEANUP(&cleanup_arg),
                OPT_STRING('u', "local-user", &keyid, N_("key-id"),
                                        N_("use another key to sign the tag")),
                OPT__FORCE(&force, N_("replace the tag if exists"), 0),
@@ -432,15 +448,10 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
        memset(&opt, 0, sizeof(opt));
        memset(&filter, 0, sizeof(filter));
        filter.lines = -1;
+       opt.sign = -1;
 
        argc = parse_options(argc, argv, prefix, options, git_tag_usage, 0);
 
-       if (keyid) {
-               opt.sign = 1;
-               set_signing_key(keyid);
-       }
-       create_tag_object = (opt.sign || annotate || msg.given || msgfile);
-
        if (!cmdmode) {
                if (argc == 0)
                        cmdmode = 'l';
@@ -453,6 +464,15 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
        if (cmdmode == 'l')
                setup_auto_pager("tag", 1);
 
+       if (opt.sign == -1)
+               opt.sign = cmdmode ? 0 : config_sign_tag > 0;
+
+       if (keyid) {
+               opt.sign = 1;
+               set_signing_key(keyid);
+       }
+       create_tag_object = (opt.sign || annotate || msg.given || msgfile);
+
        if ((create_tag_object || force) && (cmdmode != 0))
                usage_with_options(git_tag_usage, options);
 
@@ -549,7 +569,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
        if (create_tag_object) {
                if (force_sign_annotate && !annotate)
                        opt.sign = 1;
-               create_tag(&object, tag, &buf, &opt, &prev, &object);
+               create_tag(&object, object_ref, tag, &buf, &opt, &prev, &object);
        }
 
        transaction = ref_transaction_begin(&err);