git.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: Jeff King <peff@peff.net>
To: Junio C Hamano <gitster@pobox.com>
Cc: Michael J Gruber <git@drmicha.warpmail.net>,
	Johannes Sixt <j.sixt@viscovery.net>,
	Boris Faure <billiob@gmail.com>,
	git@vger.kernel.org
Subject: [PATCH] tag: accept multiple patterns for --list
Date: Mon, 20 Jun 2011 12:59:28 -0400	[thread overview]
Message-ID: <20110620165928.GA20887@sigill.intra.peff.net> (raw)
In-Reply-To: <7v1uyoecgn.fsf@alter.siamese.dyndns.org>

On Mon, Jun 20, 2011 at 08:42:32AM -0700, Junio C Hamano wrote:

> Jeff King <peff@peff.net> writes:
> 
> > ? For "tag -l", we seem to silently ignore any arguments past the first:
> >
> >   $ git tag -l 'v1.7.4.*' 'v1.7.5.*'
> >   v1.7.4.1
> >   v1.7.4.2
> >   v1.7.4.3
> >   v1.7.4.4
> >   v1.7.4.5
> >
> > We should at least warn and say "your second argument is being ignored"
> > or show the usage message.
> 
> I think it is just a bug; no need for "being ignored" warning.
> 
> > But perhaps it is even friendlier to accept
> > a list of patterns.
> 
> Yes indeed; please make it so ;-)

Here's a patch.

-- >8 --
Subject: [PATCH] tag: accept multiple patterns for --list

Until now, "git tag -l foo* bar*" would silently ignore the
second argument, showing only refs starting with "foo". It's
not just unfriendly not to take a second pattern; we
actually generated subtly wrong results (from the user's
perspective) because some of the requested tags were
omitted.

This patch allows an arbitrary number of patterns on the
command line; if any of them matches, the ref is shown.

While we're tweaking the documentation, let's also make it
clear that the pattern is fnmatch.

Signed-off-by: Jeff King <peff@peff.net>
---
 Documentation/git-tag.txt |    9 ++++++---
 builtin/tag.c             |   26 +++++++++++++++++---------
 t/t7004-tag.sh            |    5 +++++
 3 files changed, 28 insertions(+), 12 deletions(-)

diff --git a/Documentation/git-tag.txt b/Documentation/git-tag.txt
index d82f621..fb1c0ac 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>]
 	<tagname> [<commit> | <object>]
 'git tag' -d <tagname>...
-'git tag' [-n[<num>]] -l [--contains <commit>] [<pattern>]
+'git tag' [-n[<num>]] -l [--contains <commit>] [<pattern>...]
 'git tag' -v <tagname>...
 
 DESCRIPTION
@@ -69,8 +69,11 @@ OPTIONS
 	If the tag is not annotated, the commit message is displayed instead.
 
 -l <pattern>::
-	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.
+	List tags with names that match the given pattern (or all if no
+	pattern is given).  Running "git tag" without arguments also
+	lists all tags. The pattern is a shell wildcard (i.e., matched
+	using fnmatch(3)).  Multiple patterns may be given; if any of
+	them matches, the tag is shown.
 
 --contains <commit>::
 	Only list tags which contain the specified commit.
diff --git a/builtin/tag.c b/builtin/tag.c
index ec926fc..cef2726 100644
--- a/builtin/tag.c
+++ b/builtin/tag.c
@@ -16,7 +16,7 @@
 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>]] [<pattern>...]",
 	"git tag -v <tagname>...",
 	NULL
 };
@@ -24,17 +24,28 @@ static const char * const git_tag_usage[] = {
 static char signingkey[1000];
 
 struct tag_filter {
-	const char *pattern;
+	const char **patterns;
 	int lines;
 	struct commit_list *with_commit;
 };
 
+static int match_pattern(const char **patterns, const char *ref)
+{
+	/* no pattern means match everything */
+	if (!*patterns)
+		return 1;
+	for (; *patterns; patterns++)
+		if (!fnmatch(*patterns, ref, 0))
+			return 1;
+	return 0;
+}
+
 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)) {
+	if (match_pattern(filter->patterns, refname)) {
 		int i;
 		unsigned long size;
 		enum object_type type;
@@ -88,15 +99,12 @@ 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 **patterns, int lines,
 			struct commit_list *with_commit)
 {
 	struct tag_filter filter;
 
-	if (pattern == NULL)
-		pattern = "*";
-
-	filter.pattern = pattern;
+	filter.patterns = patterns;
 	filter.lines = lines;
 	filter.with_commit = with_commit;
 
@@ -425,7 +433,7 @@ 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, lines == -1 ? 0 : lines,
 				 with_commit);
 	if (lines != -1)
 		die(_("-n option is only allowed with -l."));
diff --git a/t/t7004-tag.sh b/t/t7004-tag.sh
index 2ac1c66..097ce2b 100755
--- a/t/t7004-tag.sh
+++ b/t/t7004-tag.sh
@@ -257,6 +257,11 @@ test_expect_success \
 	test_cmp expect actual
 '
 
+test_expect_success 'tag -l can accept multiple patterns' '
+	git tag -l "v1*" "v0*" >actual &&
+	test_cmp expect actual
+'
+
 # creating and verifying lightweight tags:
 
 test_expect_success \
-- 
1.7.6.rc1.38.g97f64.dirty

  reply	other threads:[~2011-06-20 16:59 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2011-06-19 19:19 [PATCH/RFC] branch: add optional parameter to -r to specify remote Boris Faure
2011-06-19 19:19 ` Boris Faure
2011-06-19 22:32   ` Junio C Hamano
2011-06-20  6:40     ` Johannes Sixt
2011-06-20  7:03       ` Jeff King
2011-06-20 11:08         ` Michael J Gruber
2011-06-20 13:09           ` Jeff King
2011-06-20 15:42             ` Junio C Hamano
2011-06-20 16:59               ` Jeff King [this message]
2011-06-20 15:49           ` Junio C Hamano
2011-06-20 15:39         ` Junio C Hamano
2011-06-20 19:12     ` Boris Faure

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=20110620165928.GA20887@sigill.intra.peff.net \
    --to=peff@peff.net \
    --cc=billiob@gmail.com \
    --cc=git@drmicha.warpmail.net \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    --cc=j.sixt@viscovery.net \
    /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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).