Skip to content

Commit

Permalink
tag: accept multiple patterns for --list
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
Jeff King authored and Junio C Hamano committed Jun 20, 2011
1 parent daab4ee commit 588d0e8
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 12 deletions.
9 changes: 6 additions & 3 deletions Documentation/git-tag.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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.
Expand Down
26 changes: 17 additions & 9 deletions builtin/tag.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,25 +16,36 @@
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
};

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;
Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -414,7 +422,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."));
Expand Down
5 changes: 5 additions & 0 deletions t/t7004-tag.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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 \
Expand Down

0 comments on commit 588d0e8

Please sign in to comment.