13 import os, revlog, time, util |
13 import os, revlog, time, util |
14 |
14 |
15 class localrepository(repo.repository): |
15 class localrepository(repo.repository): |
16 capabilities = ('lookup', 'changegroupsubset') |
16 capabilities = ('lookup', 'changegroupsubset') |
17 supported = ('revlogv1', 'store') |
17 supported = ('revlogv1', 'store') |
|
18 branchcache_features = ('unnamed',) |
18 |
19 |
19 def __del__(self): |
20 def __del__(self): |
20 self.transhandle = None |
21 self.transhandle = None |
21 def __init__(self, parentui, path=None, create=0): |
22 def __init__(self, parentui, path=None, create=0): |
22 repo.repository.__init__(self) |
23 repo.repository.__init__(self) |
395 partial = {} |
396 partial = {} |
396 try: |
397 try: |
397 f = self.opener("branches.cache") |
398 f = self.opener("branches.cache") |
398 lines = f.read().split('\n') |
399 lines = f.read().split('\n') |
399 f.close() |
400 f.close() |
400 last, lrev = lines.pop(0).rstrip().split(" ", 1) |
401 features = lines.pop(0).strip() |
|
402 if not features.startswith('features: '): |
|
403 raise ValueError(_('branch cache: no features specified')) |
|
404 features = features.split(' ', 1)[1].split() |
|
405 missing_features = [] |
|
406 for feature in self.branchcache_features: |
|
407 try: |
|
408 features.remove(feature) |
|
409 except ValueError, inst: |
|
410 missing_features.append(feature) |
|
411 if missing_features: |
|
412 raise ValueError(_('branch cache: missing features: %s') |
|
413 % ', '.join(missing_features)) |
|
414 if features: |
|
415 raise ValueError(_('branch cache: unknown features: %s') |
|
416 % ', '.join(features)) |
|
417 last, lrev = lines.pop(0).split(" ", 1) |
401 last, lrev = bin(last), int(lrev) |
418 last, lrev = bin(last), int(lrev) |
402 if not (lrev < self.changelog.count() and |
419 if not (lrev < self.changelog.count() and |
403 self.changelog.node(lrev) == last): # sanity check |
420 self.changelog.node(lrev) == last): # sanity check |
404 # invalidate the cache |
421 # invalidate the cache |
405 raise ValueError('Invalid branch cache: unknown tip') |
422 raise ValueError('Invalid branch cache: unknown tip') |
406 for l in lines: |
423 for l in lines: |
407 if not l: continue |
424 if not l: continue |
408 node, label = l.rstrip().split(" ", 1) |
425 node, label = l.split(" ", 1) |
409 partial[label] = bin(node) |
426 partial[label.strip()] = bin(node) |
410 except (KeyboardInterrupt, util.SignalInterrupt): |
427 except (KeyboardInterrupt, util.SignalInterrupt): |
411 raise |
428 raise |
412 except Exception, inst: |
429 except Exception, inst: |
413 if self.ui.debugflag: |
430 if self.ui.debugflag: |
414 self.ui.warn(str(inst), '\n') |
431 self.ui.warn(str(inst), '\n') |
416 return partial, last, lrev |
433 return partial, last, lrev |
417 |
434 |
418 def _writebranchcache(self, branches, tip, tiprev): |
435 def _writebranchcache(self, branches, tip, tiprev): |
419 try: |
436 try: |
420 f = self.opener("branches.cache", "w") |
437 f = self.opener("branches.cache", "w") |
|
438 f.write(" features: %s\n" % ' '.join(self.branchcache_features)) |
421 f.write("%s %s\n" % (hex(tip), tiprev)) |
439 f.write("%s %s\n" % (hex(tip), tiprev)) |
422 for label, node in branches.iteritems(): |
440 for label, node in branches.iteritems(): |
423 f.write("%s %s\n" % (hex(node), label)) |
441 f.write("%s %s\n" % (hex(node), label)) |
424 except IOError: |
442 except IOError: |
425 pass |
443 pass |
426 |
444 |
427 def _updatebranchcache(self, partial, start, end): |
445 def _updatebranchcache(self, partial, start, end): |
428 for r in xrange(start, end): |
446 for r in xrange(start, end): |
429 c = self.changectx(r) |
447 c = self.changectx(r) |
430 b = c.branch() |
448 b = c.branch() |
431 if b: |
449 partial[b] = c.node() |
432 partial[b] = c.node() |
|
433 |
450 |
434 def lookup(self, key): |
451 def lookup(self, key): |
435 if key == '.': |
452 if key == '.': |
436 key = self.dirstate.parents()[0] |
453 key = self.dirstate.parents()[0] |
437 if key == nullid: |
454 if key == nullid: |