[PATCH 17 of 19 STABLE] dirstate: add 'rdirs()' to examine 'directory pattern' matching correctly

FUJIWARA Katsunori foozy at lares.dti.ne.jp
Mon Feb 27 04:46:42 CST 2012


# HG changeset patch
# User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
# Date 1330335216 -32400
# Branch stable
# Node ID 35c7b7ec5277e4312d3fd167cf8f07fd51bafd01
# Parent  65d6e452e239d195df6c14f5191ac7d802fdc51f
dirstate: add 'rdirs()' to examine 'directory pattern' matching correctly

when files are marked as 'removed' in working context:

    - entry in 'dirstate' is dropped, and
    - if there is no other files in target directory:
      - entry in 'dirstate._dirs' is dropped, and
      - directory itself is removed from filesystem

so, 'f in dirstate.dirs()' can't examine whether specified pattern is
related to removed largefiles or not correctly, if it is 'directory
pattern'.

this patch adds 'dirstate.rdirs()' (removed-dirs) to know what
directories are related to removed files.

'dirstate.rdirs()' is not for serious purpose, but for checking of
directory matching to removed files, so it is updated only in
'_droppath()'.

diff -r 65d6e452e239 -r 35c7b7ec5277 mercurial/dirstate.py
--- a/mercurial/dirstate.py	Mon Feb 27 18:33:36 2012 +0900
+++ b/mercurial/dirstate.py	Mon Feb 27 18:33:36 2012 +0900
@@ -35,6 +35,15 @@
             return
         del dirs[base]
 
+def _addrdirs(dirs, path):
+    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('/')
+
 class dirstate(object):
 
     def __init__(self, opener, ui, root, validate):
@@ -253,8 +262,9 @@
             self._pl = p
 
     def invalidate(self):
-        for a in ("_map", "_copymap", "_foldmap", "_branch", "_pl", "_dirs",
-                "_ignore"):
+        for a in ("_map", "_copymap", "_foldmap", "_branch", "_pl",
+                  "_dirs", "_rdirs",
+                  "_ignore"):
             if a in self.__dict__:
                 delattr(self, a)
         self._lastnormaltime = 0
@@ -277,8 +287,11 @@
         return self._copymap
 
     def _droppath(self, f):
-        if self[f] not in "?r" and "_dirs" in self.__dict__:
-            _decdirs(self._dirs, f)
+        if self[f] not in "?r":
+            if "_dirs" in self.__dict__:
+                _decdirs(self._dirs, f)
+            if "_rdirs" in self.__dict__:
+                _addrdirs(self._rdirs, f)
 
     def _addpath(self, f, check=False):
         oldstate = self[f]
@@ -417,8 +430,9 @@
 
     def clear(self):
         self._map = {}
-        if "_dirs" in self.__dict__:
-            delattr(self, "_dirs")
+        for a in ("_dirs", "_rdirs"):
+            if a in self.__dict__:
+                delattr(self, a)
         self._copymap = {}
         self._pl = [nullid, nullid]
         self._lastnormaltime = 0
@@ -734,3 +748,17 @@
 
         return (lookup, modified, added, removed, deleted, unknown, ignored,
                 clean)
+
+    @propertycache
+    def _rdirs(self):
+        '''not for strict purpose, but for checking of directory
+        matching to removed files'''
+
+        dirs = set()
+        for f, s in self._map.iteritems():
+            if s[0] == 'r':
+                _addrdirs(dirs, f)
+        return dirs
+
+    def rdirs(self):
+        return self._rdirs


More information about the Mercurial-devel mailing list