Mercurial > hg
changeset 17595:741e2bef4155
merge with main
author | Thomas Arendsen Hein <thomas@intevation.de> |
---|---|
date | Tue, 18 Sep 2012 15:30:22 +0200 |
parents | 9e31a72bede7 (diff) 55724f42fa14 (current diff) |
children | 2eac9641496d |
files | |
diffstat | 3 files changed, 44 insertions(+), 35 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/store.py Mon Sep 17 15:13:17 2012 -0500 +++ b/mercurial/store.py Tue Sep 18 15:30:22 2012 +0200 @@ -22,8 +22,6 @@ >>> encodedir('data/foo.i.hg/bla.i') 'data/foo.i.hg.hg/bla.i' ''' - if not path.startswith('data/'): - return path return (path .replace(".hg/", ".hg.hg/") .replace(".i/", ".i.hg/") @@ -38,7 +36,7 @@ >>> decodedir('data/foo.i.hg.hg/bla.i') 'data/foo.i.hg/bla.i' ''' - if not path.startswith('data/') or ".hg/" not in path: + if ".hg/" not in path: return path return (path .replace(".d.hg/", ".d/") @@ -132,22 +130,23 @@ basename (e.g. "aux", "aux.foo"). A directory or file named "foo.aux" doesn't need encoding. - >>> _auxencode('.foo/aux.txt/txt.aux/con/prn/nul/foo.', True) + >>> s = '.foo/aux.txt/txt.aux/con/prn/nul/foo.' + >>> _auxencode(s.split('/'), True) ['~2efoo', 'au~78.txt', 'txt.aux', 'co~6e', 'pr~6e', 'nu~6c', 'foo~2e'] - >>> _auxencode('.com1com2/lpt9.lpt4.lpt1/conprn/com0/lpt0/foo.', False) + >>> s = '.com1com2/lpt9.lpt4.lpt1/conprn/com0/lpt0/foo.' + >>> _auxencode(s.split('/'), False) ['.com1com2', 'lp~749.lpt4.lpt1', 'conprn', 'com0', 'lpt0', 'foo~2e'] - >>> _auxencode('foo. ', True) + >>> _auxencode(['foo. '], True) ['foo.~20'] - >>> _auxencode(' .foo', True) + >>> _auxencode([' .foo'], True) ['~20.foo'] ''' - res = path.split('/') - for i, n in enumerate(res): + for i, n in enumerate(path): if not n: continue if dotencode and n[0] in '. ': n = "~%02x" % ord(n[0]) + n[1:] - res[i] = n + path[i] = n else: l = n.find('.') if l == -1: @@ -158,16 +157,16 @@ # encode third letter ('aux' -> 'au~78') ec = "~%02x" % ord(n[2]) n = n[0:2] + ec + n[3:] - res[i] = n + path[i] = n if n[-1] in '. ': # encode last period or space ('foo...' -> 'foo..~2e') - res[i] = n[:-1] + "~%02x" % ord(n[-1]) - return res + path[i] = n[:-1] + "~%02x" % ord(n[-1]) + return path _maxstorepathlen = 120 _dirprefixlen = 8 _maxshortdirslen = 8 * (_dirprefixlen + 1) - 4 -def _hybridencode(path, auxencode): +def _hybridencode(path, dotencode): '''encodes path with a length limit Encodes all paths that begin with 'data/', according to the following. @@ -198,27 +197,30 @@ The string 'data/' at the beginning is replaced with 'dh/', if the hashed encoding was used. ''' - if not path.startswith('data/'): - return path - # escape directories ending with .i and .d - path = encodedir(path) - ndpath = path[len('data/'):] - res = 'data/' + '/'.join(auxencode(encodefilename(ndpath))) + ef = encodefilename(path).split('/') + res = '/'.join(_auxencode(ef, dotencode)) if len(res) > _maxstorepathlen: + path = encodedir(path) digest = _sha(path).hexdigest() - parts = auxencode(lowerencode(ndpath)) - _root, ext = os.path.splitext(parts[-1]) + le = lowerencode(path).split('/')[1:] + parts = _auxencode(le, dotencode) basename = parts[-1] + _root, ext = os.path.splitext(basename) sdirs = [] + sdirslen = 0 for p in parts[:-1]: d = p[:_dirprefixlen] if d[-1] in '. ': # Windows can't access dirs ending in period or space d = d[:-1] + '_' - t = '/'.join(sdirs) + '/' + d - if len(t) > _maxshortdirslen: - break + if sdirslen == 0: + t = len(d) + else: + t = sdirslen + 1 + len(d) + if t > _maxshortdirslen: + break sdirs.append(d) + sdirslen = t dirs = '/'.join(sdirs) if len(dirs) > 0: dirs += '/' @@ -346,7 +348,7 @@ def _write(self, files, atomictemp): fp = self.opener('fncache', mode='wb', atomictemp=atomictemp) if files: - fp.write('\n'.join(map(encodedir, files)) + '\n') + fp.write(encodedir('\n'.join(files) + '\n')) fp.close() self._dirty = False @@ -394,8 +396,18 @@ self.fncache.add(path) return self.opener(self.encode(path), mode, *args, **kw) +def _plainhybridencode(f): + return _hybridencode(f, False) + +def _dothybridencode(f): + return _hybridencode(f, True) + class fncachestore(basicstore): - def __init__(self, path, openertype, encode): + def __init__(self, path, openertype, dotencode): + if dotencode: + encode = _dothybridencode + else: + encode = _plainhybridencode self.encode = encode self.path = path + '/store' self.pathsep = self.path + '/' @@ -442,8 +454,6 @@ def store(requirements, path, openertype): if 'store' in requirements: if 'fncache' in requirements: - auxencode = lambda f: _auxencode(f, 'dotencode' in requirements) - encode = lambda f: _hybridencode(f, auxencode) - return fncachestore(path, openertype, encode) + return fncachestore(path, openertype, 'dotencode' in requirements) return encodedstore(path, openertype) return basicstore(path, openertype)
--- a/tests/test-hybridencode.py Mon Sep 17 15:13:17 2012 -0500 +++ b/tests/test-hybridencode.py Tue Sep 18 15:30:22 2012 +0200 @@ -1,7 +1,6 @@ from mercurial import store -auxencode = lambda f: store._auxencode(f, True) -hybridencode = lambda f: store._hybridencode(f, auxencode) +hybridencode = lambda f: store._hybridencode(f, True) enc = hybridencode # used for 'dotencode' repo format @@ -41,7 +40,7 @@ ', pipe |, question-mark ?, asterisk *') print "encoding directories ending in .hg, .i or .d with '.hg' suffix" -show('data/x.hg/x.i/x.d/foo') +show('data/x.h.i/x.hg/x.i/x.d/foo') show('data/a.hg/a.i/a.d/foo') show('data/au.hg/au.i/au.d/foo') show('data/aux.hg/aux.i/aux.d/foo')
--- a/tests/test-hybridencode.py.out Mon Sep 17 15:13:17 2012 -0500 +++ b/tests/test-hybridencode.py.out Tue Sep 18 15:30:22 2012 +0200 @@ -35,8 +35,8 @@ B = 'data/less ~3c, greater ~3e, colon ~3a, double-quote ~22, backslash ~5c, pipe ~7c, question-mark ~3f, asterisk ~2a' encoding directories ending in .hg, .i or .d with '.hg' suffix -A = 'data/x.hg/x.i/x.d/foo' -B = 'data/x.hg.hg/x.i.hg/x.d.hg/foo' +A = 'data/x.h.i/x.hg/x.i/x.d/foo' +B = 'data/x.h.i.hg/x.hg.hg/x.i.hg/x.d.hg/foo' A = 'data/a.hg/a.i/a.d/foo' B = 'data/a.hg.hg/a.i.hg/a.d.hg/foo'