[PATCH] match: adding non-recursive directory matching

Pierre-Yves David pierre-yves.david at ens-lyon.org
Sun Oct 16 09:50:10 EDT 2016



On 10/08/2016 06:58 PM, Rodrigo Damazio Bovendorp via Mercurial-devel wrote:
> # HG changeset patch
> # User Rodrigo Damazio Bovendorp <rdamazio at google.com>
> # Date 1475944120 25200
> #      Sat Oct 08 09:28:40 2016 -0700
> # Node ID 545efe5a72efdce925a6a3fd3774b350c90b5c55
> # Parent  dbcef8918bbdd8a64d9f79a37bcfa284a26f3a39
> match: adding non-recursive directory matching
>
> This allows one to match all files in a directory, without matching anything in subdirectories.
> It's implemented almost identically to path:, except for the regex termination, which doesn't
> allow more than one / after the directory name.
>
> diff --git a/mercurial/match.py b/mercurial/match.py
> --- a/mercurial/match.py
> +++ b/mercurial/match.py
> @@ -105,6 +105,9 @@
>          'glob:<glob>' - a glob relative to cwd
>          're:<regexp>' - a regular expression
>          'path:<path>' - a path relative to repository root
> +        'files:<path>' - a path relative to repository root, which is matched
> +                         non-recursively (files inside the directory will match,
> +                         but subdirectories and files in them won't

The feature seems useful and we should have it.

The current behavior is a bit strange to me. because we have directory 
being implicitly recursed of just 1 level (directory content). Could we 
have a xxx:<path> where path is never recursed for anything. Listing a 
directory content would be an explicite 'xxx:my/directory/path/*'

We could use 'exact' or 'norecursion' for xxx.

>          '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 +289,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', 'files'):
>                  pat = util.normpath(pat)
>              elif kind in ('listfile', 'listfile0'):
>                  try:
> @@ -447,7 +450,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',
> +                    'files'):
>              return kind, pat
>      return default, pattern
>
> @@ -540,6 +544,19 @@
>          if pat == '.':
>              return ''
>          return '^' + util.re.escape(pat) + '(?:/|$)'
> +    if kind == 'files':
> +        # Match one of:
> +        # For pat = 'some/dir':
> +        # some/dir
> +        # some/dir/
> +        # some/dir/filename
> +        # For pat = '' or pat = '.':
> +        # filename
> +        if pat == '.':
> +            escaped = ''
> +        else:
> +            escaped = util.re.escape(pat)
> +        return '^' + escaped + '(?:^|/|$)[^/]*$'
>      if kind == 'relglob':
>          return '(?:|.*/)' + _globre(pat) + globsuffix
>      if kind == 'relpath':
> @@ -628,7 +645,7 @@
>                      break
>                  root.append(p)
>              r.append('/'.join(root) or '.')
> -        elif kind in ('relpath', 'path'):
> +        elif kind in ('relpath', 'path', 'files'):
>              r.append(pat or '.')
>          else: # relglob, re, relre
>              r.append('.')
> diff --git a/tests/test-locate.t b/tests/test-locate.t
> --- a/tests/test-locate.t
> +++ b/tests/test-locate.t
> @@ -52,6 +52,12 @@
>    t/b
>    t/e.h
>    t/x
> +  $ hg locate files:
> +  b
> +  t.h
> +  $ hg locate files:.
> +  b
> +  t.h
>    $ hg locate -r 0 a
>    a
>    $ hg locate -r 0 NONEXISTENT
> @@ -119,6 +125,13 @@
>    ../t/e.h (glob)
>    ../t/x (glob)
>
> +  $ hg files files:
> +  ../b (glob)
> +  ../t.h (glob)
> +  $ hg files files:.
> +  ../b (glob)
> +  ../t.h (glob)
> +
>    $ hg locate b
>    ../b (glob)
>    ../t/b (glob)
> 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,8 @@
>    f  beans/navy      ../beans/navy
>    f  beans/pinto     ../beans/pinto
>    f  beans/turtle    ../beans/turtle
> +  $ hg debugwalk -I 'files:mammals'
> +  f  mammals/skunk  skunk
>    $ hg debugwalk .
>    f  mammals/Procyonidae/cacomistle  Procyonidae/cacomistle
>    f  mammals/Procyonidae/coatimundi  Procyonidae/coatimundi
> _______________________________________________
> Mercurial-devel mailing list
> Mercurial-devel at mercurial-scm.org
> https://www.mercurial-scm.org/mailman/listinfo/mercurial-devel
>

-- 
Pierre-Yves David


More information about the Mercurial-devel mailing list