wildmatch: change behavior of "foo**bar" in WM_PATHNAME mode
authorNguyễn Thái Ngọc Duy <pclouds@gmail.com>
Sat, 27 Oct 2018 08:48:23 +0000 (10:48 +0200)
committerJunio C Hamano <gitster@pobox.com>
Mon, 29 Oct 2018 04:19:22 +0000 (13:19 +0900)
In WM_PATHNAME mode (or FNM_PATHNAME), '*' does not match '/' and '**'
can but only in three patterns:

- '**/' matches zero or more leading directories
- '/**/' matches zero or more directories in between
- '/**' matches zero or more trailing directories/files

When '**' is present but not in one of these patterns, the current
behavior is consider the pattern invalid and stop matching. In other
words, 'foo**bar' never matches anything, whatever you throw at it.

This behavior is arguably a bit confusing partly because we can't
really tell the user their pattern is invalid so that they can fix
it. So instead, tolerate it and make '**' act like two regular '*'s
(which is essentially the same as a single asterisk). This behavior
seems more predictable.

Noticed-by: dana <dana@dana.is>
Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Documentation/gitignore.txt
t/t3070-wildmatch.sh
wildmatch.c
wildmatch.h
index ff5d7f9ed6f089646807f93d59e35a10763e46c2..32b227942f808cf5e1a1f6006c3fd278d78e470d 100644 (file)
@@ -129,7 +129,8 @@ full pathname may have special meaning:
    matches zero or more directories. For example, "`a/**/b`"
    matches "`a/b`", "`a/x/b`", "`a/x/y/b`" and so on.
 
- - Other consecutive asterisks are considered invalid.
+ - Other consecutive asterisks are considered regular asterisks and
+   will match according to the previous rules.
 
 NOTES
 -----
index dce102130fb77ddda7cdc9aa9211507d9c2f2e09..7ba5d35eb270f2b3ef1e6586e545c1aeef485ee2 100755 (executable)
@@ -238,7 +238,7 @@ match 0 0 0 0 foobar 'foo\*bar'
 match 1 1 1 1 'f\oo' 'f\\oo'
 match 1 1 1 1 ball '*[al]?'
 match 0 0 0 0 ten '[ten]'
-match 0 0 1 1 ten '**[!te]'
+match 1 1 1 1 ten '**[!te]'
 match 0 0 0 0 ten '**[!ten]'
 match 1 1 1 1 ten 't[a-g]n'
 match 0 0 0 0 ten 't[!a-g]n'
@@ -254,7 +254,7 @@ match 1 1 1 1 ']' ']'
 # Extended slash-matching features
 match 0 0 1 1 'foo/baz/bar' 'foo*bar'
 match 0 0 1 1 'foo/baz/bar' 'foo**bar'
-match 0 0 1 1 'foobazbar' 'foo**bar'
+match 1 1 1 1 'foobazbar' 'foo**bar'
 match 1 1 1 1 'foo/baz/bar' 'foo/**/bar'
 match 1 1 0 0 'foo/baz/bar' 'foo/**/**/bar'
 match 1 1 1 1 'foo/b/a/z/bar' 'foo/**/bar'
index d074c1be1046f1aba11d21eb5b66a738590bc712..9e9e2a2f955d242cf994c5451c537a7f88539379 100644 (file)
@@ -104,8 +104,8 @@ static int dowild(const uchar *p, const uchar *text, unsigned int flags)
                                            dowild(p + 1, text, flags) == WM_MATCH)
                                                return WM_MATCH;
                                        match_slash = 1;
-                               } else
-                                       return WM_ABORT_MALFORMED;
+                               } else /* WM_PATHNAME is set */
+                                       match_slash = 0;
                        } else
                                /* without WM_PATHNAME, '*' == '**' */
                                match_slash = flags & WM_PATHNAME ? 0 : 1;
index b8c826aa684ec2cb0251af8e24a89689d66614b1..599369629824ec5f2bbb8e8affb19e8cc9058cc3 100644 (file)
@@ -4,7 +4,6 @@
 #define WM_CASEFOLD 1
 #define WM_PATHNAME 2
 
-#define WM_ABORT_MALFORMED 2
 #define WM_NOMATCH 1
 #define WM_MATCH 0
 #define WM_ABORT_ALL -1