# HG changeset patch # User Siddharth Agarwal # Date 2014-06-25 21:50:48 # 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 --git a/mercurial/match.py b/mercurial/match.py --- a/mercurial/match.py +++ b/mercurial/match.py @@ -233,6 +233,10 @@ def _globre(pat): [^/]* >>> 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 @@ def _globre(pat): elif c == '*': if peek() == '*': i += 1 - res += '.*' + if peek() == '/': + i += 1 + res += '(?:.*/)?' + else: + res += '.*' else: res += '[^/]*' elif c == '?': diff --git a/tests/test-hgignore.t b/tests/test-hgignore.t --- a/tests/test-hgignore.t +++ b/tests/test-hgignore.t @@ -134,3 +134,17 @@ Check patterns that match only the direc ? 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