ref-filter: add option to filter out tags, branches and remotes
[gitweb.git] / builtin / tag.c
index 6f07ac6b93c3e36a1bc69d43e6e12ca3367b4c34..471d6b1ab8847d7344483509633d3067c088bf6d 100644 (file)
@@ -56,6 +56,10 @@ static int match_pattern(const char **patterns, const char *ref)
        return 0;
 }
 
+/*
+ * This is currently duplicated in ref-filter.c, and will eventually be
+ * removed as we port tag.c to use the ref-filter APIs.
+ */
 static const unsigned char *match_points_at(const char *refname,
                                            const unsigned char *sha1)
 {
@@ -82,6 +86,11 @@ static int in_commit_list(const struct commit_list *want, struct commit *c)
        return 0;
 }
 
+/*
+ * The entire code segment for supporting the --contains option has been
+ * copied over to ref-filter.{c,h}. This will be deleted evetually when
+ * we port tag.c to use ref-filter APIs.
+ */
 enum contains_result {
        CONTAINS_UNKNOWN = -1,
        CONTAINS_NO = 0,
@@ -176,7 +185,7 @@ static enum contains_result contains(struct commit *candidate,
        return contains_test(candidate, want);
 }
 
-static void show_tag_lines(const unsigned char *sha1, int lines)
+static void show_tag_lines(const struct object_id *oid, int lines)
 {
        int i;
        unsigned long size;
@@ -184,14 +193,14 @@ static void show_tag_lines(const unsigned char *sha1, int lines)
        char *buf, *sp, *eol;
        size_t len;
 
-       buf = read_sha1_file(sha1, &type, &size);
+       buf = read_sha1_file(oid->hash, &type, &size);
        if (!buf)
-               die_errno("unable to read object %s", sha1_to_hex(sha1));
+               die_errno("unable to read object %s", oid_to_hex(oid));
        if (type != OBJ_COMMIT && type != OBJ_TAG)
                goto free_return;
        if (!size)
                die("an empty %s object %s?",
-                   typename(type), sha1_to_hex(sha1));
+                   typename(type), oid_to_hex(oid));
 
        /* skip header */
        sp = strstr(buf, "\n\n");
@@ -215,7 +224,7 @@ static void show_tag_lines(const unsigned char *sha1, int lines)
        free(buf);
 }
 
-static int show_reference(const char *refname, const unsigned char *sha1,
+static int show_reference(const char *refname, const struct object_id *oid,
                          int flag, void *cb_data)
 {
        struct tag_filter *filter = cb_data;
@@ -224,14 +233,14 @@ static int show_reference(const char *refname, const unsigned char *sha1,
                if (filter->with_commit) {
                        struct commit *commit;
 
-                       commit = lookup_commit_reference_gently(sha1, 1);
+                       commit = lookup_commit_reference_gently(oid->hash, 1);
                        if (!commit)
                                return 0;
                        if (!contains(commit, filter->with_commit))
                                return 0;
                }
 
-               if (points_at.nr && !match_points_at(refname, sha1))
+               if (points_at.nr && !match_points_at(refname, oid->hash))
                        return 0;
 
                if (!filter->lines) {
@@ -242,7 +251,7 @@ static int show_reference(const char *refname, const unsigned char *sha1,
                        return 0;
                }
                printf("%-15s ", refname);
-               show_tag_lines(sha1, filter->lines);
+               show_tag_lines(oid, filter->lines);
                putchar('\n');
        }
 
@@ -268,7 +277,7 @@ static int list_tags(const char **patterns, int lines,
        memset(&filter.tags, 0, sizeof(filter.tags));
        filter.tags.strdup_strings = 1;
 
-       for_each_tag_ref(show_reference, (void *) &filter);
+       for_each_tag_ref(show_reference, (void *)&filter);
        if (sort) {
                int i;
                if ((sort & SORT_MASK) == VERCMP_SORT)
@@ -546,23 +555,6 @@ static int strbuf_check_tag_ref(struct strbuf *sb, const char *name)
        return check_refname_format(sb->buf, 0);
 }
 
-static int parse_opt_points_at(const struct option *opt __attribute__((unused)),
-                       const char *arg, int unset)
-{
-       unsigned char sha1[20];
-
-       if (unset) {
-               sha1_array_clear(&points_at);
-               return 0;
-       }
-       if (!arg)
-               return error(_("switch 'points-at' requires an object"));
-       if (get_sha1(arg, sha1))
-               return error(_("malformed object name '%s'"), arg);
-       sha1_array_append(&points_at, sha1);
-       return 0;
-}
-
 static int parse_opt_sort(const struct option *opt, const char *arg, int unset)
 {
        int *sort = opt->value;
@@ -579,6 +571,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
        struct create_tag_options opt;
        char *cleanup_arg = NULL;
        int annotate = 0, force = 0, lines = -1;
+       int create_reflog = 0;
        int cmdmode = 0;
        const char *msgfile = NULL, *keyid = NULL;
        struct msg_arg msg = { 0, STRBUF_INIT };
@@ -605,28 +598,19 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
                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")),
+               OPT_BOOL(0, "create-reflog", &create_reflog, N_("create_reflog")),
 
                OPT_GROUP(N_("Tag listing options")),
                OPT_COLUMN(0, "column", &colopts, N_("show tag list in columns")),
+               OPT_CONTAINS(&with_commit, N_("print only tags that contain the commit")),
+               OPT_WITH(&with_commit, N_("print only tags that contain the commit")),
                {
                        OPTION_CALLBACK, 0, "sort", &tag_sort, N_("type"), N_("sort tags"),
                        PARSE_OPT_NONEG, parse_opt_sort
                },
                {
-                       OPTION_CALLBACK, 0, "contains", &with_commit, N_("commit"),
-                       N_("print only tags that contain the commit"),
-                       PARSE_OPT_LASTARG_DEFAULT,
-                       parse_opt_with_commit, (intptr_t)"HEAD",
-               },
-               {
-                       OPTION_CALLBACK, 0, "with", &with_commit, N_("commit"),
-                       N_("print only tags that contain the commit"),
-                       PARSE_OPT_HIDDEN | PARSE_OPT_LASTARG_DEFAULT,
-                       parse_opt_with_commit, (intptr_t)"HEAD",
-               },
-               {
-                       OPTION_CALLBACK, 0, "points-at", NULL, N_("object"),
-                       N_("print only tags of the object"), 0, parse_opt_points_at
+                       OPTION_CALLBACK, 0, "points-at", &points_at, N_("object"),
+                       N_("print only tags of the object"), 0, parse_opt_object_name
                },
                OPT_END()
        };
@@ -733,7 +717,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
        transaction = ref_transaction_begin(&err);
        if (!transaction ||
            ref_transaction_update(transaction, ref.buf, object, prev,
-                                  0, NULL, &err) ||
+                                  create_reflog ? REF_FORCE_CREATE_REFLOG : 0,
+                                  NULL, &err) ||
            ref_transaction_commit(transaction, &err))
                die("%s", err.buf);
        ref_transaction_free(transaction);