Patchwork match: adding support for repository-root-based globs

login
register
mail settings
Submitter via Mercurial-devel
Date Oct. 25, 2016, 7:41 a.m.
Message ID <e8454de81600e092f05a.1477381287@waste.org>
Download mbox | patch
Permalink /patch/17189/
State Deferred
Headers show

Comments

via Mercurial-devel - Oct. 25, 2016, 7:41 a.m.
# HG changeset patch
# User Rodrigo Damazio Bovendorp <rdamazio@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:
Pierre-Yves David - Oct. 28, 2016, 8:40 a.m.
On 10/25/2016 09:41 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 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)

The subject seems complicated enough that creating a Plan page seems 
relevant. This would help other people to follow what the problem space.

https://www.mercurial-scm.org/wiki/WriteANewFeaturePlan

> 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.

This seems a bit strange to me. Given that the current glob matcher is 
already not recursive, why don't we work on an alternative non recursive 
-I flag instead?

Cheers,
Augie Fackler - Nov. 1, 2016, 1:47 a.m.
> On Oct 28, 2016, at 4:40 AM, Pierre-Yves David <pierre-yves.david@ens-lyon.org> wrote:
> 
> 
> 
> On 10/25/2016 09:41 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 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)
> 
> The subject seems complicated enough that creating a Plan page seems relevant. This would help other people to follow what the problem space.
> 
> https://www.mercurial-scm.org/wiki/WriteANewFeaturePlan

I’m not sure if it needs a plan page. It strikes me as believable (perhaps even likely?) that rootglob will be the only part of this implemented for a long time, perhaps ever. (Having the whole table makes good sense to me though, because now we’ve though through the future in case it ever comes.)

> 
>> 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.
> 
> This seems a bit strange to me. Given that the current glob matcher is already not recursive, why don't we work on an alternative non recursive -I flag instead?

That means we’ll have a new flag that alters the behavior of existing matchers in subtle ways. It also requires cooperation from every command that we want to add new globbing features to, including extensions, whereas if we can add a couple of new atoms (as outlined in the proposal from foozy) we get consistent behavior across all matchers.

It’s a mistake that existing matchers have a recursive * behavior with --include, but it’s too late to change that. As such, I’d much rather have this proposal as currently stated.

> Cheers,
> 
> --
> Pierre-Yves David
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel@mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
Yuya Nishihara - Nov. 1, 2016, 12:50 p.m.
On Mon, 31 Oct 2016 21:47:35 -0400, Augie Fackler wrote:
> > On Oct 28, 2016, at 4:40 AM, Pierre-Yves David <pierre-yves.david@ens-lyon.org> wrote:
> > On 10/25/2016 09:41 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 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)
> > 
> > The subject seems complicated enough that creating a Plan page seems relevant. This would help other people to follow what the problem space.
> > 
> > https://www.mercurial-scm.org/wiki/WriteANewFeaturePlan
> 
> I’m not sure if it needs a plan page. It strikes me as believable (perhaps even likely?) that rootglob will be the only part of this implemented for a long time, perhaps ever. (Having the whole table makes good sense to me though, because now we’ve though through the future in case it ever comes.)
> 
> > 
> >> 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.
> > 
> > This seems a bit strange to me. Given that the current glob matcher is already not recursive, why don't we work on an alternative non recursive -I flag instead?
> 
> That means we’ll have a new flag that alters the behavior of existing matchers in subtle ways. It also requires cooperation from every command that we want to add new globbing features to, including extensions, whereas if we can add a couple of new atoms (as outlined in the proposal from foozy) we get consistent behavior across all matchers.
> 
> It’s a mistake that existing matchers have a recursive * behavior with --include, but it’s too late to change that. As such, I’d much rather have this proposal as currently stated.

Given the current globsuffix thing is just for backward compatibility, new
rootglob prefix makes sense to me. Fileset, which is relatively new, behaves
in that way.

% hg files -I 'set:contrib/docker/*'
contrib/docker/centos5
contrib/docker/centos6
contrib/docker/centos7
contrib/docker/debian-jessie
contrib/docker/fedora20
contrib/docker/fedora21
contrib/docker/ubuntu.template

% hg files -I 'contrib/docker/*'
contrib/docker/apache-server/Dockerfile
contrib/docker/apache-server/README.rst
contrib/docker/apache-server/entrypoint.sh
contrib/docker/apache-server/hgwebconfig
contrib/docker/apache-server/vhost.conf
contrib/docker/centos5
contrib/docker/centos6
contrib/docker/centos7
contrib/docker/debian-jessie
contrib/docker/fedora20
contrib/docker/fedora21
contrib/docker/ubuntu.template
Pierre-Yves David - Nov. 2, 2016, 2:58 p.m.
On 11/01/2016 01:50 PM, Yuya Nishihara wrote:
> On Mon, 31 Oct 2016 21:47:35 -0400, Augie Fackler wrote:
>>> On Oct 28, 2016, at 4:40 AM, Pierre-Yves David <pierre-yves.david@ens-lyon.org> wrote:
>>> On 10/25/2016 09:41 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 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)
>>>
>>> The subject seems complicated enough that creating a Plan page seems relevant. This would help other people to follow what the problem space.
>>>
>>> https://www.mercurial-scm.org/wiki/WriteANewFeaturePlan
>>
>> I’m not sure if it needs a plan page. It strikes me as believable (perhaps even likely?) that rootglob will be the only part of this implemented for a long time, perhaps ever. (Having the whole table makes good sense to me though, because now we’ve though through the future in case it ever comes.)

If I'm counting correctly, this is at least the third time matcher 
specification is touched in the history of the project. This instance 
have already created multiple email threads with interesting data 
"hidden" into them.

I think a plan page is important to give clear picture of the situation 
and the proposed solution in a single place. This would help increased 
the number of eyes on this topic that history have proved complex.

Especially give how often this topic came up I think it important to 
make sure we actually map the problem space and nail the issue once and 
for all. I'm a bit concerned we could be taking the minimal step to 
snipe a specific requirement here without actually moving toward a real 
closure providing a simplified solution that fit all all users.

Regarding how far we'll go in that plan, I hope that at least 
"rootre:/rootpath:" will be implement for feature parity with glob.

>>>> 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.
>>>
>>> This seems a bit strange to me. Given that the current glob matcher is already not recursive, why don't we work on an alternative non recursive -I flag instead?
>>
>> That means we’ll have a new flag that alters the behavior of existing matchers in subtle ways. It also requires cooperation from every command that we want to add new globbing features to, including extensions, whereas if we can add a couple of new atoms (as outlined in the proposal from foozy) we get consistent behavior across all matchers.

Command using -I/-X option usually just add the 'walkopts' list to their 
option and then pass their 'opts' dict to 'scmutil.match(…)'. So 
improving the command flag situation in a unified way does not seems too 
scary.

My main concern here is that the vast majority of user will still use 
the basic glob we expose without any prefix. If the most common matcher 
behave "differently" than all the others, that will get confusing.
That said, the exact state of all existing matchers behavior is getting 
fuzzier in my head as the discussion progress. This is one of the reason 
I would like to see the current situation and the Foozy plan summarized 
into a plan page.

A good way to test¹ design is "how embarrassing is it to explain to new 
user" (that is correlated to the simplicity of the design). The recent 
discussion and confusion around matcher show that we are not great for 
the moment.

>> It’s a mistake that existing matchers have a recursive * behavior with --include, but it’s too late to change that. As such, I’d much rather have this proposal as currently stated.

> Given the current globsuffix thing is just for backward compatibility, new
> rootglob prefix makes sense to me. Fileset, which is relatively new, behaves
> in that way.

On one hand, this extra bits from Yuya increase my wish for a nice 
summary of the current situation + objective. On the other hand there it 
start to have enough core people who seems to know what they are doing 
on this topic to let them work together on this.

So I wish there was a plan page but if none of Foozy, Yuya or Augie 
think it is necessary, just go ahead.

> % hg files -I 'set:contrib/docker/*'
> contrib/docker/centos5
> contrib/docker/centos6
> contrib/docker/centos7
> contrib/docker/debian-jessie
> contrib/docker/fedora20
> contrib/docker/fedora21
> contrib/docker/ubuntu.template
>
> % hg files -I 'contrib/docker/*'
> contrib/docker/apache-server/Dockerfile
> contrib/docker/apache-server/README.rst
> contrib/docker/apache-server/entrypoint.sh
> contrib/docker/apache-server/hgwebconfig
> contrib/docker/apache-server/vhost.conf
> contrib/docker/centos5
> contrib/docker/centos6
> contrib/docker/centos7
> contrib/docker/debian-jessie
> contrib/docker/fedora20
> contrib/docker/fedora21
> contrib/docker/ubuntu.template

Cheers,
via Mercurial-devel - Nov. 3, 2016, 2:37 a.m.
On Wed, Nov 2, 2016 at 7:58 AM, Pierre-Yves David <
pierre-yves.david@ens-lyon.org> wrote:

>
>
> On 11/01/2016 01:50 PM, Yuya Nishihara wrote:
>
>> On Mon, 31 Oct 2016 21:47:35 -0400, Augie Fackler wrote:
>>
>>> On Oct 28, 2016, at 4:40 AM, Pierre-Yves David <
>>>> pierre-yves.david@ens-lyon.org> wrote:
>>>> On 10/25/2016 09:41 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 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)
>>>>>
>>>>
>>>> The subject seems complicated enough that creating a Plan page seems
>>>> relevant. This would help other people to follow what the problem space.
>>>>
>>>> https://www.mercurial-scm.org/wiki/WriteANewFeaturePlan
>>>>
>>>
>>> I’m not sure if it needs a plan page. It strikes me as believable
>>> (perhaps even likely?) that rootglob will be the only part of this
>>> implemented for a long time, perhaps ever. (Having the whole table makes
>>> good sense to me though, because now we’ve though through the future in
>>> case it ever comes.)
>>>
>>
> If I'm counting correctly, this is at least the third time matcher
> specification is touched in the history of the project. This instance have
> already created multiple email threads with interesting data "hidden" into
> them.
>
> I think a plan page is important to give clear picture of the situation
> and the proposed solution in a single place. This would help increased the
> number of eyes on this topic that history have proved complex.


> Especially give how often this topic came up I think it important to make
> sure we actually map the problem space and nail the issue once and for all.
> I'm a bit concerned we could be taking the minimal step to snipe a specific
> requirement here without actually moving toward a real closure providing a
> simplified solution that fit all all users.
>
> Regarding how far we'll go in that plan, I hope that at least
> "rootre:/rootpath:" will be implement for feature parity with glob.
>
> 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.
>>>>>
>>>>
>>>> This seems a bit strange to me. Given that the current glob matcher is
>>>> already not recursive, why don't we work on an alternative non recursive -I
>>>> flag instead?
>>>>
>>>
>>> That means we’ll have a new flag that alters the behavior of existing
>>> matchers in subtle ways. It also requires cooperation from every command
>>> that we want to add new globbing features to, including extensions, whereas
>>> if we can add a couple of new atoms (as outlined in the proposal from
>>> foozy) we get consistent behavior across all matchers.
>>>
>>
> Command using -I/-X option usually just add the 'walkopts' list to their
> option and then pass their 'opts' dict to 'scmutil.match(…)'. So improving
> the command flag situation in a unified way does not seems too scary.
>
> My main concern here is that the vast majority of user will still use the
> basic glob we expose without any prefix. If the most common matcher behave
> "differently" than all the others, that will get confusing.
> That said, the exact state of all existing matchers behavior is getting
> fuzzier in my head as the discussion progress. This is one of the reason I
> would like to see the current situation and the Foozy plan summarized into
> a plan page.
>
> A good way to test¹ design is "how embarrassing is it to explain to new
> user" (that is correlated to the simplicity of the design). The recent
> discussion and confusion around matcher show that we are not great for the
> moment.
>
> It’s a mistake that existing matchers have a recursive * behavior with
>>> --include, but it’s too late to change that. As such, I’d much rather have
>>> this proposal as currently stated.
>>>
>>
> Given the current globsuffix thing is just for backward compatibility, new
>> rootglob prefix makes sense to me. Fileset, which is relatively new,
>> behaves
>> in that way.
>>
>
> On one hand, this extra bits from Yuya increase my wish for a nice summary
> of the current situation + objective. On the other hand there it start to
> have enough core people who seems to know what they are doing on this topic
> to let them work together on this.
>
> So I wish there was a plan page but if none of Foozy, Yuya or Augie think
> it is necessary, just go ahead.


I'll leave this decision up to you 4 :) but if a plan page is to be
created, perhaps Foozy could start with the notes he already had?

For now, I'm sending an updated change which updates the documentation as
discussed (and is rebased to the latest tip)



>
>
> % hg files -I 'set:contrib/docker/*'
>> contrib/docker/centos5
>> contrib/docker/centos6
>> contrib/docker/centos7
>> contrib/docker/debian-jessie
>> contrib/docker/fedora20
>> contrib/docker/fedora21
>> contrib/docker/ubuntu.template
>>
>> % hg files -I 'contrib/docker/*'
>> contrib/docker/apache-server/Dockerfile
>> contrib/docker/apache-server/README.rst
>> contrib/docker/apache-server/entrypoint.sh
>> contrib/docker/apache-server/hgwebconfig
>> contrib/docker/apache-server/vhost.conf
>> contrib/docker/centos5
>> contrib/docker/centos6
>> contrib/docker/centos7
>> contrib/docker/debian-jessie
>> contrib/docker/fedora20
>> contrib/docker/fedora21
>> contrib/docker/ubuntu.template
>>
>
> Cheers,
>
> --
> Pierre-Yves David
>
> [1] I got it from Durham.
>
Yuya Nishihara - Nov. 5, 2016, 3:54 a.m.
On Wed, 2 Nov 2016 15:58:12 +0100, Pierre-Yves David wrote:
> >> It’s a mistake that existing matchers have a recursive * behavior with --include, but it’s too late to change that. As such, I’d much rather have this proposal as currently stated.
> 
> > Given the current globsuffix thing is just for backward compatibility, new
> > rootglob prefix makes sense to me. Fileset, which is relatively new, behaves
> > in that way.
> 
> On one hand, this extra bits from Yuya increase my wish for a nice 
> summary of the current situation + objective. On the other hand there it 
> start to have enough core people who seems to know what they are doing 
> on this topic to let them work together on this.
> 
> So I wish there was a plan page but if none of Foozy, Yuya or Augie 
> think it is necessary, just go ahead.

Ok, let's start the plan page so hopefully the rootglob or any equivalents
can be landed in 4.1.

https://www.mercurial-scm.org/wiki/FileNamePatternsPlan

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 * 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