Patchwork [3,of,4] lfs: override walk() in lfsvfs

mail settings
Submitter Matt Harbison
Date Dec. 8, 2017, 5:47 a.m.
Message ID <a6d7005a5cb25a88c37e.1512712025@Envy>
Download mbox | patch
Permalink /patch/26065/
State Superseded
Headers show


Matt Harbison - Dec. 8, 2017, 5:47 a.m.
# HG changeset patch
# User Matt Harbison <>
# Date 1512708246 18000
#      Thu Dec 07 23:44:06 2017 -0500
# Node ID a6d7005a5cb25a88c37ee3813eaee569b037f2f3
# Parent  bde45ffbd15011a829c4bf4b29c864ed864ccab6
lfs: override walk() in lfsvfs

In order to fix the missing lfs store after an upgrade, I attempted to walk the
store vfs to hardlink to the upgraded repo's store.  But the custom join()
clashes with the default walk() implementation.  First, 'path=None' blew up in
the regex matcher, because it wanted a string.  But even if that is fixed, the
join to walk the root of the vfs wouldn't match the required xx/xx...xx pattern.

This is basically a copy/paste of the default function, but using self.base and
reljoin() to bypass the custom join() method.  That seems slightly less wrong
than changing the default implementation based on the requirements imposed by
this extension.


diff --git a/hgext/lfs/ b/hgext/lfs/
--- a/hgext/lfs/
+++ b/hgext/lfs/
@@ -15,6 +15,7 @@ 
 from mercurial import (
+    pathutil,
     url as urlmod,
     vfs as vfsmod,
@@ -32,6 +33,23 @@ 
             raise error.ProgrammingError('unexpected lfs path: %s' % path)
         return super(lfsvfs, self).join(path[0:2], path[2:])
+    def walk(self, path=None, onerror=None):
+        """Yield (dirpath, dirs, files) tuple for each directories under path
+        ``dirpath`` is relative one from the root of this vfs. This
+        uses ``os.sep`` as path separator, even you specify POSIX
+        style ``path``.
+        "The root of this vfs" is represented as empty ``dirpath``.
+        """
+        root = os.path.normpath(self.base)
+        # when dirpath == root, dirpath[prefixlen:] becomes empty
+        # because len(dirpath) < prefixlen.
+        prefixlen = len(pathutil.normasprefix(root))
+        for dirpath, dirs, files in os.walk(self.reljoin(self.base, path or ''),
+                                            onerror=onerror):
+            yield (dirpath[prefixlen:], dirs, files)
 class filewithprogress(object):
     """a file-like object that supports __len__ and read.