comparison mercurial/localrepo.py @ 3498:ff06fe0703ef

localrepo: add separate methods for manipulating repository data This change adds new methods sjoin and sopener for accessing the following elements: - changelog - manifest - data/ - journal and undo log - repo lock This will simplify sharing this data and escaping paths
author Matt Mackall <mpm@selenic.com>
date Mon, 23 Oct 2006 17:12:20 -0500
parents 3464f5e77f34
children ceaa3fefc10c
comparison
equal deleted inserted replaced
3497:3464f5e77f34 3498:ff06fe0703ef
45 45
46 self.root = os.path.abspath(path) 46 self.root = os.path.abspath(path)
47 self.origroot = path 47 self.origroot = path
48 self.ui = ui.ui(parentui=parentui) 48 self.ui = ui.ui(parentui=parentui)
49 self.opener = util.opener(self.path) 49 self.opener = util.opener(self.path)
50 self.sopener = util.opener(self.path)
50 self.wopener = util.opener(self.root) 51 self.wopener = util.opener(self.root)
51 52
52 try: 53 try:
53 self.ui.readconfig(self.join("hgrc"), self.root) 54 self.ui.readconfig(self.join("hgrc"), self.root)
54 except IOError: 55 except IOError:
64 flags |= revlog.flagstr(x) 65 flags |= revlog.flagstr(x)
65 elif self.revlogv1: 66 elif self.revlogv1:
66 flags = revlog.REVLOG_DEFAULT_FLAGS 67 flags = revlog.REVLOG_DEFAULT_FLAGS
67 68
68 v = self.revlogversion | flags 69 v = self.revlogversion | flags
69 self.manifest = manifest.manifest(self.opener, v) 70 self.manifest = manifest.manifest(self.sopener, v)
70 self.changelog = changelog.changelog(self.opener, v) 71 self.changelog = changelog.changelog(self.sopener, v)
71 72
72 # the changelog might not have the inline index flag 73 # the changelog might not have the inline index flag
73 # on. If the format of the changelog is the same as found in 74 # on. If the format of the changelog is the same as found in
74 # .hgrc, apply any flags found in the .hgrc as well. 75 # .hgrc, apply any flags found in the .hgrc as well.
75 # Otherwise, just version from the changelog 76 # Otherwise, just version from the changelog
354 return True 355 return True
355 356
356 def join(self, f): 357 def join(self, f):
357 return os.path.join(self.path, f) 358 return os.path.join(self.path, f)
358 359
360 def sjoin(self, f):
361 return os.path.join(self.path, f)
362
359 def wjoin(self, f): 363 def wjoin(self, f):
360 return os.path.join(self.root, f) 364 return os.path.join(self.root, f)
361 365
362 def file(self, f): 366 def file(self, f):
363 if f[0] == '/': 367 if f[0] == '/':
364 f = f[1:] 368 f = f[1:]
365 return filelog.filelog(self.opener, f, self.revlogversion) 369 return filelog.filelog(self.sopener, f, self.revlogversion)
366 370
367 def changectx(self, changeid=None): 371 def changectx(self, changeid=None):
368 return context.changectx(self, changeid) 372 return context.changectx(self, changeid)
369 373
370 def workingctx(self): 374 def workingctx(self):
440 ds = self.opener("dirstate").read() 444 ds = self.opener("dirstate").read()
441 except IOError: 445 except IOError:
442 ds = "" 446 ds = ""
443 self.opener("journal.dirstate", "w").write(ds) 447 self.opener("journal.dirstate", "w").write(ds)
444 448
445 tr = transaction.transaction(self.ui.warn, self.opener, 449 tr = transaction.transaction(self.ui.warn, self.sopener,
446 self.join("journal"), 450 self.sjoin("journal"),
447 aftertrans(self.path)) 451 aftertrans(self.path))
448 self.transhandle = tr 452 self.transhandle = tr
449 return tr 453 return tr
450 454
451 def recover(self): 455 def recover(self):
452 l = self.lock() 456 l = self.lock()
453 if os.path.exists(self.join("journal")): 457 if os.path.exists(self.sjoin("journal")):
454 self.ui.status(_("rolling back interrupted transaction\n")) 458 self.ui.status(_("rolling back interrupted transaction\n"))
455 transaction.rollback(self.opener, self.join("journal")) 459 transaction.rollback(self.sopener, self.sjoin("journal"))
456 self.reload() 460 self.reload()
457 return True 461 return True
458 else: 462 else:
459 self.ui.warn(_("no interrupted transaction available\n")) 463 self.ui.warn(_("no interrupted transaction available\n"))
460 return False 464 return False
461 465
462 def rollback(self, wlock=None): 466 def rollback(self, wlock=None):
463 if not wlock: 467 if not wlock:
464 wlock = self.wlock() 468 wlock = self.wlock()
465 l = self.lock() 469 l = self.lock()
466 if os.path.exists(self.join("undo")): 470 if os.path.exists(self.sjoin("undo")):
467 self.ui.status(_("rolling back last transaction\n")) 471 self.ui.status(_("rolling back last transaction\n"))
468 transaction.rollback(self.opener, self.join("undo")) 472 transaction.rollback(self.sopener, self.sjoin("undo"))
469 util.rename(self.join("undo.dirstate"), self.join("dirstate")) 473 util.rename(self.join("undo.dirstate"), self.join("dirstate"))
470 self.reload() 474 self.reload()
471 self.wreload() 475 self.wreload()
472 else: 476 else:
473 self.ui.warn(_("no rollback information available\n")) 477 self.ui.warn(_("no rollback information available\n"))
482 self.nodetagscache = None 486 self.nodetagscache = None
483 487
484 def do_lock(self, lockname, wait, releasefn=None, acquirefn=None, 488 def do_lock(self, lockname, wait, releasefn=None, acquirefn=None,
485 desc=None): 489 desc=None):
486 try: 490 try:
487 l = lock.lock(self.join(lockname), 0, releasefn, desc=desc) 491 l = lock.lock(lockname, 0, releasefn, desc=desc)
488 except lock.LockHeld, inst: 492 except lock.LockHeld, inst:
489 if not wait: 493 if not wait:
490 raise 494 raise
491 self.ui.warn(_("waiting for lock on %s held by %s\n") % 495 self.ui.warn(_("waiting for lock on %s held by %s\n") %
492 (desc, inst.args[0])) 496 (desc, inst.args[0]))
493 # default to 600 seconds timeout 497 # default to 600 seconds timeout
494 l = lock.lock(self.join(lockname), 498 l = lock.lock(lockname, int(self.ui.config("ui", "timeout", "600")),
495 int(self.ui.config("ui", "timeout") or 600),
496 releasefn, desc=desc) 499 releasefn, desc=desc)
497 if acquirefn: 500 if acquirefn:
498 acquirefn() 501 acquirefn()
499 return l 502 return l
500 503
501 def lock(self, wait=1): 504 def lock(self, wait=1):
502 return self.do_lock("lock", wait, acquirefn=self.reload, 505 return self.do_lock(self.sjoin("lock"), wait, acquirefn=self.reload,
503 desc=_('repository %s') % self.origroot) 506 desc=_('repository %s') % self.origroot)
504 507
505 def wlock(self, wait=1): 508 def wlock(self, wait=1):
506 return self.do_lock("wlock", wait, self.dirstate.write, 509 return self.do_lock(self.join("wlock"), wait, self.dirstate.write,
507 self.wreload, 510 self.wreload,
508 desc=_('working directory of %s') % self.origroot) 511 desc=_('working directory of %s') % self.origroot)
509 512
510 def filecommit(self, fn, manifest1, manifest2, linkrev, transaction, changelist): 513 def filecommit(self, fn, manifest1, manifest2, linkrev, transaction, changelist):
511 """ 514 """
1684 1687
1685 # write changelog data to temp files so concurrent readers will not see 1688 # write changelog data to temp files so concurrent readers will not see
1686 # inconsistent view 1689 # inconsistent view
1687 cl = None 1690 cl = None
1688 try: 1691 try:
1689 cl = appendfile.appendchangelog(self.opener, self.changelog.version) 1692 cl = appendfile.appendchangelog(self.sopener,
1693 self.changelog.version)
1690 1694
1691 oldheads = len(cl.heads()) 1695 oldheads = len(cl.heads())
1692 1696
1693 # pull off the changeset group 1697 # pull off the changeset group
1694 self.ui.status(_("adding changesets\n")) 1698 self.ui.status(_("adding changesets\n"))
1727 finally: 1731 finally:
1728 if cl: 1732 if cl:
1729 cl.cleanup() 1733 cl.cleanup()
1730 1734
1731 # make changelog see real files again 1735 # make changelog see real files again
1732 self.changelog = changelog.changelog(self.opener, self.changelog.version) 1736 self.changelog = changelog.changelog(self.sopener,
1737 self.changelog.version)
1733 self.changelog.checkinlinesize(tr) 1738 self.changelog.checkinlinesize(tr)
1734 1739
1735 newheads = len(self.changelog.heads()) 1740 newheads = len(self.changelog.heads())
1736 heads = "" 1741 heads = ""
1737 if oldheads and newheads != oldheads: 1742 if oldheads and newheads != oldheads:
1771 start = time.time() 1776 start = time.time()
1772 for i in xrange(total_files): 1777 for i in xrange(total_files):
1773 name, size = fp.readline().split('\0', 1) 1778 name, size = fp.readline().split('\0', 1)
1774 size = int(size) 1779 size = int(size)
1775 self.ui.debug('adding %s (%s)\n' % (name, util.bytecount(size))) 1780 self.ui.debug('adding %s (%s)\n' % (name, util.bytecount(size)))
1776 ofp = self.opener(name, 'w') 1781 ofp = self.sopener(name, 'w')
1777 for chunk in util.filechunkiter(fp, limit=size): 1782 for chunk in util.filechunkiter(fp, limit=size):
1778 ofp.write(chunk) 1783 ofp.write(chunk)
1779 ofp.close() 1784 ofp.close()
1780 elapsed = time.time() - start 1785 elapsed = time.time() - start
1781 self.ui.status(_('transferred %s in %.1f seconds (%s/sec)\n') % 1786 self.ui.status(_('transferred %s in %.1f seconds (%s/sec)\n') %