# HG changeset patch # User Siddharth Agarwal # Date 1403733048 25200 # Node ID a4b67bf1f0a5051736c14d9c13fae50fd5f5e464 # Parent b2dc026a9bd2620a0b8c1f28caf5a608352960ab match: make glob '**/' match the empty string Previously, a glob pattern of the form 'foo/**/bar' would match 'foo/a/bar' but not 'foo/bar'. That was because the '**' in 'foo/**/bar' would be translated to '.*', making the final regex pattern 'foo/.*/bar'. That pattern doesn't match the string 'foo/bar'. This is a bug because the '**/' glob matches the empty string in standard Unix shells like bash and zsh. Fix that by making the ending '/' optional if an empty string can be matched. diff -r b2dc026a9bd2 -r a4b67bf1f0a5 mercurial/match.py --- a/mercurial/match.py Wed Jun 18 19:46:18 2014 -0500 +++ b/mercurial/match.py Wed Jun 25 14:50:48 2014 -0700 @@ -233,6 +233,10 @@ [^/]* >>> print _globre(r'**') .* + >>> print _globre(r'**/a') + (?:.*/)?a + >>> print _globre(r'a/**/b') + a\/(?:.*/)?b >>> print _globre(r'[a*?!^][^b][!c]') [a*?!^][\^b][^c] >>> print _globre(r'{a,b}') @@ -254,7 +258,11 @@ elif c == '*': if peek() == '*': i += 1 - res += '.*' + if peek() == '/': + i += 1 + res += '(?:.*/)?' + else: + res += '.*' else: res += '[^/]*' elif c == '?': diff -r b2dc026a9bd2 -r a4b67bf1f0a5 tests/test-hgignore.t --- a/tests/test-hgignore.t Wed Jun 18 19:46:18 2014 -0500 +++ b/tests/test-hgignore.t Wed Jun 25 14:50:48 2014 -0700 @@ -134,3 +134,17 @@ ? a.c ? a.o ? syntax + +Check recursive glob pattern matches no directories (dir/**/c.o matches dir/c.o) + + $ echo "syntax: glob" > .hgignore + $ echo "dir/**/c.o" >> .hgignore + $ touch dir/c.o + $ mkdir dir/subdir + $ touch dir/subdir/c.o + $ hg status + A dir/b.o + ? .hgignore + ? a.c + ? a.o + ? syntax