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> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Jeff King committed
Jun 20, 2011 at 12:59 UTC
588d0e834b244565863fa80e6c48c20e0db9b62f
3 files changed
+28
-12
Documentation/git-tag.txt
+6
-3
@@ -12,7 +12,7 @@ SYNOPSIS
12
'git tag' [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>]
13
<tagname> [<commit> | <object>]
14
'git tag' -d <tagname>...
15
-'git tag' [-n[<num>]] -l [--contains <commit>] [<pattern>]
15
+'git tag' [-n[<num>]] -l [--contains <commit>] [<pattern>...]
16
'git tag' -v <tagname>...
17
18
DESCRIPTION
@@ -69,8 +69,11 @@ OPTIONS
69
If the tag is not annotated, the commit message is displayed instead.
70
71
-l <pattern>::
72
- List tags with names that match the given pattern (or all if no pattern is given).
73
- Typing "git tag" without arguments, also lists all tags.
72
+ List tags with names that match the given pattern (or all if no
73
+ pattern is given). Running "git tag" without arguments also
74
+ lists all tags. The pattern is a shell wildcard (i.e., matched
75
+ using fnmatch(3)). Multiple patterns may be given; if any of
76
+ them matches, the tag is shown.
77
78
--contains <commit>::
79
Only list tags which contain the specified commit.
builtin/tag.c
+17
-9
@@ -16,7 +16,7 @@
16
static const char * const git_tag_usage[] = {
17
"git tag [-a|-s|-u <key-id>] [-f] [-m <msg>|-F <file>] <tagname> [<head>]",
18
"git tag -d <tagname>...",
19
- "git tag -l [-n[<num>]] [<pattern>]",
19
+ "git tag -l [-n[<num>]] [<pattern>...]",
20
"git tag -v <tagname>...",
21
NULL
22
};
@@ -24,17 +24,28 @@ static const char * const git_tag_usage[] = {
24
static char signingkey[1000];
25
26
struct tag_filter {
27
- const char *pattern;
27
+ const char **patterns;
28
int lines;
29
struct commit_list *with_commit;
30
};
31
32
+static int match_pattern(const char **patterns, const char *ref)
33
+{
34
+ /* no pattern means match everything */
35
+ if (!*patterns)
36
+ return 1;
37
+ for (; *patterns; patterns++)
38
+ if (!fnmatch(*patterns, ref, 0))
39
+ return 1;
40
+ return 0;
41
+}
42
+
43
static int show_reference(const char *refname, const unsigned char *sha1,
44
int flag, void *cb_data)
45
{
46
struct tag_filter *filter = cb_data;
47
37
- if (!fnmatch(filter->pattern, refname, 0)) {
48
+ if (match_pattern(filter->patterns, refname)) {
49
int i;
50
unsigned long size;
51
enum object_type type;
@@ -88,15 +99,12 @@ static int show_reference(const char *refname, const unsigned char *sha1,
99
return 0;
100
}
101
91
-static int list_tags(const char *pattern, int lines,
102
+static int list_tags(const char **patterns, int lines,
103
struct commit_list *with_commit)
104
{
105
struct tag_filter filter;
106
96
- if (pattern == NULL)
97
- pattern = "*";
98
-
99
- filter.pattern = pattern;
107
+ filter.patterns = patterns;
108
filter.lines = lines;
109
filter.with_commit = with_commit;
110
@@ -414,7 +422,7 @@ int cmd_tag(int argc, const char **argv, const char *prefix)
422
if (list + delete + verify > 1)
423
usage_with_options(git_tag_usage, options);
424
if (list)
417
- return list_tags(argv[0], lines == -1 ? 0 : lines,
425
+ return list_tags(argv, lines == -1 ? 0 : lines,
426
with_commit);
427
if (lines != -1)
428
die(_("-n option is only allowed with -l."));
t/t7004-tag.sh
+5
@@ -257,6 +257,11 @@ test_expect_success \
257
test_cmp expect actual
258
'
259
260
+test_expect_success 'tag -l can accept multiple patterns' '
261
+ git tag -l "v1*" "v0*" >actual &&
262
+ test_cmp expect actual
263
+'
264
+
265
# creating and verifying lightweight tags:
266
267
test_expect_success \