[PATCH 1 of 2 STABLE] context: add 'changectx.dirs()' to recognize directory matching pattern

FUJIWARA Katsunori foozy at lares.dti.ne.jp
Sat Feb 18 09:15:37 CST 2012


# HG changeset patch
# User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
# Date 1329577967 -32400
# Branch stable
# Node ID 0df295bc57a9dbf897fde6be438711dd56797591
# Parent  0e0060bf2f440d5cc33e5f36d99868a5380debd4
context: add 'changectx.dirs()' to recognize directory matching pattern

when patterns which does not match any files in working context is
specified, current implementation of 'localrepository.status()' decide
whether warning message about it should be shown or not
by 'f not in targetcontext'

this works correctly for 'file pattern', but not for 'directory
pattern', because 'f not in targetcontext' always returns True for
directories.

this patch add 'changectx.dirs()', which returns map of all
directories deduced from manifest, to examine whether specified
directory is related to context or not quickly.

diff -r 0e0060bf2f44 -r 0df295bc57a9 mercurial/context.py
--- a/mercurial/context.py	Mon Feb 13 17:22:35 2012 +0100
+++ b/mercurial/context.py	Sun Feb 19 00:12:47 2012 +0900
@@ -236,6 +236,16 @@
         return patch.diff(self._repo, ctx2.node(), self.node(),
                           match=match, opts=diffopts)
 
+    @propertycache
+    def _dirs(self):
+        dirs = {}
+        for f in self._manifest:
+            util.incdirs(dirs, f)
+        return dirs
+
+    def dirs(self):
+        return self._dirs
+
 class filectx(object):
     """A filecontext object makes access to data related to a particular
        filerevision convenient."""
diff -r 0e0060bf2f44 -r 0df295bc57a9 mercurial/dirstate.py
--- a/mercurial/dirstate.py	Mon Feb 13 17:22:35 2012 +0100
+++ b/mercurial/dirstate.py	Sun Feb 19 00:12:47 2012 +0900
@@ -15,25 +15,9 @@
 _format = ">cllll"
 propertycache = util.propertycache
 
-def _finddirs(path):
-    pos = path.rfind('/')
-    while pos != -1:
-        yield path[:pos]
-        pos = path.rfind('/', 0, pos)
-
-def _incdirs(dirs, path):
-    for base in _finddirs(path):
-        if base in dirs:
-            dirs[base] += 1
-            return
-        dirs[base] = 1
-
-def _decdirs(dirs, path):
-    for base in _finddirs(path):
-        if dirs[base] > 1:
-            dirs[base] -= 1
-            return
-        del dirs[base]
+_finddirs = util.finddirs
+_incdirs = util.incdirs
+_decdirs = util.decdirs
 
 class dirstate(object):
 
diff -r 0e0060bf2f44 -r 0df295bc57a9 mercurial/localrepo.py
--- a/mercurial/localrepo.py	Mon Feb 13 17:22:35 2012 +0100
+++ b/mercurial/localrepo.py	Sun Feb 19 00:12:47 2012 +0900
@@ -1351,7 +1351,9 @@
 
         if not parentworking:
             def bad(f, msg):
-                if f not in ctx1:
+                # 'f' may be a directory pattern from 'match.files()',
+                # so 'f not in ctx1' is not enough
+                if (f not in ctx1) and (f not in ctx1.dirs()):
                     self.ui.warn('%s: %s\n' % (self.dirstate.pathto(f), msg))
             match.bad = bad
 
diff -r 0e0060bf2f44 -r 0df295bc57a9 mercurial/util.py
--- a/mercurial/util.py	Mon Feb 13 17:22:35 2012 +0100
+++ b/mercurial/util.py	Sun Feb 19 00:12:47 2012 +0900
@@ -1747,3 +1747,24 @@
         return fd.isatty()
     except AttributeError:
         return False
+
+def finddirs(path):
+    pos = path.rfind('/')
+    while pos != -1:
+        yield path[:pos]
+        pos = path.rfind('/', 0, pos)
+
+def incdirs(dirs, path):
+    for base in finddirs(path):
+        if base in dirs:
+            dirs[base] += 1
+            return
+        dirs[base] = 1
+
+def decdirs(dirs, path):
+    for base in finddirs(path):
+        if dirs[base] > 1:
+            dirs[base] -= 1
+            return
+        del dirs[base]
+
diff -r 0e0060bf2f44 -r 0df295bc57a9 tests/test-status.t
--- a/tests/test-status.t	Mon Feb 13 17:22:35 2012 +0100
+++ b/tests/test-status.t	Sun Feb 19 00:12:47 2012 +0900
@@ -295,3 +295,33 @@
   $ hg ci -q -A -m 'add another file'
   $ hg status -A --rev 1:2 010a
   C 010a
+
+  $ cd ..
+
+test "hg status" with "directory pattern" which matches against files
+only known on target revision.
+
+  $ hg init repo6
+  $ cd repo6
+
+  $ echo a > a.txt
+  $ hg add a.txt
+  $ hg commit -m '#0'
+  $ mkdir sub
+  $ echo b > sub/b.txt
+  $ hg add sub/b.txt
+  $ hg commit -m '#1'
+
+  $ hg update -C 0 > /dev/null
+  $ hg status -A
+  C a.txt
+
+the directory matching against specified pattern should be removed,
+because directory existence prevents 'dirstate.walk()' from showing
+warning message about such pattern.
+
+  $ test ! -d sub
+  $ hg status -A --rev 1 sub
+  R sub/b.txt
+
+  $ cd ..


More information about the Mercurial-devel mailing list