452 # that shared store since it has an unknown-to-us requirement. |
452 # that shared store since it has an unknown-to-us requirement. |
453 |
453 |
454 # At this point, we know we should be capable of opening the repository. |
454 # At this point, we know we should be capable of opening the repository. |
455 # Now get on with doing that. |
455 # Now get on with doing that. |
456 |
456 |
|
457 # The "store" part of the repository holds versioned data. How it is |
|
458 # accessed is determined by various requirements. The ``shared`` or |
|
459 # ``relshared`` requirements indicate the store lives in the path contained |
|
460 # in the ``.hg/sharedpath`` file. This is an absolute path for |
|
461 # ``shared`` and relative to ``.hg/`` for ``relshared``. |
|
462 if b'shared' in requirements or b'relshared' in requirements: |
|
463 sharedpath = hgvfs.read(b'sharedpath').rstrip(b'\n') |
|
464 if b'relshared' in requirements: |
|
465 sharedpath = hgvfs.join(sharedpath) |
|
466 |
|
467 sharedvfs = vfsmod.vfs(sharedpath, realpath=True) |
|
468 |
|
469 if not sharedvfs.exists(): |
|
470 raise error.RepoError(_(b'.hg/sharedpath points to nonexistent ' |
|
471 b'directory %s') % sharedvfs.base) |
|
472 |
|
473 storebasepath = sharedvfs.base |
|
474 cachepath = sharedvfs.join(b'cache') |
|
475 else: |
|
476 storebasepath = hgvfs.base |
|
477 cachepath = hgvfs.join(b'cache') |
|
478 |
|
479 # The store has changed over time and the exact layout is dictated by |
|
480 # requirements. The store interface abstracts differences across all |
|
481 # of them. |
|
482 store = storemod.store(requirements, storebasepath, |
|
483 lambda base: vfsmod.vfs(base, cacheaudited=True)) |
|
484 |
|
485 hgvfs.createmode = store.createmode |
|
486 |
|
487 # The cache vfs is used to manage cache files. |
|
488 cachevfs = vfsmod.vfs(cachepath, cacheaudited=True) |
|
489 cachevfs.createmode = store.createmode |
|
490 |
457 return localrepository( |
491 return localrepository( |
458 baseui=baseui, |
492 baseui=baseui, |
459 ui=ui, |
493 ui=ui, |
460 origroot=path, |
494 origroot=path, |
461 wdirvfs=wdirvfs, |
495 wdirvfs=wdirvfs, |
462 hgvfs=hgvfs, |
496 hgvfs=hgvfs, |
463 requirements=requirements, |
497 requirements=requirements, |
464 supportedrequirements=supportedrequirements, |
498 supportedrequirements=supportedrequirements, |
|
499 sharedpath=storebasepath, |
|
500 store=store, |
|
501 cachevfs=cachevfs, |
465 intents=intents) |
502 intents=intents) |
466 |
503 |
467 def gathersupportedrequirements(ui): |
504 def gathersupportedrequirements(ui): |
468 """Determine the complete set of recognized requirements.""" |
505 """Determine the complete set of recognized requirements.""" |
469 # Start with all requirements supported by this file. |
506 # Start with all requirements supported by this file. |
579 # the remainig bit and drop this line |
616 # the remainig bit and drop this line |
580 'bisect.state', |
617 'bisect.state', |
581 } |
618 } |
582 |
619 |
583 def __init__(self, baseui, ui, origroot, wdirvfs, hgvfs, requirements, |
620 def __init__(self, baseui, ui, origroot, wdirvfs, hgvfs, requirements, |
584 supportedrequirements, intents=None): |
621 supportedrequirements, sharedpath, store, cachevfs, |
|
622 intents=None): |
585 """Create a new local repository instance. |
623 """Create a new local repository instance. |
586 |
624 |
587 Most callers should use ``hg.repository()``, ``localrepo.instance()``, |
625 Most callers should use ``hg.repository()``, ``localrepo.instance()``, |
588 or ``localrepo.makelocalrepository()`` for obtaining a new repository |
626 or ``localrepo.makelocalrepository()`` for obtaining a new repository |
589 object. |
627 object. |
609 ``set`` of bytestrings representing repository opening requirements. |
647 ``set`` of bytestrings representing repository opening requirements. |
610 |
648 |
611 supportedrequirements |
649 supportedrequirements |
612 ``set`` of bytestrings representing repository requirements that we |
650 ``set`` of bytestrings representing repository requirements that we |
613 know how to open. May be a supetset of ``requirements``. |
651 know how to open. May be a supetset of ``requirements``. |
|
652 |
|
653 sharedpath |
|
654 ``bytes`` Defining path to storage base directory. Points to a |
|
655 ``.hg/`` directory somewhere. |
|
656 |
|
657 store |
|
658 ``store.basicstore`` (or derived) instance providing access to |
|
659 versioned storage. |
|
660 |
|
661 cachevfs |
|
662 ``vfs.vfs`` used for cache files. |
614 |
663 |
615 intents |
664 intents |
616 ``set`` of system strings indicating what this repo will be used |
665 ``set`` of system strings indicating what this repo will be used |
617 for. |
666 for. |
618 """ |
667 """ |
625 # vfs rooted at .hg/. Used to access most non-store paths. |
674 # vfs rooted at .hg/. Used to access most non-store paths. |
626 self.vfs = hgvfs |
675 self.vfs = hgvfs |
627 self.path = hgvfs.base |
676 self.path = hgvfs.base |
628 self.requirements = requirements |
677 self.requirements = requirements |
629 self.supported = supportedrequirements |
678 self.supported = supportedrequirements |
|
679 self.sharedpath = sharedpath |
|
680 self.store = store |
|
681 self.cachevfs = cachevfs |
630 |
682 |
631 self.filtername = None |
683 self.filtername = None |
632 # svfs: usually rooted at .hg/store, used to access repository history |
|
633 # If this is a shared repository, this vfs may point to another |
|
634 # repository's .hg/store directory. |
|
635 self.svfs = None |
|
636 |
684 |
637 if (self.ui.configbool('devel', 'all-warnings') or |
685 if (self.ui.configbool('devel', 'all-warnings') or |
638 self.ui.configbool('devel', 'check-locks')): |
686 self.ui.configbool('devel', 'check-locks')): |
639 self.vfs.audit = self._getvfsward(self.vfs.audit) |
687 self.vfs.audit = self._getvfsward(self.vfs.audit) |
640 # A list of callback to shape the phase if no data were found. |
688 # A list of callback to shape the phase if no data were found. |
642 # This list it to be filled by extension during repo setup |
690 # This list it to be filled by extension during repo setup |
643 self._phasedefaults = [] |
691 self._phasedefaults = [] |
644 |
692 |
645 color.setup(self.ui) |
693 color.setup(self.ui) |
646 |
694 |
647 cachepath = self.vfs.join('cache') |
|
648 self.sharedpath = self.path |
|
649 try: |
|
650 sharedpath = self.vfs.read("sharedpath").rstrip('\n') |
|
651 if 'relshared' in self.requirements: |
|
652 sharedpath = self.vfs.join(sharedpath) |
|
653 vfs = vfsmod.vfs(sharedpath, realpath=True) |
|
654 cachepath = vfs.join('cache') |
|
655 s = vfs.base |
|
656 if not vfs.exists(): |
|
657 raise error.RepoError( |
|
658 _('.hg/sharedpath points to nonexistent directory %s') % s) |
|
659 self.sharedpath = s |
|
660 except IOError as inst: |
|
661 if inst.errno != errno.ENOENT: |
|
662 raise |
|
663 |
|
664 self.store = store.store( |
|
665 self.requirements, self.sharedpath, |
|
666 lambda base: vfsmod.vfs(base, cacheaudited=True)) |
|
667 self.spath = self.store.path |
695 self.spath = self.store.path |
668 self.svfs = self.store.vfs |
696 self.svfs = self.store.vfs |
669 self.sjoin = self.store.join |
697 self.sjoin = self.store.join |
670 self.vfs.createmode = self.store.createmode |
|
671 self.cachevfs = vfsmod.vfs(cachepath, cacheaudited=True) |
|
672 self.cachevfs.createmode = self.store.createmode |
|
673 if (self.ui.configbool('devel', 'all-warnings') or |
698 if (self.ui.configbool('devel', 'all-warnings') or |
674 self.ui.configbool('devel', 'check-locks')): |
699 self.ui.configbool('devel', 'check-locks')): |
675 if util.safehasattr(self.svfs, 'vfs'): # this is filtervfs |
700 if util.safehasattr(self.svfs, 'vfs'): # this is filtervfs |
676 self.svfs.vfs.audit = self._getsvfsward(self.svfs.vfs.audit) |
701 self.svfs.vfs.audit = self._getsvfsward(self.svfs.vfs.audit) |
677 else: # standard vfs |
702 else: # standard vfs |