##// END OF EJS Templates
revlog: add files method
revlog: add files method

File last commit:

r6890:fddef060 default
r6891:22cb8243 default
Show More
store.py
127 lines | 3.8 KiB | text/x-python | PythonLexer
Adrian Buehlmann
move filename encoding functions from util.py to new store.py
r6839 # store.py - repository store handling for Mercurial
#
# Copyright 2008 Matt Mackall <mpm@selenic.com>
#
# This software may be used and distributed according to the terms
# of the GNU General Public License, incorporated herein by reference.
Adrian Buehlmann
introduce store classes...
r6840 import os, stat, osutil, util
Adrian Buehlmann
move filename encoding functions from util.py to new store.py
r6839 def _buildencodefun():
e = '_'
win_reserved = [ord(x) for x in '\\:*?"<>|']
cmap = dict([ (chr(x), chr(x)) for x in xrange(127) ])
for x in (range(32) + range(126, 256) + win_reserved):
cmap[chr(x)] = "~%02x" % x
for x in range(ord("A"), ord("Z")+1) + [ord(e)]:
cmap[chr(x)] = e + chr(x).lower()
dmap = {}
for k, v in cmap.iteritems():
dmap[v] = k
def decode(s):
i = 0
while i < len(s):
for l in xrange(1, 4):
try:
yield dmap[s[i:i+l]]
i += l
break
except KeyError:
pass
else:
raise KeyError
return (lambda s: "".join([cmap[c] for c in s]),
lambda s: "".join(list(decode(s))))
encodefilename, decodefilename = _buildencodefun()
Adrian Buehlmann
introduce store classes...
r6840 def _dirwalk(path, recurse):
'''yields (filename, size)'''
for e, kind, st in osutil.listdir(path, stat=True):
pe = os.path.join(path, e)
if kind == stat.S_IFDIR:
if recurse:
for x in _dirwalk(pe, True):
yield x
elif kind == stat.S_IFREG:
yield pe, st.st_size
class _store:
'''base class for local repository stores'''
def __init__(self, path):
self.path = path
try:
# files in .hg/ will be created using this mode
mode = os.stat(self.path).st_mode
# avoid some useless chmods
if (0777 & ~util._umask) == (0777 & mode):
mode = None
except OSError:
mode = None
self.createmode = mode
def join(self, f):
return os.path.join(self.path, f)
def _revlogfiles(self, relpath='', recurse=False):
'''yields (filename, size)'''
if relpath:
path = os.path.join(self.path, relpath)
else:
path = self.path
Adrian Buehlmann
store.py: accept empty repos...
r6890 if not os.path.isdir(path):
return
Adrian Buehlmann
introduce store classes...
r6840 striplen = len(self.path) + len(os.sep)
filetypes = ('.d', '.i')
for f, size in _dirwalk(path, recurse):
if (len(f) > 2) and f[-2:] in filetypes:
yield util.pconvert(f[striplen:]), size
def _datafiles(self):
for x in self._revlogfiles('data', True):
yield x
def walk(self):
'''yields (direncoded filename, size)'''
# yield data files first
for x in self._datafiles():
yield x
# yield manifest before changelog
meta = util.sort(self._revlogfiles())
meta.reverse()
for x in meta:
yield x
class directstore(_store):
def __init__(self, path):
_store.__init__(self, path)
self.encodefn = lambda x: x
self.opener = util.opener(self.path)
self.opener.createmode = self.createmode
class encodedstore(_store):
def __init__(self, path):
_store.__init__(self, os.path.join(path, 'store'))
self.encodefn = encodefilename
op = util.opener(self.path)
op.createmode = self.createmode
self.opener = lambda f, *args, **kw: op(self.encodefn(f), *args, **kw)
def _datafiles(self):
for f, size in self._revlogfiles('data', True):
yield decodefilename(f), size
def join(self, f):
return os.path.join(self.path, self.encodefn(f))
def encodefn(requirements):
if 'store' not in requirements:
return lambda x: x
else:
return encodefilename
def store(requirements, path):
if 'store' not in requirements:
return directstore(path)
else:
return encodedstore(path)