##// END OF EJS Templates
Fix for Issue1260
Fix for Issue1260

File last commit:

r6988:907e4e9b default
r6988:907e4e9b default
Show More
store.py
126 lines | 4.0 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()
Matt Mackall
store: simplify class hierarchy
r6898 def _calcmode(path):
try:
# files in .hg/ will be created using this mode
mode = os.stat(path).st_mode
# avoid some useless chmods
if (0777 & ~util._umask) == (0777 & mode):
mode = None
except OSError:
mode = None
return mode
Matt Mackall
clone: get a list of files to clone from store
r6903 _data = 'data 00manifest.d 00manifest.i 00changelog.d 00changelog.i'
Matt Mackall
store: simplify class hierarchy
r6898 class basicstore:
Adrian Buehlmann
introduce store classes...
r6840 '''base class for local repository stores'''
Adrian Buehlmann
Fix for Issue1260
r6988 def __init__(self, path, opener, pathjoiner):
self.pathjoiner = pathjoiner
Adrian Buehlmann
introduce store classes...
r6840 self.path = path
Matt Mackall
store: simplify class hierarchy
r6898 self.createmode = _calcmode(path)
self.opener = opener(self.path)
self.opener.createmode = self.createmode
Adrian Buehlmann
introduce store classes...
r6840
def join(self, f):
Adrian Buehlmann
Fix for Issue1260
r6988 return self.pathjoiner(self.path, f)
Adrian Buehlmann
introduce store classes...
r6840
Matt Mackall
store: simplify walking...
r6899 def _walk(self, relpath, recurse):
Matt Mackall
store: change handling of decoding errors
r6900 '''yields (unencoded, encoded, size)'''
Adrian Buehlmann
Fix for Issue1260
r6988 path = self.pathjoiner(self.path, relpath)
Adrian Buehlmann
introduce store classes...
r6840 striplen = len(self.path) + len(os.sep)
Matt Mackall
store: simplify walking...
r6899 prefix = path[striplen:]
l = []
if os.path.isdir(path):
visit = [path]
while visit:
p = visit.pop()
for f, kind, st in osutil.listdir(p, stat=True):
Adrian Buehlmann
Fix for Issue1260
r6988 fp = self.pathjoiner(p, f)
Matt Mackall
store: simplify walking...
r6899 if kind == stat.S_IFREG and f[-2:] in ('.d', '.i'):
Matt Mackall
store: change handling of decoding errors
r6900 n = util.pconvert(fp[striplen:])
l.append((n, n, st.st_size))
Matt Mackall
store: simplify walking...
r6899 elif kind == stat.S_IFDIR and recurse:
visit.append(fp)
return util.sort(l)
Adrian Buehlmann
introduce store classes...
r6840
Matt Mackall
store: change handling of decoding errors
r6900 def datafiles(self):
Matt Mackall
store: simplify walking...
r6899 return self._walk('data', True)
Adrian Buehlmann
introduce store classes...
r6840
def walk(self):
Matt Mackall
store: change handling of decoding errors
r6900 '''yields (unencoded, encoded, size)'''
Adrian Buehlmann
introduce store classes...
r6840 # yield data files first
Adrian Buehlmann
verify: check repo.store
r6892 for x in self.datafiles():
Adrian Buehlmann
introduce store classes...
r6840 yield x
# yield manifest before changelog
Matt Mackall
store: simplify walking...
r6899 meta = self._walk('', False)
Adrian Buehlmann
introduce store classes...
r6840 meta.reverse()
for x in meta:
yield x
Matt Mackall
clone: get a list of files to clone from store
r6903 def copylist(self):
return ['requires'] + _data.split()
Matt Mackall
store: simplify class hierarchy
r6898 class encodedstore(basicstore):
Adrian Buehlmann
Fix for Issue1260
r6988 def __init__(self, path, opener, pathjoiner):
self.pathjoiner = pathjoiner
self.path = self.pathjoiner(path, 'store')
Matt Mackall
store: simplify class hierarchy
r6898 self.createmode = _calcmode(self.path)
Matt Mackall
store: take opener as an argument
r6896 op = opener(self.path)
Adrian Buehlmann
introduce store classes...
r6840 op.createmode = self.createmode
Matt Mackall
store: drop self.encodefn
r6902 self.opener = lambda f, *args, **kw: op(encodefilename(f), *args, **kw)
Adrian Buehlmann
introduce store classes...
r6840
Matt Mackall
store: change handling of decoding errors
r6900 def datafiles(self):
for a, b, size in self._walk('data', True):
Adrian Buehlmann
verify: check repo.store
r6892 try:
Matt Mackall
store: change handling of decoding errors
r6900 a = decodefilename(a)
Adrian Buehlmann
verify: check repo.store
r6892 except KeyError:
Matt Mackall
store: change handling of decoding errors
r6900 a = None
yield a, b, size
Adrian Buehlmann
introduce store classes...
r6840
def join(self, f):
Adrian Buehlmann
Fix for Issue1260
r6988 return self.pathjoiner(self.path, encodefilename(f))
Adrian Buehlmann
introduce store classes...
r6840
Matt Mackall
clone: get a list of files to clone from store
r6903 def copylist(self):
return (['requires', '00changelog.i'] +
Adrian Buehlmann
Fix for Issue1260
r6988 [self.pathjoiner('store', f) for f in _data.split()])
Matt Mackall
clone: get a list of files to clone from store
r6903
Adrian Buehlmann
Fix for Issue1260
r6988 def store(requirements, path, opener, pathjoiner):
Matt Mackall
store: simplify class hierarchy
r6898 if 'store' in requirements:
Adrian Buehlmann
Fix for Issue1260
r6988 return encodedstore(path, opener, pathjoiner)
return basicstore(path, opener, pathjoiner)