status: do not report errors in sequencer/todo
[gitweb.git] / builtin / tag.c
index da186691ed8853bc5848c4106c752b015756eda3..ef37dccf864932a31c019775cdad6d33207941a1 100644 (file)
@@ -10,6 +10,7 @@
 #include "config.h"
 #include "builtin.h"
 #include "refs.h"
+#include "object-store.h"
 #include "tag.h"
 #include "run-command.h"
 #include "parse-options.h"
 #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
 };
@@ -99,7 +101,8 @@ static int delete_tag(const char *name, const char *ref,
 {
        if (delete_ref(NULL, ref, oid, 0))
                return 1;
-       printf(_("Deleted tag '%s' (was %s)\n"), name, find_unique_abbrev(oid->hash, DEFAULT_ABBREV));
+       printf(_("Deleted tag '%s' (was %s)\n"), name,
+              find_unique_abbrev(oid, DEFAULT_ABBREV));
        return 0;
 }
 
@@ -117,7 +120,7 @@ static int verify_tag(const char *name, const char *ref,
                return -1;
 
        if (format->format)
-               pretty_print_ref(name, oid->hash, format);
+               pretty_print_ref(name, oid, format);
 
        return 0;
 }
@@ -167,7 +170,7 @@ static void write_tag_body(int fd, const struct object_id *oid)
        enum object_type type;
        char *buf, *sp;
 
-       buf = read_sha1_file(oid->hash, &type, &size);
+       buf = read_object_file(oid, &type, &size);
        if (!buf)
                return;
        /* skip header */
@@ -203,7 +206,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)
 {
@@ -211,9 +221,12 @@ static void create_tag(const struct object_id *object, const char *tag,
        struct strbuf header = STRBUF_INIT;
        char *path = NULL;
 
-       type = sha1_object_info(object->hash, NULL);
+       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"
@@ -293,17 +306,17 @@ static void create_reflog_msg(const struct object_id *oid, struct strbuf *sb)
                strbuf_addstr(sb, rla);
        } else {
                strbuf_addstr(sb, "tag: tagging ");
-               strbuf_add_unique_abbrev(sb, oid->hash, DEFAULT_ABBREV);
+               strbuf_add_unique_abbrev(sb, oid, DEFAULT_ABBREV);
        }
 
        strbuf_addstr(sb, " (");
-       type = sha1_object_info(oid->hash, NULL);
+       type = oid_object_info(the_repository, oid, NULL);
        switch (type) {
        default:
                strbuf_addstr(sb, "object of unknown type");
                break;
        case OBJ_COMMIT:
-               if ((buf = read_sha1_file(oid->hash, &type, &size)) != NULL) {
+               if ((buf = read_object_file(oid, &type, &size)) != NULL) {
                        subject_len = find_commit_subject(buf, &subject_start);
                        strbuf_insert(sb, sb->len, subject_start, subject_len);
                } else {
@@ -311,7 +324,7 @@ static void create_reflog_msg(const struct object_id *oid, struct strbuf *sb)
                }
                free(buf);
 
-               if ((c = lookup_commit_reference(oid)) != NULL)
+               if ((c = lookup_commit_reference(the_repository, oid)) != NULL)
                        strbuf_addf(sb, ", %s", show_date(c->date, 0, DATE_MODE(SHORT)));
                break;
        case OBJ_TREE:
@@ -336,6 +349,8 @@ static int parse_msg_arg(const struct option *opt, const char *arg, int unset)
 {
        struct msg_arg *msg = opt->value;
 
+       BUG_ON_OPT_NEG(unset);
+
        if (!arg)
                return -1;
        if (msg->buf.len)
@@ -388,13 +403,12 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
                OPT_GROUP(N_("Tag creation options")),
                OPT_BOOL('a', "annotate", &annotate,
                                        N_("annotated tag, needs a message")),
-               OPT_CALLBACK('m', "message", &msg, N_("message"),
-                            N_("tag message"), parse_msg_arg),
+               { OPTION_CALLBACK, '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_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),
@@ -408,8 +422,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
                OPT_WITHOUT(&filter.no_commit, N_("print only tags that don't contain the commit")),
                OPT_MERGED(&filter, N_("print only tags that are merged")),
                OPT_NO_MERGED(&filter, N_("print only tags that are not merged")),
-               OPT_CALLBACK(0 , "sort", sorting_tail, N_("key"),
-                            N_("field name to sort on"), &parse_opt_ref_sorting),
+               OPT_REF_SORT(sorting_tail),
                {
                        OPTION_CALLBACK, 0, "points-at", &filter.points_at, N_("object"),
                        N_("print only tags of the object"), PARSE_OPT_LASTARG_DEFAULT,
@@ -546,7 +559,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);
@@ -557,8 +570,9 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
            ref_transaction_commit(transaction, &err))
                die("%s", err.buf);
        ref_transaction_free(transaction);
-       if (force && !is_null_oid(&prev) && oidcmp(&prev, &object))
-               printf(_("Updated tag '%s' (was %s)\n"), tag, find_unique_abbrev(prev.hash, DEFAULT_ABBREV));
+       if (force && !is_null_oid(&prev) && !oideq(&prev, &object))
+               printf(_("Updated tag '%s' (was %s)\n"), tag,
+                      find_unique_abbrev(&prev, DEFAULT_ABBREV));
 
        UNLEAK(buf);
        UNLEAK(ref);