wildmatch: change behavior of "foo**bar" in WM_PATHNAME mode

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>

Nguyễn Thái Ngọc Duy committed Oct 27, 2018 at 10:48 UTC e5bbe09e88545cd1a3bcf2b157f020f92e0b5def
4 files changed +6 -6
Documentation/gitignore.txt
+2 -1
@@ -129,7 +129,8 @@ full pathname may have special meaning:
129 matches zero or more directories. For example, "`a/**/b`"
130 matches "`a/b`", "`a/x/b`", "`a/x/y/b`" and so on.
131
132 - - Other consecutive asterisks are considered invalid.
132 + - Other consecutive asterisks are considered regular asterisks and
133 + will match according to the previous rules.
134
135 NOTES
136 -----
t/t3070-wildmatch.sh
+2 -2
@@ -238,7 +238,7 @@ match 0 0 0 0 foobar 'foo\*bar'
238 match 1 1 1 1 'f\oo' 'f\\oo'
239 match 1 1 1 1 ball '*[al]?'
240 match 0 0 0 0 ten '[ten]'
241 -match 0 0 1 1 ten '**[!te]'
241 +match 1 1 1 1 ten '**[!te]'
242 match 0 0 0 0 ten '**[!ten]'
243 match 1 1 1 1 ten 't[a-g]n'
244 match 0 0 0 0 ten 't[!a-g]n'
@@ -254,7 +254,7 @@ match 1 1 1 1 ']' ']'
254 # Extended slash-matching features
255 match 0 0 1 1 'foo/baz/bar' 'foo*bar'
256 match 0 0 1 1 'foo/baz/bar' 'foo**bar'
257 -match 0 0 1 1 'foobazbar' 'foo**bar'
257 +match 1 1 1 1 'foobazbar' 'foo**bar'
258 match 1 1 1 1 'foo/baz/bar' 'foo/**/bar'
259 match 1 1 0 0 'foo/baz/bar' 'foo/**/**/bar'
260 match 1 1 1 1 'foo/b/a/z/bar' 'foo/**/bar'
wildmatch.c
+2 -2
@@ -104,8 +104,8 @@ static int dowild(const uchar *p, const uchar *text, unsigned int flags)
104 dowild(p + 1, text, flags) == WM_MATCH)
105 return WM_MATCH;
106 match_slash = 1;
107 - } else
108 - return WM_ABORT_MALFORMED;
107 + } else /* WM_PATHNAME is set */
108 + match_slash = 0;
109 } else
110 /* without WM_PATHNAME, '*' == '**' */
111 match_slash = flags & WM_PATHNAME ? 0 : 1;
wildmatch.h
-1
@@ -4,7 +4,6 @@
4 #define WM_CASEFOLD 1
5 #define WM_PATHNAME 2
6
7 -#define WM_ABORT_MALFORMED 2
7 #define WM_NOMATCH 1
8 #define WM_MATCH 0
9 #define WM_ABORT_ALL -1