Mercurial > public > mercurial-scm > hg
comparison mercurial/localrepo.py @ 3457: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
3456:3464f5e77f34 | 3457: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') % |