Submitter | via Mercurial-devel |
---|---|
Date | Nov. 15, 2016, 4:59 a.m. |
Message ID | <93434cce258a797fcc39.1479185949@rdamazio.mtv.corp.google.com> |
Download | mbox | patch |
Permalink | /patch/17583/ |
State | Changes Requested |
Headers | show |
Comments
On 11/15/2016 04:59 AM, Rodrigo Damazio Bovendorp via Mercurial-devel wrote: > # HG changeset patch > # User Rodrigo Damazio Bovendorp <rdamazio@google.com> > # Date 1475944120 25200 > # Sat Oct 08 09:28:40 2016 -0700 > # Node ID 93434cce258a797fcc3997c0af994a524695e273 > # Parent b032a7b676c6637b2ac6f3ef29431013b15a08f9 > match: adding support for repository-root-based globs I saw that Foozy created a plan page about this, it seem to have good summary of the current matcher we have but from my reading it is a bit fuzzy about the current variation we have in behavior from one command to another and from flag usage. I think it is important to have a global view of the situation here to be able to efficiently tackle the issues at hand. I'm traveling in Marocco with poor internet connectivity until the end of the week. I would prefer if we could not take a final discussion until I've time to discuss it more at the beginning of next week. Sorry for the extra delay. > 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 rootglob does a *full* match, meaning that a * at the end will never > match recursively, even when the glob is used as an include pattern. > > diff -r b032a7b676c6 -r 93434cce258a mercurial/help/patterns.txt > --- a/mercurial/help/patterns.txt Tue Nov 01 18:54:03 2016 -0700 > +++ b/mercurial/help/patterns.txt Sat Oct 08 09:28:40 2016 -0700 > @@ -40,6 +40,11 @@ > ``-I`` or ``-X`` options), can match also against directories: files > under matched directories are treated as matched. > > +For ``-I`` and ``-X`` options, ``glob:`` will match directories recursively. > +``rootglob:``, on the other end, does a full match, meaning that all files, in > +directories or subdirectories, will only match if the entire expression matches. > +In that case, ``**`` can be used to obtain recursiveness. > + > Plain examples:: > > path:foo/bar a name bar in a directory named foo in the root > @@ -48,13 +53,18 @@ > > 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/* any file in directory foo plus all its subdirectories, > + recursively > + 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 but not its subdirectories > + rootglob:foo/** all files inside foo and its subdirectories > > Regexp examples:: > > diff -r b032a7b676c6 -r 93434cce258a mercurial/match.py > --- a/mercurial/match.py Tue Nov 01 18:54:03 2016 -0700 > +++ b/mercurial/match.py Sat Oct 08 09:28:40 2016 -0700 > @@ -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', '')]) > + ['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 -r b032a7b676c6 -r 93434cce258a tests/test-walk.t > --- a/tests/test-walk.t Tue Nov 01 18:54:03 2016 -0700 > +++ b/tests/test-walk.t Sat Oct 08 09:28:40 2016 -0700 > @@ -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 > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel@mercurial-scm.org > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel >
Pierre-Yves, hope you had a great time in Morocco :) Any other comments here? On Tue, Nov 15, 2016 at 6:21 AM, Pierre-Yves David < pierre-yves.david@ens-lyon.org> wrote: > > > On 11/15/2016 04:59 AM, Rodrigo Damazio Bovendorp via Mercurial-devel > wrote: > >> # HG changeset patch >> # User Rodrigo Damazio Bovendorp <rdamazio@google.com> >> # Date 1475944120 25200 >> # Sat Oct 08 09:28:40 2016 -0700 >> # Node ID 93434cce258a797fcc3997c0af994a524695e273 >> # Parent b032a7b676c6637b2ac6f3ef29431013b15a08f9 >> match: adding support for repository-root-based globs >> > > I saw that Foozy created a plan page about this, it seem to have good > summary of the current matcher we have but from my reading it is a bit > fuzzy about the current variation we have in behavior from one command to > another and from flag usage. I think it is important to have a global view > of the situation here to be able to efficiently tackle the issues at hand. > > I'm traveling in Marocco with poor internet connectivity until the end of > the week. I would prefer if we could not take a final discussion until I've > time to discuss it more at the beginning of next week. Sorry for the extra > delay. > > 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 rootglob does a *full* match, meaning that a * at the end will never >> match recursively, even when the glob is used as an include pattern. >> >> diff -r b032a7b676c6 -r 93434cce258a mercurial/help/patterns.txt >> --- a/mercurial/help/patterns.txt Tue Nov 01 18:54:03 2016 -0700 >> +++ b/mercurial/help/patterns.txt Sat Oct 08 09:28:40 2016 -0700 >> @@ -40,6 +40,11 @@ >> ``-I`` or ``-X`` options), can match also against directories: files >> under matched directories are treated as matched. >> >> +For ``-I`` and ``-X`` options, ``glob:`` will match directories >> recursively. >> +``rootglob:``, on the other end, does a full match, meaning that all >> files, in >> +directories or subdirectories, will only match if the entire expression >> matches. >> +In that case, ``**`` can be used to obtain recursiveness. >> + >> Plain examples:: >> >> path:foo/bar a name bar in a directory named foo in the root >> @@ -48,13 +53,18 @@ >> >> 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/* any file in directory foo plus all its subdirectories, >> + recursively >> + 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 but not its subdirectories >> + rootglob:foo/** all files inside foo and its subdirectories >> >> Regexp examples:: >> >> diff -r b032a7b676c6 -r 93434cce258a mercurial/match.py >> --- a/mercurial/match.py Tue Nov 01 18:54:03 2016 -0700 >> +++ b/mercurial/match.py Sat Oct 08 09:28:40 2016 -0700 >> @@ -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', '')]) >> + ['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 -r b032a7b676c6 -r 93434cce258a tests/test-walk.t >> --- a/tests/test-walk.t Tue Nov 01 18:54:03 2016 -0700 >> +++ b/tests/test-walk.t Sat Oct 08 09:28:40 2016 -0700 >> @@ -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 >> _______________________________________________ >> Mercurial-devel mailing list >> Mercurial-devel@mercurial-scm.org >> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel >> >> > -- > Pierre-Yves David >
On 11/24/2016 04:54 AM, Rodrigo Damazio wrote: > Pierre-Yves, hope you had a great time in Morocco :) I had, > Any other comments here? Yep, I'll start a thread about the Plan page soon, this topic is now on the tip of my "complex discussion" stack and unless Denmark is hit by an asteroid I should post something later today. > On Tue, Nov 15, 2016 at 6:21 AM, Pierre-Yves David > <pierre-yves.david@ens-lyon.org <mailto:pierre-yves.david@ens-lyon.org>> > wrote: > > > > On 11/15/2016 04:59 AM, Rodrigo Damazio Bovendorp via > Mercurial-devel wrote: > > # HG changeset patch > # User Rodrigo Damazio Bovendorp <rdamazio@google.com > <mailto:rdamazio@google.com>> > # Date 1475944120 <tel:1475944120> 25200 > # Sat Oct 08 09:28:40 2016 -0700 > # Node ID 93434cce258a797fcc3997c0af994a524695e273 > # Parent b032a7b676c6637b2ac6f3ef29431013b15a08f9 > match: adding support for repository-root-based globs > > > I saw that Foozy created a plan page about this, it seem to have > good summary of the current matcher we have but from my reading it > is a bit fuzzy about the current variation we have in behavior from > one command to another and from flag usage. I think it is important > to have a global view of the situation here to be able to > efficiently tackle the issues at hand. > > I'm traveling in Marocco with poor internet connectivity until the > end of the week. I would prefer if we could not take a final > discussion until I've time to discuss it more at the beginning of > next week. Sorry for the extra delay. > > 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 rootglob does a *full* match, meaning that a * at the end > will never > match recursively, even when the glob is used as an include pattern. > > diff -r b032a7b676c6 -r 93434cce258a mercurial/help/patterns.txt > --- a/mercurial/help/patterns.txt Tue Nov 01 18:54:03 2016 > -0700 > +++ b/mercurial/help/patterns.txt Sat Oct 08 09:28:40 2016 > -0700 > @@ -40,6 +40,11 @@ > ``-I`` or ``-X`` options), can match also against directories: > files > under matched directories are treated as matched. > > +For ``-I`` and ``-X`` options, ``glob:`` will match directories > recursively. > +``rootglob:``, on the other end, does a full match, meaning > that all files, in > +directories or subdirectories, will only match if the entire > expression matches. > +In that case, ``**`` can be used to obtain recursiveness. > + > Plain examples:: > > path:foo/bar a name bar in a directory named foo in the root > @@ -48,13 +53,18 @@ > > 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/* any file in directory foo plus all its > subdirectories, > + recursively > + 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 but not its subdirectories > + rootglob:foo/** all files inside foo and its subdirectories > > Regexp examples:: > > diff -r b032a7b676c6 -r 93434cce258a mercurial/match.py > --- a/mercurial/match.py Tue Nov 01 18:54:03 2016 -0700 > +++ b/mercurial/match.py Sat Oct 08 09:28:40 2016 -0700 > @@ -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', '')]) > + ['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 -r b032a7b676c6 -r 93434cce258a tests/test-walk.t > --- a/tests/test-walk.t Tue Nov 01 18:54:03 2016 -0700 > +++ b/tests/test-walk.t Sat Oct 08 09:28:40 2016 -0700 > @@ -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 > _______________________________________________ > Mercurial-devel mailing list > Mercurial-devel@mercurial-scm.org > <mailto:Mercurial-devel@mercurial-scm.org> > https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel > <https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel> > > > -- > Pierre-Yves David > >
Patch
============ ======== ======= =========== 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 rootglob does a *full* match, meaning that a * at the end will never match recursively, even when the glob is used as an include pattern. diff -r b032a7b676c6 -r 93434cce258a mercurial/help/patterns.txt --- a/mercurial/help/patterns.txt Tue Nov 01 18:54:03 2016 -0700 +++ b/mercurial/help/patterns.txt Sat Oct 08 09:28:40 2016 -0700 @@ -40,6 +40,11 @@ ``-I`` or ``-X`` options), can match also against directories: files under matched directories are treated as matched. +For ``-I`` and ``-X`` options, ``glob:`` will match directories recursively. +``rootglob:``, on the other end, does a full match, meaning that all files, in +directories or subdirectories, will only match if the entire expression matches. +In that case, ``**`` can be used to obtain recursiveness. + Plain examples:: path:foo/bar a name bar in a directory named foo in the root @@ -48,13 +53,18 @@ 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/* any file in directory foo plus all its subdirectories, + recursively + 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 but not its subdirectories + rootglob:foo/** all files inside foo and its subdirectories Regexp examples:: diff -r b032a7b676c6 -r 93434cce258a mercurial/match.py --- a/mercurial/match.py Tue Nov 01 18:54:03 2016 -0700 +++ b/mercurial/match.py Sat Oct 08 09:28:40 2016 -0700 @@ -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', '')]) + ['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 -r b032a7b676c6 -r 93434cce258a tests/test-walk.t --- a/tests/test-walk.t Tue Nov 01 18:54:03 2016 -0700 +++ b/tests/test-walk.t Sat Oct 08 09:28:40 2016 -0700 @@ -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