428 except IOError: |
428 except IOError: |
429 pass |
429 pass |
430 else: |
430 else: |
431 extensions.loadall(ui) |
431 extensions.loadall(ui) |
432 |
432 |
|
433 supportedrequirements = gathersupportedrequirements(ui) |
|
434 ensurerequirementsrecognized(requirements, supportedrequirements) |
|
435 |
|
436 # At this point, we know we should be capable of opening the repository. |
|
437 # Now get on with doing that. |
|
438 |
433 return localrepository( |
439 return localrepository( |
434 baseui=baseui, |
440 baseui=baseui, |
435 ui=ui, |
441 ui=ui, |
436 origroot=path, |
442 origroot=path, |
437 wdirvfs=wdirvfs, |
443 wdirvfs=wdirvfs, |
438 hgvfs=hgvfs, |
444 hgvfs=hgvfs, |
439 requirements=requirements, |
445 requirements=requirements, |
|
446 supportedrequirements=supportedrequirements, |
440 intents=intents) |
447 intents=intents) |
|
448 |
|
449 def gathersupportedrequirements(ui): |
|
450 """Determine the complete set of recognized requirements.""" |
|
451 # Start with all requirements supported by this file. |
|
452 supported = set(localrepository._basesupported) |
|
453 |
|
454 # Execute ``featuresetupfuncs`` entries if they belong to an extension |
|
455 # relevant to this ui instance. |
|
456 modules = {m.__name__ for n, m in extensions.extensions(ui)} |
|
457 |
|
458 for fn in featuresetupfuncs: |
|
459 if fn.__module__ in modules: |
|
460 fn(ui, supported) |
|
461 |
|
462 # Add derived requirements from registered compression engines. |
|
463 for name in util.compengines: |
|
464 engine = util.compengines[name] |
|
465 if engine.revlogheader(): |
|
466 supported.add(b'exp-compression-%s' % name) |
|
467 |
|
468 return supported |
|
469 |
|
470 def ensurerequirementsrecognized(requirements, supported): |
|
471 """Validate that a set of local requirements is recognized. |
|
472 |
|
473 Receives a set of requirements. Raises an ``error.RepoError`` if there |
|
474 exists any requirement in that set that currently loaded code doesn't |
|
475 recognize. |
|
476 |
|
477 Returns a set of supported requirements. |
|
478 """ |
|
479 missing = set() |
|
480 |
|
481 for requirement in requirements: |
|
482 if requirement in supported: |
|
483 continue |
|
484 |
|
485 if not requirement or not requirement[0:1].isalnum(): |
|
486 raise error.RequirementError(_(b'.hg/requires file is corrupt')) |
|
487 |
|
488 missing.add(requirement) |
|
489 |
|
490 if missing: |
|
491 raise error.RequirementError( |
|
492 _(b'repository requires features unknown to this Mercurial: %s') % |
|
493 b' '.join(sorted(missing)), |
|
494 hint=_(b'see https://mercurial-scm.org/wiki/MissingRequirement ' |
|
495 b'for more information')) |
441 |
496 |
442 @interfaceutil.implementer(repository.completelocalrepository) |
497 @interfaceutil.implementer(repository.completelocalrepository) |
443 class localrepository(object): |
498 class localrepository(object): |
444 |
499 |
445 # obsolete experimental requirements: |
500 # obsolete experimental requirements: |
488 # the remainig bit and drop this line |
543 # the remainig bit and drop this line |
489 'bisect.state', |
544 'bisect.state', |
490 } |
545 } |
491 |
546 |
492 def __init__(self, baseui, ui, origroot, wdirvfs, hgvfs, requirements, |
547 def __init__(self, baseui, ui, origroot, wdirvfs, hgvfs, requirements, |
493 intents=None): |
548 supportedrequirements, intents=None): |
494 """Create a new local repository instance. |
549 """Create a new local repository instance. |
495 |
550 |
496 Most callers should use ``hg.repository()``, ``localrepo.instance()``, |
551 Most callers should use ``hg.repository()``, ``localrepo.instance()``, |
497 or ``localrepo.makelocalrepository()`` for obtaining a new repository |
552 or ``localrepo.makelocalrepository()`` for obtaining a new repository |
498 object. |
553 object. |
528 self.wvfs = wdirvfs |
587 self.wvfs = wdirvfs |
529 self.root = wdirvfs.base |
588 self.root = wdirvfs.base |
530 # vfs rooted at .hg/. Used to access most non-store paths. |
589 # vfs rooted at .hg/. Used to access most non-store paths. |
531 self.vfs = hgvfs |
590 self.vfs = hgvfs |
532 self.path = hgvfs.base |
591 self.path = hgvfs.base |
|
592 self.requirements = requirements |
|
593 self.supported = supportedrequirements |
533 |
594 |
534 self.filtername = None |
595 self.filtername = None |
535 # svfs: usually rooted at .hg/store, used to access repository history |
596 # svfs: usually rooted at .hg/store, used to access repository history |
536 # If this is a shared repository, this vfs may point to another |
597 # If this is a shared repository, this vfs may point to another |
537 # repository's .hg/store directory. |
598 # repository's .hg/store directory. |
543 # A list of callback to shape the phase if no data were found. |
604 # A list of callback to shape the phase if no data were found. |
544 # Callback are in the form: func(repo, roots) --> processed root. |
605 # Callback are in the form: func(repo, roots) --> processed root. |
545 # This list it to be filled by extension during repo setup |
606 # This list it to be filled by extension during repo setup |
546 self._phasedefaults = [] |
607 self._phasedefaults = [] |
547 |
608 |
548 if featuresetupfuncs: |
|
549 self.supported = set(self._basesupported) # use private copy |
|
550 extmods = set(m.__name__ for n, m |
|
551 in extensions.extensions(self.ui)) |
|
552 for setupfunc in featuresetupfuncs: |
|
553 if setupfunc.__module__ in extmods: |
|
554 setupfunc(self.ui, self.supported) |
|
555 else: |
|
556 self.supported = self._basesupported |
|
557 color.setup(self.ui) |
609 color.setup(self.ui) |
558 |
|
559 # Add compression engines. |
|
560 for name in util.compengines: |
|
561 engine = util.compengines[name] |
|
562 if engine.revlogheader(): |
|
563 self.supported.add('exp-compression-%s' % name) |
|
564 |
|
565 # Validate that all seen repository requirements are supported. |
|
566 missingrequirements = [] |
|
567 for r in requirements: |
|
568 if r not in self.supported: |
|
569 if not r or not r[0:1].isalnum(): |
|
570 raise error.RequirementError( |
|
571 _(".hg/requires file is corrupt")) |
|
572 missingrequirements.append(r) |
|
573 missingrequirements.sort() |
|
574 if missingrequirements: |
|
575 raise error.RequirementError( |
|
576 _("repository requires features unknown to this Mercurial: %s") |
|
577 % " ".join(missingrequirements), |
|
578 hint=_("see https://mercurial-scm.org/wiki/MissingRequirement" |
|
579 " for more information")) |
|
580 |
|
581 self.requirements = requirements |
|
582 |
610 |
583 cachepath = self.vfs.join('cache') |
611 cachepath = self.vfs.join('cache') |
584 self.sharedpath = self.path |
612 self.sharedpath = self.path |
585 try: |
613 try: |
586 sharedpath = self.vfs.read("sharedpath").rstrip('\n') |
614 sharedpath = self.vfs.read("sharedpath").rstrip('\n') |