diff mercurial/dirstate.py @ 1487:2bc6cd62a29c

fix handling of files of unsupported type in the walk code if a file was of unsupported type, it was considered as 'seen' while walking. this way it was possible to have file in the dirstate not yielded by the walk function.
author Benoit Boissinot <benoit.boissinot@ens-lyon.org>
date Wed, 02 Nov 2005 15:46:31 -0800
parents 17e8c70fb670
children 08c7851969cc
line wrap: on
line diff
--- a/mercurial/dirstate.py	Wed Nov 02 15:45:41 2005 -0800
+++ b/mercurial/dirstate.py	Wed Nov 02 15:46:31 2005 -0800
@@ -241,6 +241,22 @@
                 bs += 1
         return ret
 
+    def supported_type(self, f, st, verbose=True):
+        if stat.S_ISREG(st.st_mode):
+            return True
+        if verbose:
+            kind = 'unknown'
+            if stat.S_ISCHR(st.st_mode): kind = _('character device')
+            elif stat.S_ISBLK(st.st_mode): kind = _('block device')
+            elif stat.S_ISFIFO(st.st_mode): kind = _('fifo')
+            elif stat.S_ISLNK(st.st_mode): kind = _('symbolic link')
+            elif stat.S_ISSOCK(st.st_mode): kind = _('socket')
+            elif stat.S_ISDIR(st.st_mode): kind = _('directory')
+            self.ui.warn(_('%s: unsupported file type (type is %s)\n') % (
+                util.pathto(self.getcwd(), f),
+                kind))
+        return False
+
     def statwalk(self, files=None, match=util.always, dc=None):
         self.read()
 
@@ -278,22 +294,6 @@
     # directly by this function, but might be modified by your statmatch call.
     #
     def walkhelper(self, files, statmatch, dc):
-        def supported_type(f, st):
-            if stat.S_ISREG(st.st_mode):
-                return True
-            else:
-                kind = 'unknown'
-                if stat.S_ISCHR(st.st_mode): kind = _('character device')
-                elif stat.S_ISBLK(st.st_mode): kind = _('block device')
-                elif stat.S_ISFIFO(st.st_mode): kind = _('fifo')
-                elif stat.S_ISLNK(st.st_mode): kind = _('symbolic link')
-                elif stat.S_ISSOCK(st.st_mode): kind = _('socket')
-                elif stat.S_ISDIR(st.st_mode): kind = _('directory')
-                self.ui.warn(_('%s: unsupported file type (type is %s)\n') % (
-                    util.pathto(self.getcwd(), f),
-                    kind))
-                return False
-
         # recursion free walker, faster than os.walk.
         def findfiles(s):
             retfiles = []
@@ -316,9 +316,13 @@
                         ds = os.path.join(nd, f +'/')
                         if statmatch(ds, st):
                             work.append(p)
-                    elif statmatch(np, st) and supported_type(np, st):
-                        yield util.pconvert(np), st
-
+                        if statmatch(np, st) and np in dc:
+                            yield 'm', util.pconvert(np), st
+                    elif statmatch(np, st):
+                        if self.supported_type(np, st):
+                            yield 'f', util.pconvert(np), st
+                        elif np in dc:
+                            yield 'm', util.pconvert(np), st
 
         known = {'.hg': 1}
         def seen(fn):
@@ -337,22 +341,22 @@
                     inst.strerror))
                 continue
             if stat.S_ISDIR(st.st_mode):
-                cmp0 = (lambda x, y: cmp(x[0], y[0]))
+                cmp1 = (lambda x, y: cmp(x[1], y[1]))
                 sorted = [ x for x in findfiles(f) ]
-                sorted.sort(cmp0)
-                for fl, stl in sorted:
-                    yield 'f', fl, stl
+                sorted.sort(cmp1)
+                for e in sorted:
+                    yield e
             else:
                 ff = util.normpath(ff)
                 if seen(ff):
                     continue
-                found = False
                 self.blockignore = True
-                if statmatch(ff, st) and supported_type(ff, st):
-                    found = True
+                if statmatch(ff, st):
+                    if self.supported_type(ff, st):
+                        yield 'f', ff, st
+                    elif ff in dc:
+                        yield 'm', ff, st
                 self.blockignore = False
-                if found:
-                    yield 'f', ff, st
 
         # step two run through anything left in the dc hash and yield
         # if we haven't already seen it
@@ -373,13 +377,20 @@
                 unknown.append(fn)
                 continue
             if src == 'm':
-                try:
-                    st = os.stat(fn)
-                except OSError, inst:
+                nonexistent = True
+                if not st:
+                    try:
+                        st = os.lstat(fn)
+                    except OSError, inst:
+                        if inst.errno != errno.ENOENT:
+                            raise
+                        st = None
+                    # We need to re-check that it is a valid file
+                    if st and self.supported_type(fn, st):
+                        nonexistent = False
                 # XXX: what to do with file no longer present in the fs
                 # who are not removed in the dirstate ?
-                    if inst.errno != errno.ENOENT:
-                        raise
+                if nonexistent:
                     deleted.append(fn)
                     continue
             # check the common case first