Show More
@@ -22,7 +22,8 b' propertycache = util.propertycache' | |||||
22 | class localrepository(repo.repository): |
|
22 | class localrepository(repo.repository): | |
23 | capabilities = set(('lookup', 'changegroupsubset', 'branchmap', 'pushkey')) |
|
23 | capabilities = set(('lookup', 'changegroupsubset', 'branchmap', 'pushkey')) | |
24 | supportedformats = set(('revlogv1', 'parentdelta')) |
|
24 | supportedformats = set(('revlogv1', 'parentdelta')) | |
25 |
supported = supportedformats | set(('store', 'fncache', 'shared' |
|
25 | supported = supportedformats | set(('store', 'fncache', 'shared', | |
|
26 | 'dotencode')) | |||
26 |
|
27 | |||
27 | def __init__(self, baseui, path=None, create=0): |
|
28 | def __init__(self, baseui, path=None, create=0): | |
28 | repo.repository.__init__(self) |
|
29 | repo.repository.__init__(self) | |
@@ -52,6 +53,8 b' class localrepository(repo.repository):' | |||||
52 | requirements.append("store") |
|
53 | requirements.append("store") | |
53 | if self.ui.configbool('format', 'usefncache', True): |
|
54 | if self.ui.configbool('format', 'usefncache', True): | |
54 | requirements.append("fncache") |
|
55 | requirements.append("fncache") | |
|
56 | if self.ui.configbool('format', 'dotencode', True): | |||
|
57 | requirements.append('dotencode') | |||
55 | # create an invalid changelog |
|
58 | # create an invalid changelog | |
56 | self.opener("00changelog.i", "a").write( |
|
59 | self.opener("00changelog.i", "a").write( | |
57 | '\0\0\0\2' # represents revlogv2 |
|
60 | '\0\0\0\2' # represents revlogv2 |
@@ -71,7 +71,7 b' lowerencode = _build_lower_encodefun()' | |||||
71 | _windows_reserved_filenames = '''con prn aux nul |
|
71 | _windows_reserved_filenames = '''con prn aux nul | |
72 | com1 com2 com3 com4 com5 com6 com7 com8 com9 |
|
72 | com1 com2 com3 com4 com5 com6 com7 com8 com9 | |
73 | lpt1 lpt2 lpt3 lpt4 lpt5 lpt6 lpt7 lpt8 lpt9'''.split() |
|
73 | lpt1 lpt2 lpt3 lpt4 lpt5 lpt6 lpt7 lpt8 lpt9'''.split() | |
74 | def auxencode(path): |
|
74 | def _auxencode(path, dotencode): | |
75 | res = [] |
|
75 | res = [] | |
76 | for n in path.split('/'): |
|
76 | for n in path.split('/'): | |
77 | if n: |
|
77 | if n: | |
@@ -83,13 +83,15 b' def auxencode(path):' | |||||
83 | if n[-1] in '. ': |
|
83 | if n[-1] in '. ': | |
84 | # encode last period or space ('foo...' -> 'foo..~2e') |
|
84 | # encode last period or space ('foo...' -> 'foo..~2e') | |
85 | n = n[:-1] + "~%02x" % ord(n[-1]) |
|
85 | n = n[:-1] + "~%02x" % ord(n[-1]) | |
|
86 | if dotencode and n[0] in '. ': | |||
|
87 | n = "~%02x" % ord(n[0]) + n[1:] | |||
86 | res.append(n) |
|
88 | res.append(n) | |
87 | return '/'.join(res) |
|
89 | return '/'.join(res) | |
88 |
|
90 | |||
89 | MAX_PATH_LEN_IN_HGSTORE = 120 |
|
91 | MAX_PATH_LEN_IN_HGSTORE = 120 | |
90 | DIR_PREFIX_LEN = 8 |
|
92 | DIR_PREFIX_LEN = 8 | |
91 | _MAX_SHORTENED_DIRS_LEN = 8 * (DIR_PREFIX_LEN + 1) - 4 |
|
93 | _MAX_SHORTENED_DIRS_LEN = 8 * (DIR_PREFIX_LEN + 1) - 4 | |
92 | def hybridencode(path): |
|
94 | def _hybridencode(path, auxencode): | |
93 | '''encodes path with a length limit |
|
95 | '''encodes path with a length limit | |
94 |
|
96 | |||
95 | Encodes all paths that begin with 'data/', according to the following. |
|
97 | Encodes all paths that begin with 'data/', according to the following. | |
@@ -282,7 +284,8 b' class fncache(object):' | |||||
282 | return iter(self.entries) |
|
284 | return iter(self.entries) | |
283 |
|
285 | |||
284 | class fncachestore(basicstore): |
|
286 | class fncachestore(basicstore): | |
285 | def __init__(self, path, opener, pathjoiner): |
|
287 | def __init__(self, path, opener, pathjoiner, encode): | |
|
288 | self.encode = encode | |||
286 | self.pathjoiner = pathjoiner |
|
289 | self.pathjoiner = pathjoiner | |
287 | self.path = self.pathjoiner(path, 'store') |
|
290 | self.path = self.pathjoiner(path, 'store') | |
288 | self.createmode = _calcmode(self.path) |
|
291 | self.createmode = _calcmode(self.path) | |
@@ -294,11 +297,11 b' class fncachestore(basicstore):' | |||||
294 | def fncacheopener(path, mode='r', *args, **kw): |
|
297 | def fncacheopener(path, mode='r', *args, **kw): | |
295 | if mode not in ('r', 'rb') and path.startswith('data/'): |
|
298 | if mode not in ('r', 'rb') and path.startswith('data/'): | |
296 | fnc.add(path) |
|
299 | fnc.add(path) | |
297 |
return op( |
|
300 | return op(self.encode(path), mode, *args, **kw) | |
298 | self.opener = fncacheopener |
|
301 | self.opener = fncacheopener | |
299 |
|
302 | |||
300 | def join(self, f): |
|
303 | def join(self, f): | |
301 |
return self.pathjoiner(self.path, |
|
304 | return self.pathjoiner(self.path, self.encode(f)) | |
302 |
|
305 | |||
303 | def datafiles(self): |
|
306 | def datafiles(self): | |
304 | rewrite = False |
|
307 | rewrite = False | |
@@ -306,7 +309,7 b' class fncachestore(basicstore):' | |||||
306 | pjoin = self.pathjoiner |
|
309 | pjoin = self.pathjoiner | |
307 | spath = self.path |
|
310 | spath = self.path | |
308 | for f in self.fncache: |
|
311 | for f in self.fncache: | |
309 |
ef = |
|
312 | ef = self.encode(f) | |
310 | try: |
|
313 | try: | |
311 | st = os.stat(pjoin(spath, ef)) |
|
314 | st = os.stat(pjoin(spath, ef)) | |
312 | yield f, ef, st.st_size |
|
315 | yield f, ef, st.st_size | |
@@ -328,6 +331,8 b' def store(requirements, path, opener, pa' | |||||
328 | pathjoiner = pathjoiner or os.path.join |
|
331 | pathjoiner = pathjoiner or os.path.join | |
329 | if 'store' in requirements: |
|
332 | if 'store' in requirements: | |
330 | if 'fncache' in requirements: |
|
333 | if 'fncache' in requirements: | |
331 | return fncachestore(path, opener, pathjoiner) |
|
334 | auxencode = lambda f: _auxencode(f, 'dotencode' in requirements) | |
|
335 | encode = lambda f: _hybridencode(f, auxencode) | |||
|
336 | return fncachestore(path, opener, pathjoiner, encode) | |||
332 | return encodedstore(path, opener, pathjoiner) |
|
337 | return encodedstore(path, opener, pathjoiner) | |
333 | return basicstore(path, opener, pathjoiner) |
|
338 | return basicstore(path, opener, pathjoiner) |
@@ -2,7 +2,10 b'' | |||||
2 |
|
2 | |||
3 | from mercurial import store |
|
3 | from mercurial import store | |
4 |
|
4 | |||
5 | enc = store.hybridencode # used for fncache repo format |
|
5 | auxencode = lambda f: store._auxencode(f, True) | |
|
6 | hybridencode = lambda f: store._hybridencode(f, auxencode) | |||
|
7 | ||||
|
8 | enc = hybridencode # used for 'dotencode' repo format | |||
6 |
|
9 | |||
7 | def show(s): |
|
10 | def show(s): | |
8 | print "A = '%s'" % s |
|
11 | print "A = '%s'" % s | |
@@ -22,4 +25,5 b" show('data/Project Planning/Resources/An" | |||||
22 | 'Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt') |
|
25 | 'Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt') | |
23 | show('data/Project.Planning/Resources/AnotherLongDirectoryName/' |
|
26 | show('data/Project.Planning/Resources/AnotherLongDirectoryName/' | |
24 | 'Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt') |
|
27 | 'Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt') | |
25 | show('data/foo.../foo / /a./_. /__/.x../ bla/something.i') |
|
28 | show('data/foo.../foo / /a./_. /__/.x../ bla/.FOO/something.i') | |
|
29 |
@@ -16,6 +16,6 b" B = 'dh/project_/resource/anotherl/follo" | |||||
16 | A = 'data/Project.Planning/Resources/AnotherLongDirectoryName/Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt' |
|
16 | A = 'data/Project.Planning/Resources/AnotherLongDirectoryName/Followedbyanother/AndAnother/AndThenAnExtremelyLongFileName.txt' | |
17 | B = 'dh/project_/resource/anotherl/followed/andanoth/andthenanextremelylongfilena0fd7c506f5c9d58204444fc67e9499006bd2d445.txt' |
|
17 | B = 'dh/project_/resource/anotherl/followed/andanoth/andthenanextremelylongfilena0fd7c506f5c9d58204444fc67e9499006bd2d445.txt' | |
18 |
|
18 | |||
19 | A = 'data/foo.../foo / /a./_. /__/.x../ bla/something.i' |
|
19 | A = 'data/foo.../foo / /a./_. /__/.x../ bla/.FOO/something.i' | |
20 |
B = 'data/foo..~2e/foo ~20/~20/a~2e/__.~20/____/ |
|
20 | B = 'data/foo..~2e/foo ~20/~20/a~2e/__.~20/____/~2ex.~2e/~20 bla/~2e_f_o_o/something.i' | |
21 |
|
21 |
@@ -42,6 +42,7 b" creating 'local'" | |||||
42 | revlogv1 |
|
42 | revlogv1 | |
43 | store |
|
43 | store | |
44 | fncache |
|
44 | fncache | |
|
45 | dotencode | |||
45 | $ echo this > local/foo |
|
46 | $ echo this > local/foo | |
46 | $ hg ci --cwd local -A -m "init" |
|
47 | $ hg ci --cwd local -A -m "init" | |
47 | adding foo |
|
48 | adding foo | |
@@ -157,6 +158,7 b" creating 'local/sub/repo'" | |||||
157 | revlogv1 |
|
158 | revlogv1 | |
158 | store |
|
159 | store | |
159 | fncache |
|
160 | fncache | |
|
161 | dotencode | |||
160 |
|
162 | |||
161 | prepare test of init of url configured from paths |
|
163 | prepare test of init of url configured from paths | |
162 |
|
164 | |||
@@ -173,6 +175,7 b' init should (for consistency with clone)' | |||||
173 | revlogv1 |
|
175 | revlogv1 | |
174 | store |
|
176 | store | |
175 | fncache |
|
177 | fncache | |
|
178 | dotencode | |||
176 |
|
179 | |||
177 | verify that clone also expand urls |
|
180 | verify that clone also expand urls | |
178 |
|
181 | |||
@@ -185,3 +188,4 b' verify that clone also expand urls' | |||||
185 | revlogv1 |
|
188 | revlogv1 | |
186 | store |
|
189 | store | |
187 | fncache |
|
190 | fncache | |
|
191 | dotencode |
General Comments 0
You need to be logged in to leave comments.
Login now