D6764: match: simplify the regexps created for glob patterns

valentin.gatienbaron (Valentin Gatien-Baron) phabricator at mercurial-scm.org
Wed Aug 28 07:37:44 EDT 2019


valentin.gatienbaron updated this revision to Diff 16327.

REPOSITORY
  rHG Mercurial

CHANGES SINCE LAST UPDATE
  https://phab.mercurial-scm.org/D6764?vs=16320&id=16327

CHANGES SINCE LAST ACTION
  https://phab.mercurial-scm.org/D6764/new/

REVISION DETAIL
  https://phab.mercurial-scm.org/D6764

AFFECTED FILES
  mercurial/match.py
  rust/hg-core/src/filepatterns.rs
  tests/test-hgignore.t
  tests/test-walk.t

CHANGE DETAILS

diff --git a/tests/test-walk.t b/tests/test-walk.t
--- a/tests/test-walk.t
+++ b/tests/test-walk.t
@@ -100,7 +100,7 @@
   f  mammals/skunk  skunk
   $ hg debugwalk -v -I 'relglob:*k'
   * matcher:
-  <includematcher includes='(?:|.*/)[^/]*k(?:/|$)'>
+  <includematcher includes='.*k(?:/|$)'>
   f  beans/black    ../beans/black
   f  fenugreek      ../fenugreek
   f  mammals/skunk  skunk
@@ -108,7 +108,7 @@
   * matcher:
   <intersectionmatcher
     m1=<patternmatcher patterns='mammals(?:/|$)'>,
-    m2=<includematcher includes='(?:|.*/)[^/]*k(?:/|$)'>>
+    m2=<includematcher includes='.*k(?:/|$)'>>
   f  mammals/skunk  skunk
   $ hg debugwalk -v -I 're:.*k$'
   * matcher:
diff --git a/tests/test-hgignore.t b/tests/test-hgignore.t
--- a/tests/test-hgignore.t
+++ b/tests/test-hgignore.t
@@ -177,7 +177,7 @@
   ? a.c
   ? syntax
   $ hg debugignore
-  <includematcher includes='(?:|.*/)[^/]*\\.o(?:/|$)'>
+  <includematcher includes='.*\\.o(?:/|$)'>
 
   $ cd ..
   $ echo > .hg/testhgignorerel
@@ -224,7 +224,7 @@
   A b.o
 
   $ hg debugignore
-  <includematcher includes='(?:|.*/)[^/]*(?:/|$)'>
+  <includematcher includes='.*(?:/|$)'>
 
   $ hg debugignore b.o
   b.o is ignored
diff --git a/rust/hg-core/src/filepatterns.rs b/rust/hg-core/src/filepatterns.rs
--- a/rust/hg-core/src/filepatterns.rs
+++ b/rust/hg-core/src/filepatterns.rs
@@ -184,14 +184,22 @@
             res.extend(b"[^/]+$");
             res
         }
+        PatternSyntax::RelGlob => {
+            let mut res: Vec<u8> = vec![];
+            let glob_re = glob_to_re(pattern);
+            if let Some(rest) = glob_re.drop_prefix(b"[^/]*") {
+                res.extend(b".*");
+                res.extend(rest);
+            } else {
+                res.extend(b"(?:|.*/)");
+                res.extend(glob_re);
+            }
+            res.extend(globsuffix.iter());
+            res
+        }
         PatternSyntax::Glob
-        | PatternSyntax::RelGlob
         | PatternSyntax::RootGlob => {
             let mut res: Vec<u8> = vec![];
-            if syntax == PatternSyntax::RelGlob {
-                res.extend(b"(?:|.*/)");
-            }
-
             res.extend(glob_to_re(pattern));
             res.extend(globsuffix.iter());
             res
diff --git a/mercurial/match.py b/mercurial/match.py
--- a/mercurial/match.py
+++ b/mercurial/match.py
@@ -1223,7 +1223,12 @@
         # Anything after the pattern must be a non-directory.
         return escaped + '[^/]+$'
     if kind == 'relglob':
-        return '(?:|.*/)' + _globre(pat) + globsuffix
+        globre = _globre(pat)
+        if globre.startswith('[^/]*'):
+            # When pat has the form *XYZ (common), make the returned regex more
+            # legible by returning the regex for **XYZ instead of **/*XYZ.
+            return '.*' + globre[len('[^/]*'):] + globsuffix
+        return '(?:|.*/)' + globre + globsuffix
     if kind == 'relre':
         if pat.startswith('^'):
             return pat



To: valentin.gatienbaron, #hg-reviewers
Cc: durin42, kevincox, mercurial-devel


More information about the Mercurial-devel mailing list