[PATCH 7 of 8 STABLE RFC] largefiles: introduce 'dirstate.rdirs()' to check status of removed files correclty

FUJIWARA Katsunori foozy at lares.dti.ne.jp
Fri Feb 17 16:07:33 UTC 2012


# HG changeset patch
# User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
# Date 1329494573 -32400
# Branch stable
# Node ID f02f94342c38f4e26cf707f98e6a04e58fa52fd3
# Parent  5bd50be1b934b1a7f08cb32dd60c49800a2bc5a4
largefiles: introduce 'dirstate.rdirs()' to check status of removed files correclty

when files are marked as 'removed':

    - 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

so, neither 'f in dirstate.dirs()' nor 'os.path.lexists(f)' can be
used to examine whether specified DIRECTORY pattern is related to
largefile or not.

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

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

diff -r 5bd50be1b934 -r f02f94342c38 hgext/largefiles/reposetup.py
--- a/hgext/largefiles/reposetup.py	Sat Feb 18 01:02:53 2012 +0900
+++ b/hgext/largefiles/reposetup.py	Sat Feb 18 01:02:53 2012 +0900
@@ -100,17 +100,25 @@
                 working = ctx2.rev() is None
                 parentworking = working and ctx1 == self['.']
 
-                def inctx(file, ctx):
+                def inctx(file, ctx, exact=True):
                     try:
                         if ctx.rev() is None:
-                            return file in ctx.manifest()
+                            if exact:
+                                return file in ctx.manifest()
+                            else:
+                                dirstate = repo.dirstate
+                                return ((file in ctx.manifest()) or
+                                        (file in dirstate.dirs()) or
+                                        (file in dirstate.rdirs()))
                         ctx[file]
                         return True
                     except KeyError:
                         return False
 
                 def hasstandin(f, dirstate):
-                    return lfutil.standin(f) in dirstate.dirs()
+                    sf = lfutil.standin(f)
+                    return ((sf in dirstate.dirs()) or
+                            (sf in dirstate.rdirs()))
 
                 if match is None:
                     match = match_.always(self.root, self.getcwd())
@@ -133,7 +141,7 @@
                 # of largefiles.
                 def tostandin(file):
                     sf = lfutil.standin(file)
-                    if inctx(sf, ctx1) or inctx(sf, ctx2):
+                    if inctx(sf, ctx1, False) or inctx(sf, ctx2, False):
                         return sf
                     return file
 
diff -r 5bd50be1b934 -r f02f94342c38 mercurial/dirstate.py
--- a/mercurial/dirstate.py	Sat Feb 18 01:02:53 2012 +0900
+++ b/mercurial/dirstate.py	Sat Feb 18 01:02:53 2012 +0900
@@ -250,8 +250,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
@@ -274,8 +275,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__:
+                _incdirs(self._rdirs, f)
 
     def _addpath(self, f, check=False):
         oldstate = self[f]
@@ -414,8 +418,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 +739,16 @@
 
     def dirs(self):
         return self._dirs
+
+    @propertycache
+    def _rdirs(self):
+        '''not for strict purpose, but for checking of directory
+        matching to removed files'''
+        dirs = {}
+        for f, s in self._map.iteritems():
+            if s[0] == 'r':
+                _incdirs(dirs, f)
+        return dirs
+
+    def rdirs(self):
+        return self._rdirs
diff -r 5bd50be1b934 -r f02f94342c38 tests/test-largefiles.t
--- a/tests/test-largefiles.t	Sat Feb 18 01:02:53 2012 +0900
+++ b/tests/test-largefiles.t	Sat Feb 18 01:02:53 2012 +0900
@@ -1091,4 +1091,16 @@
   A another/e.txt
   C sub/a.txt
 
+  $ hg remove sub/sub/d.txt
+  $ hg status -A
+  R sub/sub/d.txt
+  C sub/a.txt
+  C sub/b.txt
+  C sub/c.txt
+  $ hg status -A sub/sub
+  R sub/sub/d.txt
+  $ hg status -A sub/a.txt sub/sub
+  R sub/sub/d.txt
+  C sub/a.txt
+
   $ cd ..



More information about the Mercurial-devel mailing list