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

FUJIWARA Katsunori foozy at lares.dti.ne.jp
Sun Feb 19 04:25:41 CST 2012


# HG changeset patch
# User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
# Date 1329646846 -32400
# Branch stable
# Node ID 59430cdb845b58c916547dd5623ee438abcb2814
# 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 59430cdb845b mercurial/context.py
--- a/mercurial/context.py	Mon Feb 13 17:22:35 2012 +0100
+++ b/mercurial/context.py	Sun Feb 19 19:20:46 2012 +0900
@@ -236,6 +236,16 @@
         return patch.diff(self._repo, ctx2.node(), self.node(),
                           match=match, opts=diffopts)
 
+    @propertycache
+    def _dirs(self):
+        dirs = set()
+        for f in self._manifest:
+            util.adddirs(f, dirs)
+        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 59430cdb845b mercurial/localrepo.py
--- a/mercurial/localrepo.py	Mon Feb 13 17:22:35 2012 +0100
+++ b/mercurial/localrepo.py	Sun Feb 19 19:20:46 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 59430cdb845b mercurial/util.py
--- a/mercurial/util.py	Mon Feb 13 17:22:35 2012 +0100
+++ b/mercurial/util.py	Sun Feb 19 19:20:46 2012 +0900
@@ -1747,3 +1747,12 @@
         return fd.isatty()
     except AttributeError:
         return False
+
+def adddirs(path, dirs):
+    pos = path.rfind('/')
+    while pos != -1:
+        path = path[:pos]
+        if path in dirs:
+            break # dirs already contains this and above
+        dirs.add(path)
+        pos = path.rfind('/')
diff -r 0e0060bf2f44 -r 59430cdb845b 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 19:20:46 2012 +0900
@@ -295,3 +295,39 @@
   $ 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 -p 1/2/3/4/5
+  $ echo b > 1/2/3/4/5/b.txt
+  $ hg add 1/2/3/4/5/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 1
+  $ hg status -A --rev 1 1/2/3/4/5/b.txt
+  R 1/2/3/4/5/b.txt
+  $ hg status -A --rev 1 1/2/3/4/5
+  R 1/2/3/4/5/b.txt
+  $ hg status -A --rev 1 1/2/3
+  R 1/2/3/4/5/b.txt
+  $ hg status -A --rev 1 1
+  R 1/2/3/4/5/b.txt
+
+  $ cd ..


More information about the Mercurial-devel mailing list