How to create tags outside of refs/tags?

5 messages, 3 authors, 2016-06-15 · open the first message on its own page

How to create tags outside of refs/tags?

From: Christian Halstrick <hidden>
Date: 2016-06-15 22:50:37

I would like to create a tag which full name is not starting with
refs/tags. Is that possible with 'git tag'? If not, is there any
other command to create such tags?

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.

Ciao
 Chris

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

From: Jay Soffian <hidden>
Date: 2016-06-15 22:50:37

On Mon, Feb 21, 2011 at 12:21 PM, Christian Halstrick
[off-list ref] wrote:
I would like to create a tag which full name is not starting with
refs/tags. Is that possible with 'git tag'?
Nope.
If not, is there any other command to create such tags?
If it's just a light-weight tag, you can use the low-level (plumbing)
command update-ref to create an arbitrary ref:

$ git update-ref refs/blargh HEAD

If it's an annotated/signed tag you want, you'll have to first create
the tag object with 'git mktag', then use update-ref to create a ref
to that tag.

See git-tag.sh in the contrib directory of git.git.

HTH,

j.

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

From: Christian Halstrick <hidden>
Date: 2016-06-15 22:50:37

But look at my intention:

On Mon, Feb 21, 2011 at 18:21, Christian Halstrick
[off-list ref] 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.

Will any ref underneath "refs/' prevent gc to garbage collect a
commit? Or only those in the well-known locations (e.g. refs/tags/*)

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

From: Jeff King <hidden>
Date: 2016-06-15 22:50:37

On Tue, Feb 22, 2011 at 07:17:20AM +0100, Christian Halstrick wrote:
On Mon, Feb 21, 2011 at 18:21, Christian Halstrick
[off-list ref] wrote:
quoted
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)

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

From: Jay Soffian <hidden>
Date: 2016-06-15 22:50:37

On Tue, Feb 22, 2011 at 1:17 AM, Christian Halstrick
[off-list ref] wrote:
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.
Yes, I'm sorry I wasn't more careful/clearer in my earlier reply.
Will any ref underneath "refs/' prevent gc to garbage collect a
commit? Or only those in the well-known locations (e.g. refs/tags/*)
Anything under refs/ is safe, but you should create a subdirectory so
that you've got your own name-space under there. For example, the
gerrit code review system uses refs/changes/ for its refs.

Because these refs would be outside git's normal name-spaces
(refs/heads and refs/tags), they won't be fetched by the default
(non-mirror) refspec.

j.
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help