diff options
author | Nguyễn Thái Ngọc Duy <pclouds@gmail.com> | 2012-10-15 13:26:01 +0700 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2012-10-15 14:58:18 -0700 |
commit | 4c251e5cb5c245ee3bb98c7cedbe944df93e45f4 (patch) | |
tree | aefc5e6b1218874ae0e9559c428844b212de091d | |
parent | 40bbee0ab07d0ee4f21b11d597c878245c1b05a6 (diff) | |
download | git-4c251e5cb5c245ee3bb98c7cedbe944df93e45f4.tar.gz |
wildmatch: make /**/ match zero or more directories
"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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
-rwxr-xr-x | t/t3070-wildmatch.sh | 8 | ||||
-rw-r--r-- | wildmatch.c | 12 |
2 files changed, 19 insertions, 1 deletions
diff --git a/t/t3070-wildmatch.sh b/t/t3070-wildmatch.sh index 15848d5935..e6ad6f4703 100755 --- a/t/t3070-wildmatch.sh +++ b/t/t3070-wildmatch.sh @@ -63,11 +63,17 @@ match 1 1 ']' ']' match 0 0 'foo/baz/bar' 'foo*bar' match 0 0 'foo/baz/bar' 'foo**bar' match 0 1 'foobazbar' '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 x '/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 85bc0df8f8..3972e26e83 100644 --- a/wildmatch.c +++ b/wildmatch.c @@ -90,6 +90,18 @@ 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. + */ + if (p[0] == '/' && + dowild(p + 1, text, force_lower_case) == MATCH) + return MATCH; special = TRUE; } else return ABORT_MALFORMED; |