429 pass |
429 pass |
430 else: |
430 else: |
431 extensions.loadall(ui) |
431 extensions.loadall(ui) |
432 |
432 |
433 supportedrequirements = gathersupportedrequirements(ui) |
433 supportedrequirements = gathersupportedrequirements(ui) |
|
434 |
|
435 # We first validate the requirements are known. |
434 ensurerequirementsrecognized(requirements, supportedrequirements) |
436 ensurerequirementsrecognized(requirements, supportedrequirements) |
|
437 |
|
438 # Then we validate that the known set is reasonable to use together. |
|
439 ensurerequirementscompatible(ui, requirements) |
435 |
440 |
436 # At this point, we know we should be capable of opening the repository. |
441 # At this point, we know we should be capable of opening the repository. |
437 # Now get on with doing that. |
442 # Now get on with doing that. |
438 |
443 |
439 return localrepository( |
444 return localrepository( |
491 raise error.RequirementError( |
496 raise error.RequirementError( |
492 _(b'repository requires features unknown to this Mercurial: %s') % |
497 _(b'repository requires features unknown to this Mercurial: %s') % |
493 b' '.join(sorted(missing)), |
498 b' '.join(sorted(missing)), |
494 hint=_(b'see https://mercurial-scm.org/wiki/MissingRequirement ' |
499 hint=_(b'see https://mercurial-scm.org/wiki/MissingRequirement ' |
495 b'for more information')) |
500 b'for more information')) |
|
501 |
|
502 def ensurerequirementscompatible(ui, requirements): |
|
503 """Validates that a set of recognized requirements is mutually compatible. |
|
504 |
|
505 Some requirements may not be compatible with others or require |
|
506 config options that aren't enabled. This function is called during |
|
507 repository opening to ensure that the set of requirements needed |
|
508 to open a repository is sane and compatible with config options. |
|
509 |
|
510 Extensions can monkeypatch this function to perform additional |
|
511 checking. |
|
512 |
|
513 ``error.RepoError`` should be raised on failure. |
|
514 """ |
|
515 if b'exp-sparse' in requirements and not sparse.enabled: |
|
516 raise error.RepoError(_(b'repository is using sparse feature but ' |
|
517 b'sparse is not enabled; enable the ' |
|
518 b'"sparse" extensions to access')) |
496 |
519 |
497 @interfaceutil.implementer(repository.completelocalrepository) |
520 @interfaceutil.implementer(repository.completelocalrepository) |
498 class localrepository(object): |
521 class localrepository(object): |
499 |
522 |
500 # obsolete experimental requirements: |
523 # obsolete experimental requirements: |
622 _('.hg/sharedpath points to nonexistent directory %s') % s) |
645 _('.hg/sharedpath points to nonexistent directory %s') % s) |
623 self.sharedpath = s |
646 self.sharedpath = s |
624 except IOError as inst: |
647 except IOError as inst: |
625 if inst.errno != errno.ENOENT: |
648 if inst.errno != errno.ENOENT: |
626 raise |
649 raise |
627 |
|
628 if 'exp-sparse' in self.requirements and not sparse.enabled: |
|
629 raise error.RepoError(_('repository is using sparse feature but ' |
|
630 'sparse is not enabled; enable the ' |
|
631 '"sparse" extensions to access')) |
|
632 |
650 |
633 self.store = store.store( |
651 self.store = store.store( |
634 self.requirements, self.sharedpath, |
652 self.requirements, self.sharedpath, |
635 lambda base: vfsmod.vfs(base, cacheaudited=True)) |
653 lambda base: vfsmod.vfs(base, cacheaudited=True)) |
636 self.spath = self.store.path |
654 self.spath = self.store.path |