[PATCH] Fix walking over non-existant and unhandled files

Bryan O'Sullivan bos at serpentine.com
Fri Aug 12 14:20:59 CDT 2005


Pullable from http://www.serpentine.com/hg

Fix walk code for files that do not exist anywhere, and unhandled file
types.

Prior to this, a file that did not exist was reported as showing up in
the filesystem, as were files of unsupported types (such as fifos).

Now, an error message is printed and nothing is returned in such cases.

This change also moves the commands.pathto function to the util module,
as the walk code needs it to print non-confusing error messages.


# HG changeset patch
# User Bryan O'Sullivan <bos at serpentine.com>
# Node ID 087771ebe2e6166fb6001a5f3f229043ae868cd3
# Parent  63ca8a68d59e68bf25c60667fb7cdb1c50d4fed7
Fix walk code for files that do not exist anywhere, and unhandled types.

Prior to this, a file that did not exist was reported as showing up in
the filesystem, as were files of unsupported types (such as fifos).

Now, an error message is printed and nothing is returned in such cases.

This change also moves the commands.pathto function to the util module,
as the walk code needs it to print non-confusing error messages.

diff -r 63ca8a68d59e -r 087771ebe2e6 mercurial/commands.py
--- a/mercurial/commands.py	Fri Aug 12 15:42:32 2005
+++ b/mercurial/commands.py	Fri Aug 12 19:16:58 2005
@@ -40,22 +40,12 @@
     return util.matcher(repo, cwd, pats or ['.'], opts.get('include'),
                         opts.get('exclude'), head)
 
-def pathto(n1, n2):
-    '''return the relative path from one place to another'''
-    if not n1: return n2
-    a, b = n1.split(os.sep), n2.split(os.sep)
-    a.reverse(), b.reverse()
-    while a and b and a[-1] == b[-1]:
-        a.pop(), b.pop()
-    b.reverse()
-    return os.sep.join((['..'] * len(a)) + b)
-
 def makewalk(repo, pats, opts, head = ''):
     cwd = repo.getcwd()
     files, matchfn = matchpats(repo, cwd, pats, opts, head)
     def walk():
         for src, fn in repo.walk(files = files, match = matchfn):
-            yield src, fn, pathto(cwd, fn)
+            yield src, fn, util.pathto(cwd, fn)
     return files, matchfn, walk()
 
 def walk(repo, pats, opts, head = ''):
@@ -1078,7 +1068,7 @@
 
     cwd = repo.getcwd()
     files, matchfn = matchpats(repo, cwd, pats, opts)
-    (c, a, d, u) = [[pathto(cwd, x) for x in n]
+    (c, a, d, u) = [[util.pathto(cwd, x) for x in n]
                     for n in repo.changes(files=files, match=matchfn)]
 
     changetypes = [('modified', 'M', c),
diff -r 63ca8a68d59e -r 087771ebe2e6 mercurial/hg.py
--- a/mercurial/hg.py	Fri Aug 12 15:42:32 2005
+++ b/mercurial/hg.py	Fri Aug 12 19:16:58 2005
@@ -11,7 +11,7 @@
 from demandload import *
 demandload(globals(), "re lock urllib urllib2 transaction time socket")
 demandload(globals(), "tempfile httprangereader bdiff urlparse")
-demandload(globals(), "bisect select")
+demandload(globals(), "bisect errno select stat")
 
 class filelog(revlog):
     def __init__(self, opener, path):
@@ -489,9 +489,16 @@
             if fn in known: return True
             known[fn] = 1
         def traverse():
-            for f in util.unique(files):
-                f = os.path.join(self.root, f)
-                if os.path.isdir(f):
+            for ff in util.unique(files):
+                f = os.path.join(self.root, ff)
+                try:
+                    st = os.stat(f)
+                except OSError, inst:
+                    if ff not in dc: self.ui.warn('%s: %s\n' % (
+                        util.pathto(self.getcwd(), ff),
+                        inst.strerror))
+                    continue
+                if stat.S_ISDIR(st.st_mode):
                     for dir, subdirs, fl in os.walk(f):
                         d = dir[len(self.root) + 1:]
                         nd = os.path.normpath(d)
@@ -507,8 +514,18 @@
                         for fn in fl:
                             fn = util.pconvert(os.path.join(d, fn))
                             yield 'f', fn
+                elif stat.S_ISREG(st.st_mode):
+                    yield 'f', ff
                 else:
-                    yield 'f', f[len(self.root) + 1:]
+                    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'
+                    self.ui.warn('%s: unsupported file type (type is %s)\n' % (
+                        util.pathto(self.getcwd(), ff),
+                        kind))
 
             ks = dc.keys()
             ks.sort()
diff -r 63ca8a68d59e -r 087771ebe2e6 mercurial/util.py
--- a/mercurial/util.py	Fri Aug 12 15:42:32 2005
+++ b/mercurial/util.py	Fri Aug 12 19:16:58 2005
@@ -68,6 +68,16 @@
     return head + res + tail
 
 _globchars = {'[': 1, '{': 1, '*': 1, '?': 1}
+
+def pathto(n1, n2):
+    '''return the relative path from one place to another'''
+    if not n1: return n2
+    a, b = n1.split(os.sep), n2.split(os.sep)
+    a.reverse(), b.reverse()
+    while a and b and a[-1] == b[-1]:
+        a.pop(), b.pop()
+    b.reverse()
+    return os.sep.join((['..'] * len(a)) + b)
 
 def canonpath(repo, cwd, myname):
     rootsep = repo.root + os.sep




More information about the Mercurial mailing list