[PATCH] match: introduce nevermatcher for when no ignore files are present

Siddharth Agarwal sid0 at fb.com
Thu Jun 1 07:41:16 UTC 2017


# HG changeset patch
# User Siddharth Agarwal <sid0 at fb.com>
# Date 1496302852 25200
#      Thu Jun 01 00:40:52 2017 -0700
# Node ID 14f332c8fe10c498e7c35bef09e53b8b6c7e5f43
# Parent  dbf330cadc5a3c0707c4611f2f4150be13cac02a
match: introduce nevermatcher for when no ignore files are present

952017471f93 introduced a deterministic `__repr__` for ignores. However, it
didn't account for when ignore was `util.never`. This broke fsmonitor's ignore
change detection -- with an empty hgignore, it would kick in all the time.

Introduce `nevermatcher` and switch to it. This neatly parallels
`alwaysmatcher`.

diff --git a/mercurial/dirstate.py b/mercurial/dirstate.py
--- a/mercurial/dirstate.py
+++ b/mercurial/dirstate.py
@@ -232,7 +232,7 @@ class dirstate(object):
     def _ignore(self):
         files = self._ignorefiles()
         if not files:
-            return util.never
+            return matchmod.never(self._root, '')
 
         pats = ['include:%s' % f for f in files]
         return matchmod.match(self._root, '', [], pats, warn=self._ui.warn)
diff --git a/mercurial/match.py b/mercurial/match.py
--- a/mercurial/match.py
+++ b/mercurial/match.py
@@ -175,6 +175,9 @@ def exact(root, cwd, files, badfn=None):
 def always(root, cwd):
     return alwaysmatcher(root, cwd)
 
+def never(root, cwd):
+    return nevermatcher(root, cwd)
+
 def badmatch(match, badfn):
     """Make a copy of the given matcher, replacing its bad method with the given
     one.
@@ -339,6 +342,25 @@ class alwaysmatcher(basematcher):
     def __repr__(self):
         return '<alwaysmatcher>'
 
+class nevermatcher(basematcher):
+    '''Matches nothing.'''
+
+    def __init__(self, root, cwd, badfn=None, relativeuipath=False):
+        super(nevermatcher, self).__init__(root, cwd, badfn,
+                                           relativeuipath=relativeuipath)
+
+    def always(self):
+        return False
+
+    def matchfn(self, f):
+        return False
+
+    def visitdir(self, dir):
+        return False
+
+    def __repr__(self):
+        return '<nevermatcher>'
+
 class patternmatcher(basematcher):
 
     def __init__(self, root, cwd, kindpats, ctx=None, listsubrepos=False,
diff --git a/tests/test-hgignore.t b/tests/test-hgignore.t
--- a/tests/test-hgignore.t
+++ b/tests/test-hgignore.t
@@ -1,6 +1,10 @@
   $ hg init ignorerepo
   $ cd ignorerepo
 
+debugignore with no hgignore should be deterministic:
+  $ hg debugignore
+  <nevermatcher>
+
 Issue562: .hgignore requires newline at end:
 
   $ touch foo


More information about the Mercurial-devel mailing list