##// END OF EJS Templates
store: use absolute_import
Gregory Szorc -
r27480:50915967 default
parent child Browse files
Show More
@@ -1,542 +1,552
1 1 # store.py - repository store handling for Mercurial
2 2 #
3 3 # Copyright 2008 Matt Mackall <mpm@selenic.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 from i18n import _
9 import scmutil, util, parsers, error
10 import os, stat, errno
8 from __future__ import absolute_import
9
10 import errno
11 import os
12 import stat
13
14 from .i18n import _
15 from . import (
16 error,
17 parsers,
18 scmutil,
19 util,
20 )
11 21
12 22 _sha = util.sha1
13 23
14 24 # This avoids a collision between a file named foo and a dir named
15 25 # foo.i or foo.d
16 26 def _encodedir(path):
17 27 '''
18 28 >>> _encodedir('data/foo.i')
19 29 'data/foo.i'
20 30 >>> _encodedir('data/foo.i/bla.i')
21 31 'data/foo.i.hg/bla.i'
22 32 >>> _encodedir('data/foo.i.hg/bla.i')
23 33 'data/foo.i.hg.hg/bla.i'
24 34 >>> _encodedir('data/foo.i\\ndata/foo.i/bla.i\\ndata/foo.i.hg/bla.i\\n')
25 35 'data/foo.i\\ndata/foo.i.hg/bla.i\\ndata/foo.i.hg.hg/bla.i\\n'
26 36 '''
27 37 return (path
28 38 .replace(".hg/", ".hg.hg/")
29 39 .replace(".i/", ".i.hg/")
30 40 .replace(".d/", ".d.hg/"))
31 41
32 42 encodedir = getattr(parsers, 'encodedir', _encodedir)
33 43
34 44 def decodedir(path):
35 45 '''
36 46 >>> decodedir('data/foo.i')
37 47 'data/foo.i'
38 48 >>> decodedir('data/foo.i.hg/bla.i')
39 49 'data/foo.i/bla.i'
40 50 >>> decodedir('data/foo.i.hg.hg/bla.i')
41 51 'data/foo.i.hg/bla.i'
42 52 '''
43 53 if ".hg/" not in path:
44 54 return path
45 55 return (path
46 56 .replace(".d.hg/", ".d/")
47 57 .replace(".i.hg/", ".i/")
48 58 .replace(".hg.hg/", ".hg/"))
49 59
50 60 def _buildencodefun():
51 61 '''
52 62 >>> enc, dec = _buildencodefun()
53 63
54 64 >>> enc('nothing/special.txt')
55 65 'nothing/special.txt'
56 66 >>> dec('nothing/special.txt')
57 67 'nothing/special.txt'
58 68
59 69 >>> enc('HELLO')
60 70 '_h_e_l_l_o'
61 71 >>> dec('_h_e_l_l_o')
62 72 'HELLO'
63 73
64 74 >>> enc('hello:world?')
65 75 'hello~3aworld~3f'
66 76 >>> dec('hello~3aworld~3f')
67 77 'hello:world?'
68 78
69 79 >>> enc('the\x07quick\xADshot')
70 80 'the~07quick~adshot'
71 81 >>> dec('the~07quick~adshot')
72 82 'the\\x07quick\\xadshot'
73 83 '''
74 84 e = '_'
75 85 winreserved = [ord(x) for x in '\\:*?"<>|']
76 86 cmap = dict([(chr(x), chr(x)) for x in xrange(127)])
77 87 for x in (range(32) + range(126, 256) + winreserved):
78 88 cmap[chr(x)] = "~%02x" % x
79 89 for x in range(ord("A"), ord("Z") + 1) + [ord(e)]:
80 90 cmap[chr(x)] = e + chr(x).lower()
81 91 dmap = {}
82 92 for k, v in cmap.iteritems():
83 93 dmap[v] = k
84 94 def decode(s):
85 95 i = 0
86 96 while i < len(s):
87 97 for l in xrange(1, 4):
88 98 try:
89 99 yield dmap[s[i:i + l]]
90 100 i += l
91 101 break
92 102 except KeyError:
93 103 pass
94 104 else:
95 105 raise KeyError
96 106 return (lambda s: ''.join([cmap[c] for c in s]),
97 107 lambda s: ''.join(list(decode(s))))
98 108
99 109 _encodefname, _decodefname = _buildencodefun()
100 110
101 111 def encodefilename(s):
102 112 '''
103 113 >>> encodefilename('foo.i/bar.d/bla.hg/hi:world?/HELLO')
104 114 'foo.i.hg/bar.d.hg/bla.hg.hg/hi~3aworld~3f/_h_e_l_l_o'
105 115 '''
106 116 return _encodefname(encodedir(s))
107 117
108 118 def decodefilename(s):
109 119 '''
110 120 >>> decodefilename('foo.i.hg/bar.d.hg/bla.hg.hg/hi~3aworld~3f/_h_e_l_l_o')
111 121 'foo.i/bar.d/bla.hg/hi:world?/HELLO'
112 122 '''
113 123 return decodedir(_decodefname(s))
114 124
115 125 def _buildlowerencodefun():
116 126 '''
117 127 >>> f = _buildlowerencodefun()
118 128 >>> f('nothing/special.txt')
119 129 'nothing/special.txt'
120 130 >>> f('HELLO')
121 131 'hello'
122 132 >>> f('hello:world?')
123 133 'hello~3aworld~3f'
124 134 >>> f('the\x07quick\xADshot')
125 135 'the~07quick~adshot'
126 136 '''
127 137 winreserved = [ord(x) for x in '\\:*?"<>|']
128 138 cmap = dict([(chr(x), chr(x)) for x in xrange(127)])
129 139 for x in (range(32) + range(126, 256) + winreserved):
130 140 cmap[chr(x)] = "~%02x" % x
131 141 for x in range(ord("A"), ord("Z") + 1):
132 142 cmap[chr(x)] = chr(x).lower()
133 143 return lambda s: "".join([cmap[c] for c in s])
134 144
135 145 lowerencode = getattr(parsers, 'lowerencode', None) or _buildlowerencodefun()
136 146
137 147 # Windows reserved names: con, prn, aux, nul, com1..com9, lpt1..lpt9
138 148 _winres3 = ('aux', 'con', 'prn', 'nul') # length 3
139 149 _winres4 = ('com', 'lpt') # length 4 (with trailing 1..9)
140 150 def _auxencode(path, dotencode):
141 151 '''
142 152 Encodes filenames containing names reserved by Windows or which end in
143 153 period or space. Does not touch other single reserved characters c.
144 154 Specifically, c in '\\:*?"<>|' or ord(c) <= 31 are *not* encoded here.
145 155 Additionally encodes space or period at the beginning, if dotencode is
146 156 True. Parameter path is assumed to be all lowercase.
147 157 A segment only needs encoding if a reserved name appears as a
148 158 basename (e.g. "aux", "aux.foo"). A directory or file named "foo.aux"
149 159 doesn't need encoding.
150 160
151 161 >>> s = '.foo/aux.txt/txt.aux/con/prn/nul/foo.'
152 162 >>> _auxencode(s.split('/'), True)
153 163 ['~2efoo', 'au~78.txt', 'txt.aux', 'co~6e', 'pr~6e', 'nu~6c', 'foo~2e']
154 164 >>> s = '.com1com2/lpt9.lpt4.lpt1/conprn/com0/lpt0/foo.'
155 165 >>> _auxencode(s.split('/'), False)
156 166 ['.com1com2', 'lp~749.lpt4.lpt1', 'conprn', 'com0', 'lpt0', 'foo~2e']
157 167 >>> _auxencode(['foo. '], True)
158 168 ['foo.~20']
159 169 >>> _auxencode([' .foo'], True)
160 170 ['~20.foo']
161 171 '''
162 172 for i, n in enumerate(path):
163 173 if not n:
164 174 continue
165 175 if dotencode and n[0] in '. ':
166 176 n = "~%02x" % ord(n[0]) + n[1:]
167 177 path[i] = n
168 178 else:
169 179 l = n.find('.')
170 180 if l == -1:
171 181 l = len(n)
172 182 if ((l == 3 and n[:3] in _winres3) or
173 183 (l == 4 and n[3] <= '9' and n[3] >= '1'
174 184 and n[:3] in _winres4)):
175 185 # encode third letter ('aux' -> 'au~78')
176 186 ec = "~%02x" % ord(n[2])
177 187 n = n[0:2] + ec + n[3:]
178 188 path[i] = n
179 189 if n[-1] in '. ':
180 190 # encode last period or space ('foo...' -> 'foo..~2e')
181 191 path[i] = n[:-1] + "~%02x" % ord(n[-1])
182 192 return path
183 193
184 194 _maxstorepathlen = 120
185 195 _dirprefixlen = 8
186 196 _maxshortdirslen = 8 * (_dirprefixlen + 1) - 4
187 197
188 198 def _hashencode(path, dotencode):
189 199 digest = _sha(path).hexdigest()
190 200 le = lowerencode(path[5:]).split('/') # skips prefix 'data/' or 'meta/'
191 201 parts = _auxencode(le, dotencode)
192 202 basename = parts[-1]
193 203 _root, ext = os.path.splitext(basename)
194 204 sdirs = []
195 205 sdirslen = 0
196 206 for p in parts[:-1]:
197 207 d = p[:_dirprefixlen]
198 208 if d[-1] in '. ':
199 209 # Windows can't access dirs ending in period or space
200 210 d = d[:-1] + '_'
201 211 if sdirslen == 0:
202 212 t = len(d)
203 213 else:
204 214 t = sdirslen + 1 + len(d)
205 215 if t > _maxshortdirslen:
206 216 break
207 217 sdirs.append(d)
208 218 sdirslen = t
209 219 dirs = '/'.join(sdirs)
210 220 if len(dirs) > 0:
211 221 dirs += '/'
212 222 res = 'dh/' + dirs + digest + ext
213 223 spaceleft = _maxstorepathlen - len(res)
214 224 if spaceleft > 0:
215 225 filler = basename[:spaceleft]
216 226 res = 'dh/' + dirs + filler + digest + ext
217 227 return res
218 228
219 229 def _hybridencode(path, dotencode):
220 230 '''encodes path with a length limit
221 231
222 232 Encodes all paths that begin with 'data/', according to the following.
223 233
224 234 Default encoding (reversible):
225 235
226 236 Encodes all uppercase letters 'X' as '_x'. All reserved or illegal
227 237 characters are encoded as '~xx', where xx is the two digit hex code
228 238 of the character (see encodefilename).
229 239 Relevant path components consisting of Windows reserved filenames are
230 240 masked by encoding the third character ('aux' -> 'au~78', see _auxencode).
231 241
232 242 Hashed encoding (not reversible):
233 243
234 244 If the default-encoded path is longer than _maxstorepathlen, a
235 245 non-reversible hybrid hashing of the path is done instead.
236 246 This encoding uses up to _dirprefixlen characters of all directory
237 247 levels of the lowerencoded path, but not more levels than can fit into
238 248 _maxshortdirslen.
239 249 Then follows the filler followed by the sha digest of the full path.
240 250 The filler is the beginning of the basename of the lowerencoded path
241 251 (the basename is everything after the last path separator). The filler
242 252 is as long as possible, filling in characters from the basename until
243 253 the encoded path has _maxstorepathlen characters (or all chars of the
244 254 basename have been taken).
245 255 The extension (e.g. '.i' or '.d') is preserved.
246 256
247 257 The string 'data/' at the beginning is replaced with 'dh/', if the hashed
248 258 encoding was used.
249 259 '''
250 260 path = encodedir(path)
251 261 ef = _encodefname(path).split('/')
252 262 res = '/'.join(_auxencode(ef, dotencode))
253 263 if len(res) > _maxstorepathlen:
254 264 res = _hashencode(path, dotencode)
255 265 return res
256 266
257 267 def _pathencode(path):
258 268 de = encodedir(path)
259 269 if len(path) > _maxstorepathlen:
260 270 return _hashencode(de, True)
261 271 ef = _encodefname(de).split('/')
262 272 res = '/'.join(_auxencode(ef, True))
263 273 if len(res) > _maxstorepathlen:
264 274 return _hashencode(de, True)
265 275 return res
266 276
267 277 _pathencode = getattr(parsers, 'pathencode', _pathencode)
268 278
269 279 def _plainhybridencode(f):
270 280 return _hybridencode(f, False)
271 281
272 282 def _calcmode(vfs):
273 283 try:
274 284 # files in .hg/ will be created using this mode
275 285 mode = vfs.stat().st_mode
276 286 # avoid some useless chmods
277 287 if (0o777 & ~util.umask) == (0o777 & mode):
278 288 mode = None
279 289 except OSError:
280 290 mode = None
281 291 return mode
282 292
283 293 _data = ('data 00manifest.d 00manifest.i 00changelog.d 00changelog.i'
284 294 ' phaseroots obsstore')
285 295
286 296 class basicstore(object):
287 297 '''base class for local repository stores'''
288 298 def __init__(self, path, vfstype):
289 299 vfs = vfstype(path)
290 300 self.path = vfs.base
291 301 self.createmode = _calcmode(vfs)
292 302 vfs.createmode = self.createmode
293 303 self.rawvfs = vfs
294 304 self.vfs = scmutil.filtervfs(vfs, encodedir)
295 305 self.opener = self.vfs
296 306
297 307 def join(self, f):
298 308 return self.path + '/' + encodedir(f)
299 309
300 310 def _walk(self, relpath, recurse):
301 311 '''yields (unencoded, encoded, size)'''
302 312 path = self.path
303 313 if relpath:
304 314 path += '/' + relpath
305 315 striplen = len(self.path) + 1
306 316 l = []
307 317 if self.rawvfs.isdir(path):
308 318 visit = [path]
309 319 readdir = self.rawvfs.readdir
310 320 while visit:
311 321 p = visit.pop()
312 322 for f, kind, st in readdir(p, stat=True):
313 323 fp = p + '/' + f
314 324 if kind == stat.S_IFREG and f[-2:] in ('.d', '.i'):
315 325 n = util.pconvert(fp[striplen:])
316 326 l.append((decodedir(n), n, st.st_size))
317 327 elif kind == stat.S_IFDIR and recurse:
318 328 visit.append(fp)
319 329 l.sort()
320 330 return l
321 331
322 332 def datafiles(self):
323 333 return self._walk('data', True)
324 334
325 335 def topfiles(self):
326 336 # yield manifest before changelog
327 337 return reversed(self._walk('', False))
328 338
329 339 def walk(self):
330 340 '''yields (unencoded, encoded, size)'''
331 341 # yield data files first
332 342 for x in self.datafiles():
333 343 yield x
334 344 for x in self.topfiles():
335 345 yield x
336 346
337 347 def copylist(self):
338 348 return ['requires'] + _data.split()
339 349
340 350 def write(self, tr):
341 351 pass
342 352
343 353 def invalidatecaches(self):
344 354 pass
345 355
346 356 def markremoved(self, fn):
347 357 pass
348 358
349 359 def __contains__(self, path):
350 360 '''Checks if the store contains path'''
351 361 path = "/".join(("data", path))
352 362 # file?
353 363 if self.vfs.exists(path + ".i"):
354 364 return True
355 365 # dir?
356 366 if not path.endswith("/"):
357 367 path = path + "/"
358 368 return self.vfs.exists(path)
359 369
360 370 class encodedstore(basicstore):
361 371 def __init__(self, path, vfstype):
362 372 vfs = vfstype(path + '/store')
363 373 self.path = vfs.base
364 374 self.createmode = _calcmode(vfs)
365 375 vfs.createmode = self.createmode
366 376 self.rawvfs = vfs
367 377 self.vfs = scmutil.filtervfs(vfs, encodefilename)
368 378 self.opener = self.vfs
369 379
370 380 def datafiles(self):
371 381 for a, b, size in self._walk('data', True):
372 382 try:
373 383 a = decodefilename(a)
374 384 except KeyError:
375 385 a = None
376 386 yield a, b, size
377 387
378 388 def join(self, f):
379 389 return self.path + '/' + encodefilename(f)
380 390
381 391 def copylist(self):
382 392 return (['requires', '00changelog.i'] +
383 393 ['store/' + f for f in _data.split()])
384 394
385 395 class fncache(object):
386 396 # the filename used to be partially encoded
387 397 # hence the encodedir/decodedir dance
388 398 def __init__(self, vfs):
389 399 self.vfs = vfs
390 400 self.entries = None
391 401 self._dirty = False
392 402
393 403 def _load(self):
394 404 '''fill the entries from the fncache file'''
395 405 self._dirty = False
396 406 try:
397 407 fp = self.vfs('fncache', mode='rb')
398 408 except IOError:
399 409 # skip nonexistent file
400 410 self.entries = set()
401 411 return
402 412 self.entries = set(decodedir(fp.read()).splitlines())
403 413 if '' in self.entries:
404 414 fp.seek(0)
405 415 for n, line in enumerate(fp):
406 416 if not line.rstrip('\n'):
407 417 t = _('invalid entry in fncache, line %d') % (n + 1)
408 418 raise error.Abort(t)
409 419 fp.close()
410 420
411 421 def write(self, tr):
412 422 if self._dirty:
413 423 tr.addbackup('fncache')
414 424 fp = self.vfs('fncache', mode='wb', atomictemp=True)
415 425 if self.entries:
416 426 fp.write(encodedir('\n'.join(self.entries) + '\n'))
417 427 fp.close()
418 428 self._dirty = False
419 429
420 430 def add(self, fn):
421 431 if self.entries is None:
422 432 self._load()
423 433 if fn not in self.entries:
424 434 self._dirty = True
425 435 self.entries.add(fn)
426 436
427 437 def remove(self, fn):
428 438 if self.entries is None:
429 439 self._load()
430 440 try:
431 441 self.entries.remove(fn)
432 442 self._dirty = True
433 443 except KeyError:
434 444 pass
435 445
436 446 def __contains__(self, fn):
437 447 if self.entries is None:
438 448 self._load()
439 449 return fn in self.entries
440 450
441 451 def __iter__(self):
442 452 if self.entries is None:
443 453 self._load()
444 454 return iter(self.entries)
445 455
446 456 class _fncachevfs(scmutil.abstractvfs, scmutil.auditvfs):
447 457 def __init__(self, vfs, fnc, encode):
448 458 scmutil.auditvfs.__init__(self, vfs)
449 459 self.fncache = fnc
450 460 self.encode = encode
451 461
452 462 def __call__(self, path, mode='r', *args, **kw):
453 463 if mode not in ('r', 'rb') and path.startswith('data/'):
454 464 self.fncache.add(path)
455 465 return self.vfs(self.encode(path), mode, *args, **kw)
456 466
457 467 def join(self, path):
458 468 if path:
459 469 return self.vfs.join(self.encode(path))
460 470 else:
461 471 return self.vfs.join(path)
462 472
463 473 class fncachestore(basicstore):
464 474 def __init__(self, path, vfstype, dotencode):
465 475 if dotencode:
466 476 encode = _pathencode
467 477 else:
468 478 encode = _plainhybridencode
469 479 self.encode = encode
470 480 vfs = vfstype(path + '/store')
471 481 self.path = vfs.base
472 482 self.pathsep = self.path + '/'
473 483 self.createmode = _calcmode(vfs)
474 484 vfs.createmode = self.createmode
475 485 self.rawvfs = vfs
476 486 fnc = fncache(vfs)
477 487 self.fncache = fnc
478 488 self.vfs = _fncachevfs(vfs, fnc, encode)
479 489 self.opener = self.vfs
480 490
481 491 def join(self, f):
482 492 return self.pathsep + self.encode(f)
483 493
484 494 def getsize(self, path):
485 495 return self.rawvfs.stat(path).st_size
486 496
487 497 def datafiles(self):
488 498 for f in sorted(self.fncache):
489 499 ef = self.encode(f)
490 500 try:
491 501 yield f, ef, self.getsize(ef)
492 502 except OSError as err:
493 503 if err.errno != errno.ENOENT:
494 504 raise
495 505
496 506 def copylist(self):
497 507 d = ('data dh fncache phaseroots obsstore'
498 508 ' 00manifest.d 00manifest.i 00changelog.d 00changelog.i')
499 509 return (['requires', '00changelog.i'] +
500 510 ['store/' + f for f in d.split()])
501 511
502 512 def write(self, tr):
503 513 self.fncache.write(tr)
504 514
505 515 def invalidatecaches(self):
506 516 self.fncache.entries = None
507 517
508 518 def markremoved(self, fn):
509 519 self.fncache.remove(fn)
510 520
511 521 def _exists(self, f):
512 522 ef = self.encode(f)
513 523 try:
514 524 self.getsize(ef)
515 525 return True
516 526 except OSError as err:
517 527 if err.errno != errno.ENOENT:
518 528 raise
519 529 # nonexistent entry
520 530 return False
521 531
522 532 def __contains__(self, path):
523 533 '''Checks if the store contains path'''
524 534 path = "/".join(("data", path))
525 535 # check for files (exact match)
526 536 e = path + '.i'
527 537 if e in self.fncache and self._exists(e):
528 538 return True
529 539 # now check for directories (prefix match)
530 540 if not path.endswith('/'):
531 541 path += '/'
532 542 for e in self.fncache:
533 543 if e.startswith(path) and self._exists(e):
534 544 return True
535 545 return False
536 546
537 547 def store(requirements, path, vfstype):
538 548 if 'store' in requirements:
539 549 if 'fncache' in requirements:
540 550 return fncachestore(path, vfstype, 'dotencode' in requirements)
541 551 return encodedstore(path, vfstype)
542 552 return basicstore(path, vfstype)
@@ -1,206 +1,205
1 1 #require test-repo
2 2
3 3 $ cd "$TESTDIR"/..
4 4
5 5 $ hg files 'set:(**.py)' | sed 's|\\|/|g' | xargs python contrib/check-py3-compat.py
6 6 contrib/casesmash.py not using absolute_import
7 7 contrib/check-code.py not using absolute_import
8 8 contrib/check-code.py requires print_function
9 9 contrib/check-config.py not using absolute_import
10 10 contrib/check-config.py requires print_function
11 11 contrib/debugcmdserver.py not using absolute_import
12 12 contrib/debugcmdserver.py requires print_function
13 13 contrib/debugshell.py not using absolute_import
14 14 contrib/fixpax.py not using absolute_import
15 15 contrib/fixpax.py requires print_function
16 16 contrib/hgclient.py not using absolute_import
17 17 contrib/hgclient.py requires print_function
18 18 contrib/hgfixes/fix_bytes.py not using absolute_import
19 19 contrib/hgfixes/fix_bytesmod.py not using absolute_import
20 20 contrib/hgfixes/fix_leftover_imports.py not using absolute_import
21 21 contrib/import-checker.py not using absolute_import
22 22 contrib/import-checker.py requires print_function
23 23 contrib/memory.py not using absolute_import
24 24 contrib/perf.py not using absolute_import
25 25 contrib/python-hook-examples.py not using absolute_import
26 26 contrib/revsetbenchmarks.py not using absolute_import
27 27 contrib/revsetbenchmarks.py requires print_function
28 28 contrib/showstack.py not using absolute_import
29 29 contrib/synthrepo.py not using absolute_import
30 30 contrib/win32/hgwebdir_wsgi.py not using absolute_import
31 31 doc/check-seclevel.py not using absolute_import
32 32 doc/gendoc.py not using absolute_import
33 33 doc/hgmanpage.py not using absolute_import
34 34 hgext/__init__.py not using absolute_import
35 35 hgext/acl.py not using absolute_import
36 36 hgext/blackbox.py not using absolute_import
37 37 hgext/bugzilla.py not using absolute_import
38 38 hgext/censor.py not using absolute_import
39 39 hgext/children.py not using absolute_import
40 40 hgext/churn.py not using absolute_import
41 41 hgext/clonebundles.py not using absolute_import
42 42 hgext/color.py not using absolute_import
43 43 hgext/convert/__init__.py not using absolute_import
44 44 hgext/convert/bzr.py not using absolute_import
45 45 hgext/convert/common.py not using absolute_import
46 46 hgext/convert/convcmd.py not using absolute_import
47 47 hgext/convert/cvs.py not using absolute_import
48 48 hgext/convert/cvsps.py not using absolute_import
49 49 hgext/convert/darcs.py not using absolute_import
50 50 hgext/convert/filemap.py not using absolute_import
51 51 hgext/convert/git.py not using absolute_import
52 52 hgext/convert/gnuarch.py not using absolute_import
53 53 hgext/convert/hg.py not using absolute_import
54 54 hgext/convert/monotone.py not using absolute_import
55 55 hgext/convert/p4.py not using absolute_import
56 56 hgext/convert/subversion.py not using absolute_import
57 57 hgext/convert/transport.py not using absolute_import
58 58 hgext/eol.py not using absolute_import
59 59 hgext/extdiff.py not using absolute_import
60 60 hgext/factotum.py not using absolute_import
61 61 hgext/fetch.py not using absolute_import
62 62 hgext/gpg.py not using absolute_import
63 63 hgext/graphlog.py not using absolute_import
64 64 hgext/hgcia.py not using absolute_import
65 65 hgext/hgk.py not using absolute_import
66 66 hgext/highlight/__init__.py not using absolute_import
67 67 hgext/highlight/highlight.py not using absolute_import
68 68 hgext/histedit.py not using absolute_import
69 69 hgext/keyword.py not using absolute_import
70 70 hgext/largefiles/__init__.py not using absolute_import
71 71 hgext/largefiles/basestore.py not using absolute_import
72 72 hgext/largefiles/lfcommands.py not using absolute_import
73 73 hgext/largefiles/lfutil.py not using absolute_import
74 74 hgext/largefiles/localstore.py not using absolute_import
75 75 hgext/largefiles/overrides.py not using absolute_import
76 76 hgext/largefiles/proto.py not using absolute_import
77 77 hgext/largefiles/remotestore.py not using absolute_import
78 78 hgext/largefiles/reposetup.py not using absolute_import
79 79 hgext/largefiles/uisetup.py not using absolute_import
80 80 hgext/largefiles/wirestore.py not using absolute_import
81 81 hgext/mq.py not using absolute_import
82 82 hgext/notify.py not using absolute_import
83 83 hgext/pager.py not using absolute_import
84 84 hgext/patchbomb.py not using absolute_import
85 85 hgext/purge.py not using absolute_import
86 86 hgext/rebase.py not using absolute_import
87 87 hgext/record.py not using absolute_import
88 88 hgext/relink.py not using absolute_import
89 89 hgext/schemes.py not using absolute_import
90 90 hgext/share.py not using absolute_import
91 91 hgext/shelve.py not using absolute_import
92 92 hgext/strip.py not using absolute_import
93 93 hgext/transplant.py not using absolute_import
94 94 hgext/win32mbcs.py not using absolute_import
95 95 hgext/win32text.py not using absolute_import
96 96 hgext/zeroconf/Zeroconf.py not using absolute_import
97 97 hgext/zeroconf/Zeroconf.py requires print_function
98 98 hgext/zeroconf/__init__.py not using absolute_import
99 99 i18n/check-translation.py not using absolute_import
100 100 i18n/polib.py not using absolute_import
101 101 mercurial/byterange.py not using absolute_import
102 102 mercurial/cmdutil.py not using absolute_import
103 103 mercurial/commands.py not using absolute_import
104 104 mercurial/context.py not using absolute_import
105 105 mercurial/dirstate.py not using absolute_import
106 106 mercurial/dispatch.py requires print_function
107 107 mercurial/exchange.py not using absolute_import
108 108 mercurial/httpclient/__init__.py not using absolute_import
109 109 mercurial/httpclient/_readers.py not using absolute_import
110 110 mercurial/httpclient/socketutil.py not using absolute_import
111 111 mercurial/httpconnection.py not using absolute_import
112 112 mercurial/keepalive.py not using absolute_import
113 113 mercurial/keepalive.py requires print_function
114 114 mercurial/localrepo.py not using absolute_import
115 115 mercurial/lsprof.py requires print_function
116 116 mercurial/lsprofcalltree.py not using absolute_import
117 117 mercurial/lsprofcalltree.py requires print_function
118 118 mercurial/mail.py requires print_function
119 119 mercurial/manifest.py not using absolute_import
120 120 mercurial/mdiff.py not using absolute_import
121 121 mercurial/patch.py not using absolute_import
122 122 mercurial/pvec.py not using absolute_import
123 123 mercurial/py3kcompat.py not using absolute_import
124 124 mercurial/scmposix.py not using absolute_import
125 125 mercurial/scmutil.py not using absolute_import
126 126 mercurial/scmwindows.py not using absolute_import
127 mercurial/store.py not using absolute_import
128 127 setup.py not using absolute_import
129 128 tests/filterpyflakes.py requires print_function
130 129 tests/generate-working-copy-states.py requires print_function
131 130 tests/get-with-headers.py requires print_function
132 131 tests/heredoctest.py requires print_function
133 132 tests/hypothesishelpers.py not using absolute_import
134 133 tests/hypothesishelpers.py requires print_function
135 134 tests/killdaemons.py not using absolute_import
136 135 tests/md5sum.py not using absolute_import
137 136 tests/mockblackbox.py not using absolute_import
138 137 tests/printenv.py not using absolute_import
139 138 tests/readlink.py not using absolute_import
140 139 tests/readlink.py requires print_function
141 140 tests/revlog-formatv0.py not using absolute_import
142 141 tests/run-tests.py not using absolute_import
143 142 tests/seq.py not using absolute_import
144 143 tests/seq.py requires print_function
145 144 tests/silenttestrunner.py not using absolute_import
146 145 tests/silenttestrunner.py requires print_function
147 146 tests/sitecustomize.py not using absolute_import
148 147 tests/svn-safe-append.py not using absolute_import
149 148 tests/svnxml.py not using absolute_import
150 149 tests/test-ancestor.py requires print_function
151 150 tests/test-atomictempfile.py not using absolute_import
152 151 tests/test-batching.py not using absolute_import
153 152 tests/test-batching.py requires print_function
154 153 tests/test-bdiff.py not using absolute_import
155 154 tests/test-bdiff.py requires print_function
156 155 tests/test-context.py not using absolute_import
157 156 tests/test-context.py requires print_function
158 157 tests/test-demandimport.py not using absolute_import
159 158 tests/test-demandimport.py requires print_function
160 159 tests/test-dispatch.py not using absolute_import
161 160 tests/test-dispatch.py requires print_function
162 161 tests/test-doctest.py not using absolute_import
163 162 tests/test-duplicateoptions.py not using absolute_import
164 163 tests/test-duplicateoptions.py requires print_function
165 164 tests/test-filecache.py not using absolute_import
166 165 tests/test-filecache.py requires print_function
167 166 tests/test-filelog.py not using absolute_import
168 167 tests/test-filelog.py requires print_function
169 168 tests/test-hg-parseurl.py not using absolute_import
170 169 tests/test-hg-parseurl.py requires print_function
171 170 tests/test-hgweb-auth.py not using absolute_import
172 171 tests/test-hgweb-auth.py requires print_function
173 172 tests/test-hgwebdir-paths.py not using absolute_import
174 173 tests/test-hybridencode.py not using absolute_import
175 174 tests/test-hybridencode.py requires print_function
176 175 tests/test-lrucachedict.py not using absolute_import
177 176 tests/test-lrucachedict.py requires print_function
178 177 tests/test-manifest.py not using absolute_import
179 178 tests/test-minirst.py not using absolute_import
180 179 tests/test-minirst.py requires print_function
181 180 tests/test-parseindex2.py not using absolute_import
182 181 tests/test-parseindex2.py requires print_function
183 182 tests/test-pathencode.py not using absolute_import
184 183 tests/test-pathencode.py requires print_function
185 184 tests/test-propertycache.py not using absolute_import
186 185 tests/test-propertycache.py requires print_function
187 186 tests/test-revlog-ancestry.py not using absolute_import
188 187 tests/test-revlog-ancestry.py requires print_function
189 188 tests/test-run-tests.py not using absolute_import
190 189 tests/test-simplemerge.py not using absolute_import
191 190 tests/test-status-inprocess.py not using absolute_import
192 191 tests/test-status-inprocess.py requires print_function
193 192 tests/test-symlink-os-yes-fs-no.py not using absolute_import
194 193 tests/test-trusted.py not using absolute_import
195 194 tests/test-trusted.py requires print_function
196 195 tests/test-ui-color.py not using absolute_import
197 196 tests/test-ui-color.py requires print_function
198 197 tests/test-ui-config.py not using absolute_import
199 198 tests/test-ui-config.py requires print_function
200 199 tests/test-ui-verbosity.py not using absolute_import
201 200 tests/test-ui-verbosity.py requires print_function
202 201 tests/test-url.py not using absolute_import
203 202 tests/test-url.py requires print_function
204 203 tests/test-walkrepo.py requires print_function
205 204 tests/test-wireproto.py requires print_function
206 205 tests/tinyproxy.py requires print_function
General Comments 0
You need to be logged in to leave comments. Login now