git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH-master] tag: add --points-at list option

From
Tom Grennan <tmgrennan@gmail.com>
Date
Feb 8, 2012, 23:03 UTC
Message-ID
<1328742223-24419-2-git-send-email-tmgrennan@gmail.com>
In-Reply-To
<1328742223-24419-1-git-send-email-tmgrennan@gmail.com>

This filters the list for tags of the given object. Example,

   john$ git tag v1.0-john v1.0
   john$ git tag -l --points-at v1.0
   v1.0-john
   v1.0
Signed-off-by: Tom Grennan <tmgrennan@gmail.com>
---
 Documentation/git-tag.txt |    6 ++++-
 builtin/tag.c             |   50 ++++++++++++++++++++++++++++++++++++++++++++-
 t/t7004-tag.sh            |   39 +++++++++++++++++++++++++++++++++++
 3 files changed, 93 insertions(+), 2 deletions(-)
diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt
index 53ff5f6..8d32b9a 100644
--- a/Documentation/git-tag.txt
+++ b/Documentation/git-tag.txt
@@ -12,7 +12,8 @@ SYNOPSIS
 'git tag' [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>]
 	<tagname> [<commit> | <object>]
 'git tag' -d <tagname>...
-'git tag' [-n[<num>]] -l [--contains <commit>] [<pattern>...]
+'git tag' [-n[<num>]] -l [--contains <commit>] [--points-at <object>]
+	[<pattern>...]
 'git tag' -v <tagname>...
 
 DESCRIPTION
@@ -86,6 +87,9 @@ OPTIONS
 --contains <commit>::
 	Only list tags which contain the specified commit.
 
+--points-at <object>::
+	Only list tags of the given object.
+
 -m <msg>::
 --message=<msg>::
 	Use the given tag message (instead of prompting).
diff --git a/builtin/tag.c b/builtin/tag.c
index 31f02e8..27c3557 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -15,11 +15,13 @@
 #include "diff.h"
 #include "revision.h"
 #include "gpg-interface.h"
+#include "sha1-array.h"
 
 static const char * const git_tag_usage[] = {
 	"git tag [-a|-s|-u <key-id>] [-f] [-m <msg>|-F <file>] <tagname> [<head>]",
 	"git tag -d <tagname>...",
-	"git tag -l [-n[<num>]] [<pattern>...]",
+	"git tag -l [-n[<num>]] [--contains <commit>] [--points-at <object>] "
+		"\n\t\t[<pattern>...]",
 	"git tag -v <tagname>...",
 	NULL
 };
@@ -30,6 +32,8 @@ struct tag_filter {
 	struct commit_list *with_commit;
 };
 
+static struct sha1_array points_at;
+
 static int match_pattern(const char **patterns, const char *ref)
 {
 	/* no pattern means match everything */
@@ -41,6 +45,24 @@ static int match_pattern(const char **patterns, const char *ref)
 	return 0;
 }
 
+static const unsigned char *match_points_at(const char *refname,
+					    const unsigned char *sha1)
+{
+	const unsigned char *tagged_sha1 = NULL;
+	struct object *obj;
+
+	if (sha1_array_lookup(&points_at, sha1) >= 0)
+		return sha1;
+	obj = parse_object(sha1);
+	if (!obj)
+		die(_("malformed object at '%s'"), refname);
+	if (obj->type == OBJ_TAG)
+		tagged_sha1 = ((struct tag *)obj)->tagged->sha1;
+	if (tagged_sha1 && sha1_array_lookup(&points_at, tagged_sha1) >= 0)
+		return tagged_sha1;
+	return NULL;
+}
+
 static int in_commit_list(const struct commit_list *want, struct commit *c)
 {
 	for (; want; want = want->next)
@@ -105,6 +127,9 @@ static int show_reference(const char *refname, const unsigned char *sha1,
 				return 0;
 		}
 
+		if (points_at.nr && !match_points_at(refname, sha1))
+			return 0;
+
 		if (!filter->lines) {
 			printf("%s\n", refname);
 			return 0;
@@ -375,6 +400,23 @@ static int strbuf_check_tag_ref(struct strbuf *sb, const char *name)
 	return check_refname_format(sb->buf, 0);
 }
 
+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;
+}
+
 int cmd_tag(int argc, const char **argv, const char *prefix)
 {
 	struct strbuf buf = STRBUF_INIT;
@@ -417,6 +459,10 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 			PARSE_OPT_LASTARG_DEFAULT,
 			parse_opt_with_commit, (intptr_t)"HEAD",
 		},
+		{
+			OPTION_CALLBACK, 0, "points-at", NULL, "object",
+			"print only tags of the object", 0, parse_opt_points_at
+		},
 		OPT_END()
 	};
 
@@ -448,6 +494,8 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
 		die(_("-n option is only allowed with -l."));
 	if (with_commit)
 		die(_("--contains option is only allowed with -l."));
+	if (points_at.nr)
+		die(_("--points-at option is only allowed with -l."));
 	if (delete)
 		return for_each_tag_name(argv, delete_tag);
 	if (verify)
diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh
index e93ac73..f61e398 100755
--- a/t/t7004-tag.sh
+++ b/t/t7004-tag.sh
@@ -1269,4 +1269,43 @@ test_expect_success 'mixing incompatibles modes and options is forbidden' '
 	test_must_fail git tag -v -s
 '
 
+# check points-at
+
+test_expect_success '--points-at cannot be used in non-list mode' '
+	test_must_fail git tag --points-at=v4.0 foo
+'
+
+test_expect_success '--points-at finds lightweight tags' '
+	echo v4.0 >expect &&
+	git tag --points-at v4.0 >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success '--points-at finds annotated tags of commits' '
+	git tag -m "v4.0, annotated" annotated-v4.0 v4.0 &&
+	echo annotated-v4.0 >expect &&
+	git tag -l --points-at v4.0 "annotated*" >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success '--points-at finds annotated tags of tags' '
+	git tag -m "describing the v4.0 tag object" \
+		annotated-again-v4.0 annotated-v4.0 &&
+	cat >expect <<-\EOF &&
+	annotated-again-v4.0
+	annotated-v4.0
+	EOF
+	git tag --points-at=annotated-v4.0 >actual &&
+	test_cmp expect actual
+'
+
+test_expect_success 'multiple --points-at are OR-ed together' '
+	cat >expect <<-\EOF &&
+	v2.0
+	v3.0
+	EOF
+	git tag --points-at=v2.0 --points-at=v3.0 >actual &&
+	test_cmp expect actual
+'
+
 test_done
-- 
1.7.8
Previous: Tom GrennanNext: Jeff King
Message 50 of 53 in “tag: add --points-at list option”
  1. tag: add --points-at list optionTom Grennan, Feb 5, 2012
  2. Junio C HamanoFeb 5, 2012
  3. Tom GrennanFeb 6, 2012
  4. Junio C HamanoFeb 6, 2012
  5. Tom GrennanFeb 6, 2012
  6. Jeff KingFeb 6, 2012
  7. Tom GrennanFeb 6, 2012
  8. Jeff KingFeb 6, 2012
  9. Jeff KingFeb 6, 2012
  10. Jeff KingFeb 6, 2012
  11. Jeff KingFeb 6, 2012
  12. 1/3 tag: fix output of "tag -n" when errors occurJeff King, Feb 6, 2012
  13. 2/3 tag: die when listing missing or corrupt objectsJeff King, Feb 6, 2012
  14. Junio C HamanoFeb 6, 2012
  15. Jeff KingFeb 6, 2012
  16. Junio C HamanoFeb 6, 2012
  17. Jeff KingFeb 6, 2012
  18. Junio C HamanoFeb 6, 2012
  19. Junio C HamanoFeb 6, 2012
  20. Jeff KingFeb 6, 2012
  21. Junio C HamanoFeb 6, 2012
  22. Jeff KingFeb 8, 2012
  23. Junio C HamanoFeb 9, 2012
  24. 3/3 tag: don't show non-tag contents with "-n"Jeff King, Feb 6, 2012
  25. [PATCHv2] tag: add --points-at list optionTom Grennan, Feb 7, 2012
  26. [PATCHv2] tag: add --points-at list optionTom Grennan, Feb 7, 2012
  27. Junio C HamanoFeb 7, 2012
  28. Tom GrennanFeb 7, 2012
  29. Jeff KingFeb 7, 2012
  30. Tom GrennanFeb 7, 2012
  31. Jeff KingFeb 7, 2012
  32. Tom GrennanFeb 7, 2012
  33. Jeff KingFeb 7, 2012
  34. Junio C HamanoFeb 7, 2012
  35. Jeff KingFeb 7, 2012
  36. Tom GrennanFeb 7, 2012
  37. Jeff KingFeb 8, 2012
  38. Tom GrennanFeb 8, 2012
  39. Jeff KingFeb 8, 2012
  40. [PATCHv3] tag: add --points-at list optionTom Grennan, Feb 8, 2012
  41. [PATCHv3] tag: add --points-at list optionTom Grennan, Feb 8, 2012
  42. Jeff KingFeb 8, 2012
  43. Tom GrennanFeb 8, 2012
  44. Jeff KingFeb 8, 2012
  45. [PATCHv4] tag: add --points-at list optionTom Grennan, Feb 8, 2012
  46. [PATCHv4] tag: add --points-at list optionTom Grennan, Feb 8, 2012
  47. Jeff KingFeb 8, 2012
  48. Tom GrennanFeb 8, 2012
  49. tag: add --points-at list optionTom Grennan, Feb 8, 2012
  50. tag: add --points-at list optionTom Grennan, Feb 8, 2012
  51. Jeff KingFeb 9, 2012
  52. Junio C HamanoFeb 9, 2012
  53. Tom GrennanFeb 8, 2012

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.