git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v16 10/14] ref-filter: add option to match literal pattern

From
Karthik Nayak <karthik.188@gmail.com>
Date
Sep 5, 2015, 18:52 UTC
Message-ID
<1441479135-5285-11-git-send-email-Karthik.188@gmail.com>
In-Reply-To
<1441479135-5285-1-git-send-email-Karthik.188@gmail.com>
From: Karthik Nayak <karthik.188@gmail.com>

Since 'ref-filter' only has an option to match path names add an option for plain fnmatch pattern-matching.

This is to support the pattern matching options which are used in `git tag -l` and `git branch -l` where we can match patterns like `git tag -l foo*` which would match all tags which has a "foo*" pattern.

Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Matthieu Moy <matthieu.moy@grenoble-inp.fr>
Signed-off-by: Karthik Nayak <karthik.188@gmail.com>
---
 builtin/for-each-ref.c |  1 +
 ref-filter.c           | 40 +++++++++++++++++++++++++++++++++++++---
 ref-filter.h           |  3 ++-
 3 files changed, 40 insertions(+), 4 deletions(-)
diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c
index 40f343b..4e9f6c2 100644
--- a/builtin/for-each-ref.c
+++ b/builtin/for-each-ref.c
@@ -68,6 +68,7 @@ int cmd_for_each_ref(int argc, const char **argv, const char *prefix)
 	git_config(git_default_config, NULL);
 
 	filter.name_patterns = argv;
+	filter.match_as_path = 1;
 	filter_refs(&array, &filter, FILTER_REFS_ALL | FILTER_REFS_INCLUDE_BROKEN);
 	ref_array_sort(sorting, &array);
 
diff --git a/ref-filter.c b/ref-filter.c
index 696c0c7..e3024d3 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -1167,9 +1167,33 @@ static int commit_contains(struct ref_filter *filter, struct commit *commit)
 
 /*
  * Return 1 if the refname matches one of the patterns, otherwise 0.
+ * A pattern can be a literal prefix (e.g. a refname "refs/heads/master"
+ * matches a pattern "refs/heads/mas") or a wildcard (e.g. the same ref
+ * matches "refs/heads/mas*", too).
+ */
+static int match_pattern(const char **patterns, const char *refname)
+{
+	/*
+	 * When no '--format' option is given we need to skip the prefix
+	 * for matching refs of tags and branches.
+	 */
+	(void)(skip_prefix(refname, "refs/tags/", &refname) ||
+	       skip_prefix(refname, "refs/heads/", &refname) ||
+	       skip_prefix(refname, "refs/remotes/", &refname) ||
+	       skip_prefix(refname, "refs/", &refname));
+
+	for (; *patterns; patterns++) {
+		if (!wildmatch(*patterns, refname, 0, NULL))
+			return 1;
+	}
+	return 0;
+}
+
+/*
+ * Return 1 if the refname matches one of the patterns, otherwise 0.
  * A pattern can be path prefix (e.g. a refname "refs/heads/master"
- * matches a pattern "refs/heads/") or a wildcard (e.g. the same ref
- * matches "refs/heads/m*",too).
+ * matches a pattern "refs/heads/" but not "refs/heads/m") or a
+ * wildcard (e.g. the same ref matches "refs/heads/m*", too).
  */
 static int match_name_as_path(const char **pattern, const char *refname)
 {
@@ -1190,6 +1214,16 @@ static int match_name_as_path(const char **pattern, const char *refname)
 	return 0;
 }
 
+/* Return 1 if the refname matches one of the patterns, otherwise 0. */
+static int filter_pattern_match(struct ref_filter *filter, const char *refname)
+{
+	if (!*filter->name_patterns)
+		return 1; /* No pattern always matches */
+	if (filter->match_as_path)
+		return match_name_as_path(filter->name_patterns, refname);
+	return match_pattern(filter->name_patterns, refname);
+}
+
 /*
  * Given a ref (sha1, refname), check if the ref belongs to the array
  * of sha1s. If the given ref is a tag, check if the given tag points
@@ -1292,7 +1326,7 @@ static int ref_filter_handler(const char *refname, const struct object_id *oid,
 	if (!(kind & filter->kind))
 		return 0;
 
-	if (*filter->name_patterns && !match_name_as_path(filter->name_patterns, refname))
+	if (!filter_pattern_match(filter, refname))
 		return 0;
 
 	if (filter->points_at.nr && !match_points_at(&filter->points_at, oid->hash, refname))
diff --git a/ref-filter.h b/ref-filter.h
index ef25b6e..a5cfa5e 100644
--- a/ref-filter.h
+++ b/ref-filter.h
@@ -59,7 +59,8 @@ struct ref_filter {
 	} merge;
 	struct commit *merge_commit;
 
-	unsigned int with_commit_tag_algo : 1;
+	unsigned int with_commit_tag_algo : 1,
+		match_as_path : 1;
 	unsigned int kind,
 		lines;
 };
-- 
2.5.1
Previous: Karthik NayakNext: Karthik Nayak
Message 15 of 30 in “port tag.c to use ref-filter APIs”
  1. 00/14 port tag.c to use ref-filter APIsKarthik Nayak, Sep 5, 2015
  2. 01/14 ref-filter: move `struct atom_value` to ref-filter.cKarthik Nayak, Sep 5, 2015
  3. 02/14 ref-filter: introduce ref_formatting_state and ref_formatting_stackKarthik Nayak, Sep 5, 2015
  4. 03/14 utf8: add function to align a string into given strbufKarthik Nayak, Sep 5, 2015
  5. 04/14 ref-filter: introduce handler function for each atomKarthik Nayak, Sep 5, 2015
  6. 05/14 ref-filter: introduce match_atom_name()Karthik Nayak, Sep 5, 2015
  7. Eric SunshineSep 6, 2015
  8. Karthik NayakSep 7, 2015
  9. 06/14 ref-filter: implement an `align` atomKarthik Nayak, Sep 5, 2015
  10. Eric SunshineSep 6, 2015
  11. Karthik NayakSep 7, 2015
  12. 07/14 ref-filter: add option to filter out tags, branches and remotesKarthik Nayak, Sep 5, 2015
  13. 08/14 ref-filter: add support for %(contents:lines=X)Karthik Nayak, Sep 5, 2015
  14. 09/14 ref-filter: add support to sort by versionKarthik Nayak, Sep 5, 2015
  15. 10/14 ref-filter: add option to match literal patternKarthik Nayak, Sep 5, 2015
  16. 11/14 tag.c: use 'ref-filter' data structuresKarthik Nayak, Sep 5, 2015
  17. 12/14 tag.c: use 'ref-filter' APIsKarthik Nayak, Sep 5, 2015
  18. 13/14 tag.c: implement '--format' optionKarthik Nayak, Sep 5, 2015
  19. 14/14 tag.c: implement '--merged' and '--no-merged' optionsKarthik Nayak, Sep 5, 2015
  20. Matthieu MoySep 6, 2015
  21. Karthik NayakSep 6, 2015
  22. Junio C HamanoSep 7, 2015
  23. Matthieu MoySep 7, 2015
  24. Karthik NayakSep 7, 2015
  25. Matthieu MoySep 7, 2015
  26. Karthik NayakSep 8, 2015
  27. Junio C HamanoSep 8, 2015
  28. Karthik NayakSep 9, 2015
  29. Junio C HamanoSep 9, 2015
  30. Junio C HamanoSep 8, 2015

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.