[PATCH] match: adding support for repository-root-based globs
Rodrigo Damazio Bovendorp
rdamazio at google.com
Tue Oct 25 07:41:27 UTC 2016
# HG changeset patch
# User Rodrigo Damazio Bovendorp <rdamazio at google.com>
# Date 1475944120 25200
# Sat Oct 08 09:28:40 2016 -0700
# Node ID e8454de81600e092f05aa22ecbac32925b70d074
# Parent 260af19891f2bed679a662be07d1379bb8207592
match: adding support for repository-root-based globs
The broader plan is to add explicit base directories for all patterns:
============ ======== ======= ===========
pattern type root-ed cwd-ed any-of-path
============ ======== ======= ===========
wildcard rootglob cwdglob anyglob
regexp rootre cwdre anyre
raw string rootpath cwdpath anypath
============ ======== ======= ===========
(table by foozy)
I'm starting by adding rootglob.
One important characteristic and difference from the older glob types is
that * will never match recursively, even when the glob is used as an include
pattern.
diff --git a/mercurial/help/patterns.txt b/mercurial/help/patterns.txt
--- a/mercurial/help/patterns.txt
+++ b/mercurial/help/patterns.txt
@@ -38,7 +38,9 @@
All patterns, except for ``glob:`` specified in command line (not for
``-I`` or ``-X`` options), can match also against directories: files
-under matched directories are treated as matched.
+under matched directories are treated as matched. ``rootglob:`` will not match
+subdirectories either on the command line or via ``-I`` or ``-X`` unless ** is
+used.
Plain examples::
@@ -48,13 +50,16 @@
Glob examples::
- glob:*.c any name ending in ".c" in the current directory
- *.c any name ending in ".c" in the current directory
- **.c any name ending in ".c" in any subdirectory of the
- current directory including itself.
- foo/*.c any name ending in ".c" in the directory foo
- foo/**.c any name ending in ".c" in any subdirectory of foo
- including itself.
+ glob:*.c any name ending in ".c" in the current directory
+ *.c any name ending in ".c" in the current directory
+ **.c any name ending in ".c" in any subdirectory of the
+ current directory including itself.
+ foo/*.c any name ending in ".c" in the directory foo
+ foo/**.c any name ending in ".c" in any subdirectory of foo
+ including itself.
+ rootglob:*.c any name ending in ".c" in the repository root
+ rootglob:foo/** all files inside foo and its subdirectories
+ rootglob:foo/* all files inside foo but not its subdirectories
Regexp examples::
diff --git a/mercurial/match.py b/mercurial/match.py
--- a/mercurial/match.py
+++ b/mercurial/match.py
@@ -105,6 +105,8 @@
'glob:<glob>' - a glob relative to cwd
're:<regexp>' - a regular expression
'path:<path>' - a path relative to repository root
+ 'rootglob:<path>' - a glob relative to repository root. Unlike glob, *
+ will never match subdirectories.
'relglob:<glob>' - an unrooted glob (*.c matches C files in all dirs)
'relpath:<path>' - a path relative to cwd
'relre:<regexp>' - a regexp that needn't match the start of a name
@@ -286,7 +288,7 @@
for kind, pat in [_patsplit(p, default) for p in patterns]:
if kind in ('glob', 'relpath'):
pat = pathutil.canonpath(root, cwd, pat, auditor)
- elif kind in ('relglob', 'path'):
+ elif kind in ('relglob', 'path', 'rootglob'):
pat = util.normpath(pat)
elif kind in ('listfile', 'listfile0'):
try:
@@ -447,7 +449,8 @@
if ':' in pattern:
kind, pat = pattern.split(':', 1)
if kind in ('re', 'glob', 'path', 'relglob', 'relpath', 'relre',
- 'listfile', 'listfile0', 'set', 'include', 'subinclude'):
+ 'listfile', 'listfile0', 'set', 'include', 'subinclude',
+ 'rootglob'):
return kind, pat
return default, pattern
@@ -540,6 +543,8 @@
if pat == '.':
return ''
return '^' + util.re.escape(pat) + '(?:/|$)'
+ if kind == 'rootglob':
+ return '^' + _globre(pat) + '$'
if kind == 'relglob':
return '(?:|.*/)' + _globre(pat) + globsuffix
if kind == 'relpath':
@@ -614,6 +619,8 @@
>>> _roots([('glob', 'g/*', ''), ('glob', 'g', ''), ('glob', 'g*', '')])
['g', 'g', '.']
+ >>> _roots([('rootglob', 'g/*', ''), ('rootglob', 'g'), ('glob', 'g*', '')])
+ ['g', 'g', '.']
>>> _roots([('relpath', 'r', ''), ('path', 'p/p', ''), ('path', '', '')])
['r', 'p/p', '.']
>>> _roots([('relglob', 'rg*', ''), ('re', 're/', ''), ('relre', 'rr', '')])
@@ -621,7 +628,7 @@
'''
r = []
for kind, pat, source in kindpats:
- if kind == 'glob': # find the non-glob prefix
+ if kind == 'glob' or kind == 'rootglob': # find the non-glob prefix
root = []
for p in pat.split('/'):
if '[' in p or '{' in p or '*' in p or '?' in p:
@@ -636,7 +643,7 @@
def _anypats(kindpats):
for kind, pat, source in kindpats:
- if kind in ('glob', 're', 'relglob', 'relre', 'set'):
+ if kind in ('glob', 're', 'relglob', 'relre', 'set', 'rootglob'):
return True
_commentre = None
diff --git a/tests/test-walk.t b/tests/test-walk.t
--- a/tests/test-walk.t
+++ b/tests/test-walk.t
@@ -112,6 +112,69 @@
f beans/navy ../beans/navy
f beans/pinto ../beans/pinto
f beans/turtle ../beans/turtle
+
+ $ hg debugwalk -I 'rootglob:*'
+ f fennel ../fennel
+ f fenugreek ../fenugreek
+ f fiddlehead ../fiddlehead
+ $ hg debugwalk -I 'rootglob:sk*nk'
+ $ hg debugwalk 'rootglob:sk*nk'
+ $ hg debugwalk -I 'rootglob:*k'
+ f fenugreek ../fenugreek
+ $ hg debugwalk -I 'rootglob:mammals/*'
+ f mammals/skunk skunk
+ $ hg debugwalk 'rootglob:mammals/*'
+ f mammals/skunk skunk
+ $ hg debugwalk -I 'rootglob:**/*u*'
+ f beans/turtle ../beans/turtle
+ f fenugreek ../fenugreek
+ f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
+ f mammals/skunk skunk
+ $ hg debugwalk -I 'rootglob:mammals/**'
+ f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
+ f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
+ f mammals/Procyonidae/raccoon Procyonidae/raccoon
+ f mammals/skunk skunk
+ $ hg debugwalk -I 'rootglob:*a*/*u*'
+ f beans/turtle ../beans/turtle
+ f mammals/skunk skunk
+ $ hg debugwalk 'rootglob:*a*/*u*'
+ f beans/turtle ../beans/turtle
+ f mammals/skunk skunk
+ $ hg debugwalk -X 'rootglob:mammals/*'
+ f beans/black ../beans/black
+ f beans/borlotti ../beans/borlotti
+ f beans/kidney ../beans/kidney
+ f beans/navy ../beans/navy
+ f beans/pinto ../beans/pinto
+ f beans/turtle ../beans/turtle
+ f fennel ../fennel
+ f fenugreek ../fenugreek
+ f fiddlehead ../fiddlehead
+ f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
+ f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
+ f mammals/Procyonidae/raccoon Procyonidae/raccoon
+ $ hg debugwalk -X 'rootglob:mammals/**'
+ f beans/black ../beans/black
+ f beans/borlotti ../beans/borlotti
+ f beans/kidney ../beans/kidney
+ f beans/navy ../beans/navy
+ f beans/pinto ../beans/pinto
+ f beans/turtle ../beans/turtle
+ f fennel ../fennel
+ f fenugreek ../fenugreek
+ f fiddlehead ../fiddlehead
+ $ hg debugwalk -X 'rootglob:**/*u*'
+ f beans/black ../beans/black
+ f beans/borlotti ../beans/borlotti
+ f beans/kidney ../beans/kidney
+ f beans/navy ../beans/navy
+ f beans/pinto ../beans/pinto
+ f fennel ../fennel
+ f fiddlehead ../fiddlehead
+ f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
+ f mammals/Procyonidae/raccoon Procyonidae/raccoon
+
$ hg debugwalk .
f mammals/Procyonidae/cacomistle Procyonidae/cacomistle
f mammals/Procyonidae/coatimundi Procyonidae/coatimundi
More information about the Mercurial-devel
mailing list