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

[PATCH 7/8] wildmatch: make /**/ match zero or more directories

From
Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Date
Oct 9, 2012, 03:09 UTC
Message-ID
<1349752147-13314-8-git-send-email-pclouds@gmail.com>
In-Reply-To
<1349752147-13314-1-git-send-email-pclouds@gmail.com>

"foo/**/bar" matches "foo/x/bar", "foo/x/y/bar"... but not "foo/bar". We make a special case, when foo/**/ is detected (and "foo/" part is already matched), try matching "bar" with the rest of the string.

"Match one or more directories" semantics can be easily achieved using "foo/*/**/bar".

This also makes "**/foo" match "foo" in addition to "x/foo", "x/y/foo"..

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 t/t3070-wildmatch.sh |  8 +++++++-
 wildmatch.c          | 17 +++++++++++++++++
 2 files changed, 24 insertions(+), 1 deletion(-)
diff --git a/t/t3070-wildmatch.sh b/t/t3070-wildmatch.sh
index d320f84..a247a36 100755
--- a/t/t3070-wildmatch.sh
+++ b/t/t3070-wildmatch.sh
@@ -52,11 +52,17 @@ match 1 1 ']' ']'
 # Extended slash-matching features
 match 0 0 'foo/baz/bar' 'foo*bar'
 match 0 0 'foo/baz/bar' 'foo**bar'
+match 1 1 'foo/baz/bar' 'foo/**/bar'
+match 1 0 'foo/baz/bar' 'foo/**/**/bar'
+match 1 0 'foo/b/a/z/bar' 'foo/**/bar'
+match 1 0 'foo/b/a/z/bar' 'foo/**/**/bar'
+match 1 0 'foo/bar' 'foo/**/bar'
+match 1 0 'foo/bar' 'foo/**/**/bar'
 match 0 0 'foo/bar' 'foo?bar'
 match 0 0 'foo/bar' 'foo[/]bar'
 match 0 0 'foo/bar' 'f[^eiu][^eiu][^eiu][^eiu][^eiu]r'
 match 1 1 'foo-bar' 'f[^eiu][^eiu][^eiu][^eiu][^eiu]r'
-match 0 0 'foo' '**/foo'
+match 1 0 'foo' '**/foo'
 match 1 1 '/foo' '**/foo'
 match 1 0 'bar/baz/foo' '**/foo'
 match 0 0 'bar/baz/foo' '*/foo'
diff --git a/wildmatch.c b/wildmatch.c
index 1b39346..4069b2d 100644
--- a/wildmatch.c
+++ b/wildmatch.c
@@ -96,6 +96,23 @@ static int dowild(const uchar *p, const uchar *text, int force_lower_case)
 		if ((prev_p == text || *prev_p == '/') ||
 		    (*p == '\0' || *p == '/' ||
 		     (p[0] == '\\' && p[1] == '/'))) {
+			/*
+			 * Assuming we already match 'foo/' and are at
+			 * <star star slash>, just assume it matches
+			 * nothing and go ahead match the rest of the
+			 * pattern with the remaining string. This
+			 * helps make foo/<*><*>/bar (<> because
+			 * otherwise it breaks C comment syntax) match
+			 * both foo/bar and foo/a/bar.
+			 *
+			 * Crazy patterns like /<*><*>/<*><*>/ are
+			 * treated like /<*><*>/. But undefined
+			 * behavior is even appropriate for people
+			 * writing such a pattern.
+			 */
+			if (p[0] == '/' &&
+			    dowild(p + 1, text, force_lower_case) == TRUE)
+				return TRUE;
 		    special = TRUE;
 		} else
 		    special = FALSE;
-- 
1.8.0.rc0.29.g1fdd78f
Previous: Nguyễn Thái Ngọc DuyNext: Nguyễn Thái Ngọc Duy
Message 12 of 15 in “wildmatch take 3”
  1. 0/8 wildmatch take 3Nguyễn Thái Ngọc Duy, Oct 9, 2012
  2. 1/8 Import wildmatch from rsyncNguyễn Thái Ngọc Duy, Oct 9, 2012
  3. 2/8 wildmatch: remove unnecessary functionsNguyễn Thái Ngọc Duy, Oct 9, 2012
  4. 3/8 Integrate wildmatch to gitNguyễn Thái Ngọc Duy, Oct 9, 2012
  5. 4/8 wildmatch: remove static variable force_lower_caseNguyễn Thái Ngọc Duy, Oct 9, 2012
  6. Junio C HamanoOct 9, 2012
  7. Nguyen Thai Ngoc DuyOct 10, 2012
  8. Junio C HamanoOct 10, 2012
  9. Nguyen Thai Ngoc DuyOct 10, 2012
  10. 5/8 wildmatch: fix case-insensitive matchingNguyễn Thái Ngọc Duy, Oct 9, 2012
  11. 6/8 wildmatch: adjust "**" behaviorNguyễn Thái Ngọc Duy, Oct 9, 2012
  12. 7/8 wildmatch: make /**/ match zero or more directoriesNguyễn Thái Ngọc Duy, Oct 9, 2012
  13. 8/8 Support "**" wildcard in .gitignore and .gitattributesNguyễn Thái Ngọc Duy, Oct 9, 2012
  14. Michael HaggertyOct 9, 2012
  15. Nguyen Thai Ngoc DuyOct 10, 2012

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.