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>
This commit is contained in:
Jeff King
2011-06-20 12:59:28 -04:00
committed by Junio C Hamano
parent daab4eeafa
commit 588d0e834b
3 changed files with 28 additions and 12 deletions

View File

@ -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;
@ -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."));