git-describe: Add a --match option to limit considered tags.

Signed-off-by: Pierre Habouzit <madcoder@debian.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
diff --git a/builtin-describe.c b/builtin-describe.c
index 7a148a2..18eab47 100644
--- a/builtin-describe.c
+++ b/builtin-describe.c
@@ -19,6 +19,7 @@
 static int tags;	/* But allow any tags if --tags is specified */
 static int abbrev = DEFAULT_ABBREV;
 static int max_candidates = 10;
+const char *pattern = NULL;
 
 struct commit_name {
 	int prio; /* annotated tag = 2, tag = 1, head = 0 */
@@ -57,9 +58,11 @@
 	 * Otherwise only annotated tags are used.
 	 */
 	if (!prefixcmp(path, "refs/tags/")) {
-		if (object->type == OBJ_TAG)
+		if (object->type == OBJ_TAG) {
 			prio = 2;
-		else
+			if (pattern && fnmatch(pattern, path + 10, 0))
+				prio = 0;
+		} else
 			prio = 1;
 	}
 	else
@@ -253,7 +256,9 @@
 		OPT_BOOLEAN(0, "tags",       &tags, "use any tag in .git/refs/tags"),
 		OPT__ABBREV(&abbrev),
 		OPT_INTEGER(0, "candidates", &max_candidates,
-					"consider <n> most recent tags (default: 10)"),
+			    "consider <n> most recent tags (default: 10)"),
+		OPT_STRING(0, "match",       &pattern, "pattern",
+			   "only consider tags matching <pattern>"),
 		OPT_END(),
 	};
 
@@ -266,12 +271,18 @@
 	save_commit_buffer = 0;
 
 	if (contains) {
-		const char **args = xmalloc((4 + argc) * sizeof(char*));
+		const char **args = xmalloc((5 + argc) * sizeof(char*));
 		int i = 0;
 		args[i++] = "name-rev";
 		args[i++] = "--name-only";
-		if (!all)
+		if (!all) {
 			args[i++] = "--tags";
+			if (pattern) {
+				char *s = xmalloc(strlen("--refs=refs/tags/") + strlen(pattern) + 1);
+				sprintf(s, "--refs=refs/tags/%s", pattern);
+				args[i++] = s;
+			}
+		}
 		memcpy(args + i, argv, argc * sizeof(char*));
 		args[i + argc] = NULL;
 		return cmd_name_rev(i + argc, args, prefix);