Re: How to create tags outside of refs/tags?

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Tue, Feb 22, 2011 at 07:17:20AM +0100, Christian Halstrick wrote:

> On Mon, Feb 21, 2011 at 18:21, Christian Halstrick
> <christian.halstrick@xxxxxxxxx> wrote:
> > I would like to create such tags to mark released states of my sources
> > which should never be garbage collected in case no branch is pointing
> > them anymore. On the other hand these tags should not pollute the
> > namespace of normal tags, means: don't want a 'git tag' command to
> > list those technical tags.
> 
> Is there any better way to achieve that certain commits are not
> garbage collected than to create such tags. I love my foot and don't
> want to "shoot if off" but I want to make sure the the
> "release-process-machinery" in our company can be sure that certain
> source states are never gc'ed. I can also live with creating normal
> tags 'refs/tags/release/1.20' but would prefer a solution where 'git
> tags' shows only developer created tags.

It sounds a lot saner to me to fix "git tag", then, to ignore certain
uninteresting bits of the tag namespace. We already do allow pattern
matching the tags shown, but:

  1. It's an fnmatch, so I don't think there is a way to do a negative
     match like "ignore everything that matches release/*".

  2. It can only be specified on the command-line, whereas obviously you
     would want this as the default for a repo when you type "git tag".

So I think we could do something like the patch below, which allows:

  # set up some boring and interesting tags
  for i in boring more-boring interesting; do
    for j in one two three; do
      git tag $i/$j
    done
  done

  # tell git to ignore boring stuff
  git config tag.ignore 'boring/*'
  git config --add tag.ignore 'more-boring/*'

  # only interesting tags are shown
  git tag

  # only interesting tags are checked for --contains
  git tag --contains HEAD

  # all tags are shown
  git tag --no-ignore

One alternative would be to allow specifying a default pattern in the
config, and then some way of marking it as a regex instead of fnmatch.
Then you could (in theory) construct a regex that negatively matches
your boring refs. Although without perl-compatibile negative look-ahead,
such regexes can get pretty hard to write.

Anyway, here's what the patch looks like. Obviously missing docs and
tests.

---
diff --git a/builtin/tag.c b/builtin/tag.c
index 46f7138..629dfa3 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -12,6 +12,7 @@
 #include "tag.h"
 #include "run-command.h"
 #include "parse-options.h"
+#include "string-list.h"
 
 static const char * const git_tag_usage[] = {
 	"git tag [-a|-s|-u <key-id>] [-f] [-m <msg>|-F <file>] <tagname> [<head>]",
@@ -27,8 +28,11 @@ struct tag_filter {
 	const char *pattern;
 	int lines;
 	struct commit_list *with_commit;
+	const struct string_list *ignore;
 };
 
+static struct string_list ignore_tags = STRING_LIST_INIT_DUP;
+
 static int show_reference(const char *refname, const unsigned char *sha1,
 			  int flag, void *cb_data)
 {
@@ -41,6 +45,13 @@ static int show_reference(const char *refname, const unsigned char *sha1,
 		char *buf, *sp, *eol;
 		size_t len;
 
+		if (filter->ignore) {
+			for (i = 0; i < filter->ignore->nr; i++)
+				if (!fnmatch(filter->ignore->items[i].string,
+					     refname, 0))
+					return 0;
+		}
+
 		if (filter->with_commit) {
 			struct commit *commit;
 
@@ -89,7 +100,8 @@ static int show_reference(const char *refname, const unsigned char *sha1,
 }
 
 static int list_tags(const char *pattern, int lines,
-			struct commit_list *with_commit)
+			struct commit_list *with_commit,
+			const struct string_list *ignore)
 {
 	struct tag_filter filter;
 
@@ -99,6 +111,7 @@ static int list_tags(const char *pattern, int lines,
 	filter.pattern = pattern;
 	filter.lines = lines;
 	filter.with_commit = with_commit;
+	filter.ignore = ignore;
 
 	for_each_tag_ref(show_reference, (void *) &filter);
 
@@ -233,6 +246,13 @@ static int git_tag_config(const char *var, const char *value, void *cb)
 		return 0;
 	}
 
+	if (!strcmp(var, "tag.ignore")) {
+		if (!value)
+			return config_error_nonbool(var);
+		string_list_append(&ignore_tags, value);
+		return 0;
+	}
+
 	return git_default_config(var, value, cb);
 }
 
@@ -365,6 +385,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 	const char *msgfile = NULL, *keyid = NULL;
 	struct msg_arg msg = { 0, STRBUF_INIT };
 	struct commit_list *with_commit = NULL;
+	int ignore = 1;
 	struct option options[] = {
 		OPT_BOOLEAN('l', NULL, &list, "list tag names"),
 		{ OPTION_INTEGER, 'n', NULL, &lines, "n",
@@ -391,6 +412,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 			PARSE_OPT_LASTARG_DEFAULT,
 			parse_opt_with_commit, (intptr_t)"HEAD",
 		},
+		OPT_BOOLEAN(0, "ignore", &ignore, "respect tag.ignore config"),
 		OPT_END()
 	};
 
@@ -415,7 +437,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 		usage_with_options(git_tag_usage, options);
 	if (list)
 		return list_tags(argv[0], lines == -1 ? 0 : lines,
-				 with_commit);
+				 with_commit,
+				 ignore ? &ignore_tags : NULL);
 	if (lines != -1)
 		die("-n option is only allowed with -l.");
 	if (with_commit)
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [Linux Kernel Development]     [Gcc Help]     [IETF Annouce]     [DCCP]     [Netdev]     [Networking]     [Security]     [V4L]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux SCSI]     [Fedora Users]