All of lore.kernel.org
 help / color / mirror / Atom feed
From: Jake Goulding <goulding@vivisimo.com>
To: git@vger.kernel.org
Subject: [PATCH 3/3] Add --contains flag to git tag
Date: Thu, 22 Jan 2009 19:48:46 -0500	[thread overview]
Message-ID: <497913EE.9040608@vivisimo.com> (raw)
In-Reply-To: <1232671630-19683-2-git-send-email-goulding@vivisimo.com>

This functions similar to git branch --contains - it will show all
tags that contain the specified commit. Indeed, it uses the same
lookup mechanisms as git branch.

Also adding documentation and tests for new option.

Signed-off-by: Jake Goulding <goulding@vivisimo.com>
---

Reworked with feedback from the list.

Moved commit testing inside of the regex match, instead of before.
Moved test cases into existing test.
Squashed code / doc / test into one commit.

 Documentation/git-tag.txt |    5 ++-
 builtin-tag.c             |   32 +++++++++++-
 t/t7004-tag.sh            |  115
+++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 148 insertions(+), 4 deletions(-)

diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt
index e44f543..533d18b 100644
--- a/Documentation/git-tag.txt
+++ b/Documentation/git-tag.txt
@@ -12,7 +12,7 @@ SYNOPSIS
 'git tag' [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>]
 	<name> [<commit> | <object>]
 'git tag' -d <name>...
-'git tag' [-n[<num>]] -l [<pattern>]
+'git tag' [-n[<num>]] -l [--contains <commit>] [<pattern>]
 'git tag' -v <name>...

 DESCRIPTION
@@ -68,6 +68,9 @@ OPTIONS
 	List tags with names that match the given pattern (or all if no
pattern is given).
 	Typing "git tag" without arguments, also lists all tags.

+--contains <commit>::
+	Only list tags which contain the specified commit.
+
 -m <msg>::
 	Use the given tag message (instead of prompting).
 	If multiple `-m` options are given, their values are
diff --git a/builtin-tag.c b/builtin-tag.c
index a398499..33424c0 100644
--- a/builtin-tag.c
+++ b/builtin-tag.c
@@ -26,6 +26,7 @@ static char signingkey[1000];
 struct tag_filter {
 	const char *pattern;
 	int lines;
+	struct commit_list *with_commit;
 };

 #define PGP_SIGNATURE "-----BEGIN PGP SIGNATURE-----"
@@ -34,7 +35,6 @@ static int show_reference(const char *refname, const
unsigned char *sha1,
 			  int flag, void *cb_data)
 {
 	struct tag_filter *filter = cb_data;
-
 	if (!fnmatch(filter->pattern, refname, 0)) {
 		int i;
 		unsigned long size;
@@ -42,6 +42,18 @@ static int show_reference(const char *refname, const
unsigned char *sha1,
 		char *buf, *sp, *eol;
 		size_t len;

+		if (filter->with_commit) {
+			struct commit *commit;
+
+			commit = lookup_commit_reference_gently(sha1, 1);
+			if (!commit) {
+				error("tag '%s' does not point at a commit", refname);
+				return 0;
+			}
+			if (!has_commit(commit, filter->with_commit))
+				return 0;
+		}
+
 		if (!filter->lines) {
 			printf("%s\n", refname);
 			return 0;
@@ -79,7 +91,8 @@ static int show_reference(const char *refname, const
unsigned char *sha1,
 	return 0;
 }

-static int list_tags(const char *pattern, int lines)
+static int list_tags(const char *pattern, int lines,
+			struct commit_list *with_commit)
 {
 	struct tag_filter filter;

@@ -88,6 +101,7 @@ static int list_tags(const char *pattern, int lines)

 	filter.pattern = pattern;
 	filter.lines = lines;
+	filter.with_commit = with_commit;

 	for_each_tag_ref(show_reference, (void *) &filter);

@@ -360,6 +374,7 @@ int cmd_tag(int argc, const char **argv, const char
*prefix)
 		list = 0, delete = 0, verify = 0;
 	const char *msgfile = NULL, *keyid = NULL;
 	struct msg_arg msg = { 0, STRBUF_INIT };
+	struct commit_list *with_commit = NULL;
 	struct option options[] = {
 		OPT_BOOLEAN('l', NULL, &list, "list tag names"),
 		{ OPTION_INTEGER, 'n', NULL, &lines, NULL,
@@ -378,6 +393,14 @@ int cmd_tag(int argc, const char **argv, const char
*prefix)
 		OPT_STRING('u', NULL, &keyid, "key-id",
 					"use another key to sign the tag"),
 		OPT_BOOLEAN('f', NULL, &force, "replace the tag if exists"),
+
+		OPT_GROUP("Tag listing options"),
+		{
+			OPTION_CALLBACK, 0, "contains", &with_commit, "commit",
+			"print only tags that contain the commit",
+			PARSE_OPT_LASTARG_DEFAULT,
+			parse_opt_with_commit, (intptr_t)"HEAD",
+		},
 		OPT_END()
 	};

@@ -402,9 +425,12 @@ int cmd_tag(int argc, const char **argv, const char
*prefix)
 	if (list + delete + verify > 1)
 		usage_with_options(git_tag_usage, options);
 	if (list)
-		return list_tags(argv[0], lines == -1 ? 0 : lines);
+		return list_tags(argv[0], lines == -1 ? 0 : lines,
+				 with_commit);
 	if (lines != -1)
 		die("-n option is only allowed with -l.");
+	if (with_commit)
+		die("--contains 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 f377fea..69501e2 100755
--- a/t/t7004-tag.sh
+++ b/t/t7004-tag.sh
@@ -1090,6 +1090,121 @@ test_expect_success 'filename for the message is
relative to cwd' '
 	git cat-file tag tag-from-subdir-2 | grep "in sub directory"
 '

+# create a few more commits to test --contains
+
+hash1=$(git rev-parse HEAD)
+
+test_expect_success 'creating second commit and tag' '
+	echo foo-2.0 >foo &&
+	git add foo &&
+	git commit -m second
+	git tag v2.0
+'
+
+hash2=$(git rev-parse HEAD)
+
+test_expect_success 'creating third commit without tag' '
+	echo foo-dev >foo &&
+	git add foo &&
+	git commit -m third
+'
+
+hash3=$(git rev-parse HEAD)
+
+# simple linear checks of --continue
+
+cat > expected <<EOF
+v0.2.1
+v1.0
+v1.0.1
+v1.1.3
+v2.0
+EOF
+
+test_expect_success 'checking that first commit is in all tags (hash)' "
+	git tag -l --contains $hash1 v* >actual
+	test_cmp expected actual
+"
+
+# other ways of specifying the commit
+test_expect_success 'checking that first commit is in all tags (tag)' "
+	git tag -l --contains v1.0 v* >actual
+	test_cmp expected actual
+"
+
+test_expect_success 'checking that first commit is in all tags
(relative)' "
+	git tag -l --contains HEAD~2 v* >actual
+	test_cmp expected actual
+"
+
+cat > expected <<EOF
+v2.0
+EOF
+
+test_expect_success 'checking that second commit only has one tag' "
+	git tag -l --contains $hash2 v* >actual
+	test_cmp expected actual
+"
+
+
+cat > expected <<EOF
+EOF
+
+test_expect_success 'checking that third commit has no tags' "
+	git tag -l --contains $hash3 v* >actual
+	test_cmp expected actual
+"
+
+# how about a simple merge?
+
+test_expect_success 'creating simple branch' '
+	git branch stable v2.0 &&
+        git checkout stable &&
+	echo foo-3.0 > foo &&
+	git commit foo -m fourth
+	git tag v3.0
+'
+
+hash4=$(git rev-parse HEAD)
+
+cat > expected <<EOF
+v3.0
+EOF
+
+test_expect_success 'checking that branch head only has one tag' "
+	git tag -l --contains $hash4 v* >actual
+	test_cmp expected actual
+"
+
+test_expect_success 'merging original branch into this branch' '
+	git merge --strategy=ours master &&
+        git tag v4.0
+'
+
+cat > expected <<EOF
+v4.0
+EOF
+
+test_expect_success 'checking that original branch head has one tag now' "
+	git tag -l --contains $hash3 v* >actual
+	test_cmp expected actual
+"
+
+cat > expected <<EOF
+v0.2.1
+v1.0
+v1.0.1
+v1.1.3
+v2.0
+v3.0
+v4.0
+EOF
+
+test_expect_success 'checking that initial commit is in all tags' "
+	git tag -l --contains $hash1 v* >actual
+	test_cmp expected actual
+"
+
 # mixing modes and options:

 test_expect_success 'mixing incompatibles modes and options is forbidden' '
-- 
1.6.0.4

  parent reply	other threads:[~2009-01-23  0:51 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <1232671630-19683-1-git-send-email-goulding@vivisimo.com>
2009-01-23  0:48 ` [PATCH 2/3] Make has_commit non-static Jake Goulding
2009-01-23  1:13   ` Junio C Hamano
2009-01-23 22:41     ` Jake Goulding
     [not found] ` <1232671630-19683-2-git-send-email-goulding@vivisimo.com>
2009-01-23  0:48   ` Jake Goulding [this message]
2009-01-23  1:18     ` [PATCH 3/3] Add --contains flag to git tag Junio C Hamano
2009-01-26 14:13 [PATCH 1/3] Make opt_parse_with_commit non-static Jake Goulding
2009-01-26 14:13 ` [PATCH 2/3] Make has_commit non-static Jake Goulding
2009-01-26 14:13   ` [PATCH 3/3] Add --contains flag to git tag Jake Goulding

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=497913EE.9040608@vivisimo.com \
    --to=goulding@vivisimo.com \
    --cc=git@vger.kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.