[Updated] [+----- ] D9477: upgrade: split definition and management of the actions from the main code
baymax (Baymax, Your Personal Patch-care Companion)
phabricator at mercurial-scm.org
Fri Dec 4 23:48:15 UTC 2020
baymax updated this revision to Diff 24032.
REPOSITORY
rHG Mercurial
CHANGES SINCE LAST UPDATE
https://phab.mercurial-scm.org/D9477?vs=23904&id=24032
BRANCH
default
CHANGES SINCE LAST ACTION
https://phab.mercurial-scm.org/D9477/new/
REVISION DETAIL
https://phab.mercurial-scm.org/D9477
AFFECTED FILES
hgext/largefiles/overrides.py
hgext/lfs/wrapper.py
mercurial/upgrade.py
mercurial/upgrade_utils/actions.py
CHANGE DETAILS
diff --git a/mercurial/upgrade.py b/mercurial/upgrade_utils/actions.py
copy from mercurial/upgrade.py
copy to mercurial/upgrade_utils/actions.py
--- a/mercurial/upgrade.py
+++ b/mercurial/upgrade_utils/actions.py
@@ -7,21 +7,14 @@
from __future__ import absolute_import
-from .i18n import _
-from . import (
- error,
- hg,
+from ..i18n import _
+from .. import (
localrepo,
- pycompat,
requirements,
util,
)
-from .upgrade_utils import (
- engine as upgrade_engine,
-)
-
-from .utils import compression
+from ..utils import compression
# list of requirements that request a clone of all revlog if added/removed
RECLONES_REQUIREMENTS = {
@@ -333,7 +326,7 @@
@registerformatvariant
-class sharedsafe(requirementformatvariant):
+class sharesafe(requirementformatvariant):
name = b'exp-sharesafe'
_requirement = requirements.SHARESAFE_REQUIREMENT
@@ -544,19 +537,6 @@
return deficiencies
-# search without '-' to support older form on newer client.
-#
-# We don't enforce backward compatibility for debug command so this
-# might eventually be dropped. However, having to use two different
-# forms in script when comparing result is anoying enough to add
-# backward compatibility for a while.
-legacy_opts_map = {
- b'redeltaparent': b're-delta-parent',
- b'redeltamultibase': b're-delta-multibase',
- b'redeltaall': b're-delta-all',
- b'redeltafulladd': b're-delta-fulladd',
-}
-
ALL_OPTIMISATIONS = []
@@ -684,329 +664,3 @@
# e.g. adding generaldelta could schedule parent redeltas.
return newactions
-
-
-def upgraderepo(
- ui,
- repo,
- run=False,
- optimize=None,
- backup=True,
- manifest=None,
- changelog=None,
- filelogs=None,
-):
- """Upgrade a repository in place."""
- if optimize is None:
- optimize = []
- optimize = {legacy_opts_map.get(o, o) for o in optimize}
- repo = repo.unfiltered()
-
- revlogs = set(upgrade_engine.UPGRADE_ALL_REVLOGS)
- specentries = (
- (upgrade_engine.UPGRADE_CHANGELOG, changelog),
- (upgrade_engine.UPGRADE_MANIFEST, manifest),
- (upgrade_engine.UPGRADE_FILELOGS, filelogs),
- )
- specified = [(y, x) for (y, x) in specentries if x is not None]
- if specified:
- # we have some limitation on revlogs to be recloned
- if any(x for y, x in specified):
- revlogs = set()
- for upgrade, enabled in specified:
- if enabled:
- revlogs.add(upgrade)
- else:
- # none are enabled
- for upgrade, __ in specified:
- revlogs.discard(upgrade)
-
- # Ensure the repository can be upgraded.
- missingreqs = requiredsourcerequirements(repo) - repo.requirements
- if missingreqs:
- raise error.Abort(
- _(b'cannot upgrade repository; requirement missing: %s')
- % _(b', ').join(sorted(missingreqs))
- )
-
- blockedreqs = blocksourcerequirements(repo) & repo.requirements
- if blockedreqs:
- raise error.Abort(
- _(
- b'cannot upgrade repository; unsupported source '
- b'requirement: %s'
- )
- % _(b', ').join(sorted(blockedreqs))
- )
-
- # FUTURE there is potentially a need to control the wanted requirements via
- # command arguments or via an extension hook point.
- newreqs = localrepo.newreporequirements(
- repo.ui, localrepo.defaultcreateopts(repo.ui)
- )
- newreqs.update(preservedrequirements(repo))
-
- noremovereqs = (
- repo.requirements - newreqs - supportremovedrequirements(repo)
- )
- if noremovereqs:
- raise error.Abort(
- _(
- b'cannot upgrade repository; requirement would be '
- b'removed: %s'
- )
- % _(b', ').join(sorted(noremovereqs))
- )
-
- noaddreqs = newreqs - repo.requirements - allowednewrequirements(repo)
- if noaddreqs:
- raise error.Abort(
- _(
- b'cannot upgrade repository; do not support adding '
- b'requirement: %s'
- )
- % _(b', ').join(sorted(noaddreqs))
- )
-
- unsupportedreqs = newreqs - supporteddestrequirements(repo)
- if unsupportedreqs:
- raise error.Abort(
- _(
- b'cannot upgrade repository; do not support '
- b'destination requirement: %s'
- )
- % _(b', ').join(sorted(unsupportedreqs))
- )
-
- # Find and validate all improvements that can be made.
- alloptimizations = findoptimizations(repo)
-
- # Apply and Validate arguments.
- optimizations = []
- for o in alloptimizations:
- if o.name in optimize:
- optimizations.append(o)
- optimize.discard(o.name)
-
- if optimize: # anything left is unknown
- raise error.Abort(
- _(b'unknown optimization action requested: %s')
- % b', '.join(sorted(optimize)),
- hint=_(b'run without arguments to see valid optimizations'),
- )
-
- deficiencies = finddeficiencies(repo)
- actions = determineactions(repo, deficiencies, repo.requirements, newreqs)
- actions.extend(
- o
- for o in sorted(optimizations)
- # determineactions could have added optimisation
- if o not in actions
- )
-
- removedreqs = repo.requirements - newreqs
- addedreqs = newreqs - repo.requirements
-
- if revlogs != upgrade_engine.UPGRADE_ALL_REVLOGS:
- incompatible = RECLONES_REQUIREMENTS & (removedreqs | addedreqs)
- if incompatible:
- msg = _(
- b'ignoring revlogs selection flags, format requirements '
- b'change: %s\n'
- )
- ui.warn(msg % b', '.join(sorted(incompatible)))
- revlogs = upgrade_engine.UPGRADE_ALL_REVLOGS
-
- def write_labeled(l, label):
- first = True
- for r in sorted(l):
- if not first:
- ui.write(b', ')
- ui.write(r, label=label)
- first = False
-
- def printrequirements():
- ui.write(_(b'requirements\n'))
- ui.write(_(b' preserved: '))
- write_labeled(
- newreqs & repo.requirements, "upgrade-repo.requirement.preserved"
- )
- ui.write((b'\n'))
- removed = repo.requirements - newreqs
- if repo.requirements - newreqs:
- ui.write(_(b' removed: '))
- write_labeled(removed, "upgrade-repo.requirement.removed")
- ui.write((b'\n'))
- added = newreqs - repo.requirements
- if added:
- ui.write(_(b' added: '))
- write_labeled(added, "upgrade-repo.requirement.added")
- ui.write((b'\n'))
- ui.write(b'\n')
-
- def printoptimisations():
- optimisations = [a for a in actions if a.type == OPTIMISATION]
- optimisations.sort(key=lambda a: a.name)
- if optimisations:
- ui.write(_(b'optimisations: '))
- write_labeled(
- [a.name for a in optimisations],
- "upgrade-repo.optimisation.performed",
- )
- ui.write(b'\n\n')
-
- def printupgradeactions():
- for a in actions:
- ui.status(b'%s\n %s\n\n' % (a.name, a.upgrademessage))
-
- def print_affected_revlogs():
- if not revlogs:
- ui.write((b'no revlogs to process\n'))
- else:
- ui.write((b'processed revlogs:\n'))
- for r in sorted(revlogs):
- ui.write((b' - %s\n' % r))
- ui.write((b'\n'))
-
- if not run:
- fromconfig = []
- onlydefault = []
-
- for d in deficiencies:
- if d.fromconfig(repo):
- fromconfig.append(d)
- elif d.default:
- onlydefault.append(d)
-
- if fromconfig or onlydefault:
-
- if fromconfig:
- ui.status(
- _(
- b'repository lacks features recommended by '
- b'current config options:\n\n'
- )
- )
- for i in fromconfig:
- ui.status(b'%s\n %s\n\n' % (i.name, i.description))
-
- if onlydefault:
- ui.status(
- _(
- b'repository lacks features used by the default '
- b'config options:\n\n'
- )
- )
- for i in onlydefault:
- ui.status(b'%s\n %s\n\n' % (i.name, i.description))
-
- ui.status(b'\n')
- else:
- ui.status(
- _(
- b'(no feature deficiencies found in existing '
- b'repository)\n'
- )
- )
-
- ui.status(
- _(
- b'performing an upgrade with "--run" will make the following '
- b'changes:\n\n'
- )
- )
-
- printrequirements()
- printoptimisations()
- printupgradeactions()
- print_affected_revlogs()
-
- unusedoptimize = [i for i in alloptimizations if i not in actions]
-
- if unusedoptimize:
- ui.status(
- _(
- b'additional optimizations are available by specifying '
- b'"--optimize <name>":\n\n'
- )
- )
- for i in unusedoptimize:
- ui.status(_(b'%s\n %s\n\n') % (i.name, i.description))
- return
-
- # Else we're in the run=true case.
- ui.write(_(b'upgrade will perform the following actions:\n\n'))
- printrequirements()
- printoptimisations()
- printupgradeactions()
- print_affected_revlogs()
-
- upgradeactions = [a.name for a in actions]
-
- ui.status(_(b'beginning upgrade...\n'))
- with repo.wlock(), repo.lock():
- ui.status(_(b'repository locked and read-only\n'))
- # Our strategy for upgrading the repository is to create a new,
- # temporary repository, write data to it, then do a swap of the
- # data. There are less heavyweight ways to do this, but it is easier
- # to create a new repo object than to instantiate all the components
- # (like the store) separately.
- tmppath = pycompat.mkdtemp(prefix=b'upgrade.', dir=repo.path)
- backuppath = None
- try:
- ui.status(
- _(
- b'creating temporary repository to stage migrated '
- b'data: %s\n'
- )
- % tmppath
- )
-
- # clone ui without using ui.copy because repo.ui is protected
- repoui = repo.ui.__class__(repo.ui)
- dstrepo = hg.repository(repoui, path=tmppath, create=True)
-
- with dstrepo.wlock(), dstrepo.lock():
- backuppath = upgrade_engine.upgrade(
- ui, repo, dstrepo, newreqs, upgradeactions, revlogs=revlogs
- )
- if not (backup or backuppath is None):
- ui.status(
- _(b'removing old repository content%s\n') % backuppath
- )
- repo.vfs.rmtree(backuppath, forcibly=True)
- backuppath = None
-
- finally:
- ui.status(_(b'removing temporary repository %s\n') % tmppath)
- repo.vfs.rmtree(tmppath, forcibly=True)
-
- if backuppath and not ui.quiet:
- ui.warn(
- _(b'copy of old repository backed up at %s\n') % backuppath
- )
- ui.warn(
- _(
- b'the old repository will not be deleted; remove '
- b'it to free up disk space once the upgraded '
- b'repository is verified\n'
- )
- )
-
- if sharedsafe.name in addedreqs:
- ui.warn(
- _(
- b'repository upgraded to share safe mode, existing'
- b' shares will still work in old non-safe mode. '
- b'Re-share existing shares to use them in safe mode'
- b' New shares will be created in safe mode.\n'
- )
- )
- if sharedsafe.name in removedreqs:
- ui.warn(
- _(
- b'repository downgraded to not use share safe mode, '
- b'existing shares will not work and needs to'
- b' be reshared.\n'
- )
- )
diff --git a/mercurial/upgrade.py b/mercurial/upgrade.py
--- a/mercurial/upgrade.py
+++ b/mercurial/upgrade.py
@@ -13,536 +13,14 @@
hg,
localrepo,
pycompat,
- requirements,
- util,
)
from .upgrade_utils import (
+ actions as upgrade_actions,
engine as upgrade_engine,
)
-from .utils import compression
-
-# list of requirements that request a clone of all revlog if added/removed
-RECLONES_REQUIREMENTS = {
- b'generaldelta',
- requirements.SPARSEREVLOG_REQUIREMENT,
-}
-
-
-def requiredsourcerequirements(repo):
- """Obtain requirements required to be present to upgrade a repo.
-
- An upgrade will not be allowed if the repository doesn't have the
- requirements returned by this function.
- """
- return {
- # Introduced in Mercurial 0.9.2.
- b'revlogv1',
- # Introduced in Mercurial 0.9.2.
- b'store',
- }
-
-
-def blocksourcerequirements(repo):
- """Obtain requirements that will prevent an upgrade from occurring.
-
- An upgrade cannot be performed if the source repository contains a
- requirements in the returned set.
- """
- return {
- # The upgrade code does not yet support these experimental features.
- # This is an artificial limitation.
- requirements.TREEMANIFEST_REQUIREMENT,
- # This was a precursor to generaldelta and was never enabled by default.
- # It should (hopefully) not exist in the wild.
- b'parentdelta',
- # Upgrade should operate on the actual store, not the shared link.
- requirements.SHARED_REQUIREMENT,
- }
-
-
-def supportremovedrequirements(repo):
- """Obtain requirements that can be removed during an upgrade.
-
- If an upgrade were to create a repository that dropped a requirement,
- the dropped requirement must appear in the returned set for the upgrade
- to be allowed.
- """
- supported = {
- requirements.SPARSEREVLOG_REQUIREMENT,
- requirements.SIDEDATA_REQUIREMENT,
- requirements.COPIESSDC_REQUIREMENT,
- requirements.NODEMAP_REQUIREMENT,
- requirements.SHARESAFE_REQUIREMENT,
- }
- for name in compression.compengines:
- engine = compression.compengines[name]
- if engine.available() and engine.revlogheader():
- supported.add(b'exp-compression-%s' % name)
- if engine.name() == b'zstd':
- supported.add(b'revlog-compression-zstd')
- return supported
-
-
-def supporteddestrequirements(repo):
- """Obtain requirements that upgrade supports in the destination.
-
- If the result of the upgrade would create requirements not in this set,
- the upgrade is disallowed.
-
- Extensions should monkeypatch this to add their custom requirements.
- """
- supported = {
- b'dotencode',
- b'fncache',
- b'generaldelta',
- b'revlogv1',
- b'store',
- requirements.SPARSEREVLOG_REQUIREMENT,
- requirements.SIDEDATA_REQUIREMENT,
- requirements.COPIESSDC_REQUIREMENT,
- requirements.NODEMAP_REQUIREMENT,
- requirements.SHARESAFE_REQUIREMENT,
- }
- for name in compression.compengines:
- engine = compression.compengines[name]
- if engine.available() and engine.revlogheader():
- supported.add(b'exp-compression-%s' % name)
- if engine.name() == b'zstd':
- supported.add(b'revlog-compression-zstd')
- return supported
-
-
-def allowednewrequirements(repo):
- """Obtain requirements that can be added to a repository during upgrade.
-
- This is used to disallow proposed requirements from being added when
- they weren't present before.
-
- We use a list of allowed requirement additions instead of a list of known
- bad additions because the whitelist approach is safer and will prevent
- future, unknown requirements from accidentally being added.
- """
- supported = {
- b'dotencode',
- b'fncache',
- b'generaldelta',
- requirements.SPARSEREVLOG_REQUIREMENT,
- requirements.SIDEDATA_REQUIREMENT,
- requirements.COPIESSDC_REQUIREMENT,
- requirements.NODEMAP_REQUIREMENT,
- requirements.SHARESAFE_REQUIREMENT,
- }
- for name in compression.compengines:
- engine = compression.compengines[name]
- if engine.available() and engine.revlogheader():
- supported.add(b'exp-compression-%s' % name)
- if engine.name() == b'zstd':
- supported.add(b'revlog-compression-zstd')
- return supported
-
-
-def preservedrequirements(repo):
- return set()
-
-
-DEFICIENCY = b'deficiency'
-OPTIMISATION = b'optimization'
-
-
-class improvement(object):
- """Represents an improvement that can be made as part of an upgrade.
-
- The following attributes are defined on each instance:
-
- name
- Machine-readable string uniquely identifying this improvement. It
- will be mapped to an action later in the upgrade process.
-
- type
- Either ``DEFICIENCY`` or ``OPTIMISATION``. A deficiency is an obvious
- problem. An optimization is an action (sometimes optional) that
- can be taken to further improve the state of the repository.
-
- description
- Message intended for humans explaining the improvement in more detail,
- including the implications of it. For ``DEFICIENCY`` types, should be
- worded in the present tense. For ``OPTIMISATION`` types, should be
- worded in the future tense.
-
- upgrademessage
- Message intended for humans explaining what an upgrade addressing this
- issue will do. Should be worded in the future tense.
- """
-
- def __init__(self, name, type, description, upgrademessage):
- self.name = name
- self.type = type
- self.description = description
- self.upgrademessage = upgrademessage
-
- def __eq__(self, other):
- if not isinstance(other, improvement):
- # This is what python tell use to do
- return NotImplemented
- return self.name == other.name
-
- def __ne__(self, other):
- return not (self == other)
-
- def __hash__(self):
- return hash(self.name)
-
-
-allformatvariant = []
-
-
-def registerformatvariant(cls):
- allformatvariant.append(cls)
- return cls
-
-
-class formatvariant(improvement):
- """an improvement subclass dedicated to repository format"""
-
- type = DEFICIENCY
- ### The following attributes should be defined for each class:
-
- # machine-readable string uniquely identifying this improvement. it will be
- # mapped to an action later in the upgrade process.
- name = None
-
- # message intended for humans explaining the improvement in more detail,
- # including the implications of it ``DEFICIENCY`` types, should be worded
- # in the present tense.
- description = None
-
- # message intended for humans explaining what an upgrade addressing this
- # issue will do. should be worded in the future tense.
- upgrademessage = None
-
- # value of current Mercurial default for new repository
- default = None
-
- def __init__(self):
- raise NotImplementedError()
-
- @staticmethod
- def fromrepo(repo):
- """current value of the variant in the repository"""
- raise NotImplementedError()
-
- @staticmethod
- def fromconfig(repo):
- """current value of the variant in the configuration"""
- raise NotImplementedError()
-
-
-class requirementformatvariant(formatvariant):
- """formatvariant based on a 'requirement' name.
-
- Many format variant are controlled by a 'requirement'. We define a small
- subclass to factor the code.
- """
-
- # the requirement that control this format variant
- _requirement = None
-
- @staticmethod
- def _newreporequirements(ui):
- return localrepo.newreporequirements(
- ui, localrepo.defaultcreateopts(ui)
- )
-
- @classmethod
- def fromrepo(cls, repo):
- assert cls._requirement is not None
- return cls._requirement in repo.requirements
-
- @classmethod
- def fromconfig(cls, repo):
- assert cls._requirement is not None
- return cls._requirement in cls._newreporequirements(repo.ui)
-
-
- at registerformatvariant
-class fncache(requirementformatvariant):
- name = b'fncache'
-
- _requirement = b'fncache'
-
- default = True
-
- description = _(
- b'long and reserved filenames may not work correctly; '
- b'repository performance is sub-optimal'
- )
-
- upgrademessage = _(
- b'repository will be more resilient to storing '
- b'certain paths and performance of certain '
- b'operations should be improved'
- )
-
-
- at registerformatvariant
-class dotencode(requirementformatvariant):
- name = b'dotencode'
-
- _requirement = b'dotencode'
-
- default = True
-
- description = _(
- b'storage of filenames beginning with a period or '
- b'space may not work correctly'
- )
-
- upgrademessage = _(
- b'repository will be better able to store files '
- b'beginning with a space or period'
- )
-
-
- at registerformatvariant
-class generaldelta(requirementformatvariant):
- name = b'generaldelta'
-
- _requirement = b'generaldelta'
-
- default = True
-
- description = _(
- b'deltas within internal storage are unable to '
- b'choose optimal revisions; repository is larger and '
- b'slower than it could be; interaction with other '
- b'repositories may require extra network and CPU '
- b'resources, making "hg push" and "hg pull" slower'
- )
-
- upgrademessage = _(
- b'repository storage will be able to create '
- b'optimal deltas; new repository data will be '
- b'smaller and read times should decrease; '
- b'interacting with other repositories using this '
- b'storage model should require less network and '
- b'CPU resources, making "hg push" and "hg pull" '
- b'faster'
- )
-
-
- at registerformatvariant
-class sharedsafe(requirementformatvariant):
- name = b'exp-sharesafe'
- _requirement = requirements.SHARESAFE_REQUIREMENT
-
- default = False
-
- description = _(
- b'old shared repositories do not share source repository '
- b'requirements and config. This leads to various problems '
- b'when the source repository format is upgraded or some new '
- b'extensions are enabled.'
- )
-
- upgrademessage = _(
- b'Upgrades a repository to share-safe format so that future '
- b'shares of this repository share its requirements and configs.'
- )
-
-
- at registerformatvariant
-class sparserevlog(requirementformatvariant):
- name = b'sparserevlog'
-
- _requirement = requirements.SPARSEREVLOG_REQUIREMENT
-
- default = True
-
- description = _(
- b'in order to limit disk reading and memory usage on older '
- b'version, the span of a delta chain from its root to its '
- b'end is limited, whatever the relevant data in this span. '
- b'This can severly limit Mercurial ability to build good '
- b'chain of delta resulting is much more storage space being '
- b'taken and limit reusability of on disk delta during '
- b'exchange.'
- )
-
- upgrademessage = _(
- b'Revlog supports delta chain with more unused data '
- b'between payload. These gaps will be skipped at read '
- b'time. This allows for better delta chains, making a '
- b'better compression and faster exchange with server.'
- )
-
-
- at registerformatvariant
-class sidedata(requirementformatvariant):
- name = b'sidedata'
-
- _requirement = requirements.SIDEDATA_REQUIREMENT
-
- default = False
-
- description = _(
- b'Allows storage of extra data alongside a revision, '
- b'unlocking various caching options.'
- )
-
- upgrademessage = _(b'Allows storage of extra data alongside a revision.')
-
-
- at registerformatvariant
-class persistentnodemap(requirementformatvariant):
- name = b'persistent-nodemap'
-
- _requirement = requirements.NODEMAP_REQUIREMENT
-
- default = False
-
- description = _(
- b'persist the node -> rev mapping on disk to speedup lookup'
- )
-
- upgrademessage = _(b'Speedup revision lookup by node id.')
-
-
- at registerformatvariant
-class copiessdc(requirementformatvariant):
- name = b'copies-sdc'
-
- _requirement = requirements.COPIESSDC_REQUIREMENT
-
- default = False
-
- description = _(b'Stores copies information alongside changesets.')
-
- upgrademessage = _(
- b'Allows to use more efficient algorithm to deal with ' b'copy tracing.'
- )
-
-
- at registerformatvariant
-class removecldeltachain(formatvariant):
- name = b'plain-cl-delta'
-
- default = True
-
- description = _(
- b'changelog storage is using deltas instead of '
- b'raw entries; changelog reading and any '
- b'operation relying on changelog data are slower '
- b'than they could be'
- )
-
- upgrademessage = _(
- b'changelog storage will be reformated to '
- b'store raw entries; changelog reading will be '
- b'faster; changelog size may be reduced'
- )
-
- @staticmethod
- def fromrepo(repo):
- # Mercurial 4.0 changed changelogs to not use delta chains. Search for
- # changelogs with deltas.
- cl = repo.changelog
- chainbase = cl.chainbase
- return all(rev == chainbase(rev) for rev in cl)
-
- @staticmethod
- def fromconfig(repo):
- return True
-
-
- at registerformatvariant
-class compressionengine(formatvariant):
- name = b'compression'
- default = b'zlib'
-
- description = _(
- b'Compresion algorithm used to compress data. '
- b'Some engine are faster than other'
- )
-
- upgrademessage = _(
- b'revlog content will be recompressed with the new algorithm.'
- )
-
- @classmethod
- def fromrepo(cls, repo):
- # we allow multiple compression engine requirement to co-exist because
- # strickly speaking, revlog seems to support mixed compression style.
- #
- # The compression used for new entries will be "the last one"
- compression = b'zlib'
- for req in repo.requirements:
- prefix = req.startswith
- if prefix(b'revlog-compression-') or prefix(b'exp-compression-'):
- compression = req.split(b'-', 2)[2]
- return compression
-
- @classmethod
- def fromconfig(cls, repo):
- compengines = repo.ui.configlist(b'format', b'revlog-compression')
- # return the first valid value as the selection code would do
- for comp in compengines:
- if comp in util.compengines:
- return comp
-
- # no valide compression found lets display it all for clarity
- return b','.join(compengines)
-
-
- at registerformatvariant
-class compressionlevel(formatvariant):
- name = b'compression-level'
- default = b'default'
-
- description = _(b'compression level')
-
- upgrademessage = _(b'revlog content will be recompressed')
-
- @classmethod
- def fromrepo(cls, repo):
- comp = compressionengine.fromrepo(repo)
- level = None
- if comp == b'zlib':
- level = repo.ui.configint(b'storage', b'revlog.zlib.level')
- elif comp == b'zstd':
- level = repo.ui.configint(b'storage', b'revlog.zstd.level')
- if level is None:
- return b'default'
- return bytes(level)
-
- @classmethod
- def fromconfig(cls, repo):
- comp = compressionengine.fromconfig(repo)
- level = None
- if comp == b'zlib':
- level = repo.ui.configint(b'storage', b'revlog.zlib.level')
- elif comp == b'zstd':
- level = repo.ui.configint(b'storage', b'revlog.zstd.level')
- if level is None:
- return b'default'
- return bytes(level)
-
-
-def finddeficiencies(repo):
- """returns a list of deficiencies that the repo suffer from"""
- deficiencies = []
-
- # We could detect lack of revlogv1 and store here, but they were added
- # in 0.9.2 and we don't support upgrading repos without these
- # requirements, so let's not bother.
-
- for fv in allformatvariant:
- if not fv.fromrepo(repo):
- deficiencies.append(fv)
-
- return deficiencies
-
+allformatvariant = upgrade_actions.allformatvariant
# search without '-' to support older form on newer client.
#
@@ -557,134 +35,6 @@
b'redeltafulladd': b're-delta-fulladd',
}
-ALL_OPTIMISATIONS = []
-
-
-def register_optimization(obj):
- ALL_OPTIMISATIONS.append(obj)
- return obj
-
-
-register_optimization(
- improvement(
- name=b're-delta-parent',
- type=OPTIMISATION,
- description=_(
- b'deltas within internal storage will be recalculated to '
- b'choose an optimal base revision where this was not '
- b'already done; the size of the repository may shrink and '
- b'various operations may become faster; the first time '
- b'this optimization is performed could slow down upgrade '
- b'execution considerably; subsequent invocations should '
- b'not run noticeably slower'
- ),
- upgrademessage=_(
- b'deltas within internal storage will choose a new '
- b'base revision if needed'
- ),
- )
-)
-
-register_optimization(
- improvement(
- name=b're-delta-multibase',
- type=OPTIMISATION,
- description=_(
- b'deltas within internal storage will be recalculated '
- b'against multiple base revision and the smallest '
- b'difference will be used; the size of the repository may '
- b'shrink significantly when there are many merges; this '
- b'optimization will slow down execution in proportion to '
- b'the number of merges in the repository and the amount '
- b'of files in the repository; this slow down should not '
- b'be significant unless there are tens of thousands of '
- b'files and thousands of merges'
- ),
- upgrademessage=_(
- b'deltas within internal storage will choose an '
- b'optimal delta by computing deltas against multiple '
- b'parents; may slow down execution time '
- b'significantly'
- ),
- )
-)
-
-register_optimization(
- improvement(
- name=b're-delta-all',
- type=OPTIMISATION,
- description=_(
- b'deltas within internal storage will always be '
- b'recalculated without reusing prior deltas; this will '
- b'likely make execution run several times slower; this '
- b'optimization is typically not needed'
- ),
- upgrademessage=_(
- b'deltas within internal storage will be fully '
- b'recomputed; this will likely drastically slow down '
- b'execution time'
- ),
- )
-)
-
-register_optimization(
- improvement(
- name=b're-delta-fulladd',
- type=OPTIMISATION,
- description=_(
- b'every revision will be re-added as if it was new '
- b'content. It will go through the full storage '
- b'mechanism giving extensions a chance to process it '
- b'(eg. lfs). This is similar to "re-delta-all" but even '
- b'slower since more logic is involved.'
- ),
- upgrademessage=_(
- b'each revision will be added as new content to the '
- b'internal storage; this will likely drastically slow '
- b'down execution time, but some extensions might need '
- b'it'
- ),
- )
-)
-
-
-def findoptimizations(repo):
- """Determine optimisation that could be used during upgrade"""
- # These are unconditionally added. There is logic later that figures out
- # which ones to apply.
- return list(ALL_OPTIMISATIONS)
-
-
-def determineactions(repo, deficiencies, sourcereqs, destreqs):
- """Determine upgrade actions that will be performed.
-
- Given a list of improvements as returned by ``finddeficiencies`` and
- ``findoptimizations``, determine the list of upgrade actions that
- will be performed.
-
- The role of this function is to filter improvements if needed, apply
- recommended optimizations from the improvements list that make sense,
- etc.
-
- Returns a list of action names.
- """
- newactions = []
-
- for d in deficiencies:
- name = d._requirement
-
- # If the action is a requirement that doesn't show up in the
- # destination requirements, prune the action.
- if name is not None and name not in destreqs:
- continue
-
- newactions.append(d)
-
- # FUTURE consider adding some optimizations here for certain transitions.
- # e.g. adding generaldelta could schedule parent redeltas.
-
- return newactions
-
def upgraderepo(
ui,
@@ -722,14 +72,18 @@
revlogs.discard(upgrade)
# Ensure the repository can be upgraded.
- missingreqs = requiredsourcerequirements(repo) - repo.requirements
+ missingreqs = (
+ upgrade_actions.requiredsourcerequirements(repo) - repo.requirements
+ )
if missingreqs:
raise error.Abort(
_(b'cannot upgrade repository; requirement missing: %s')
% _(b', ').join(sorted(missingreqs))
)
- blockedreqs = blocksourcerequirements(repo) & repo.requirements
+ blockedreqs = (
+ upgrade_actions.blocksourcerequirements(repo) & repo.requirements
+ )
if blockedreqs:
raise error.Abort(
_(
@@ -744,10 +98,12 @@
newreqs = localrepo.newreporequirements(
repo.ui, localrepo.defaultcreateopts(repo.ui)
)
- newreqs.update(preservedrequirements(repo))
+ newreqs.update(upgrade_actions.preservedrequirements(repo))
noremovereqs = (
- repo.requirements - newreqs - supportremovedrequirements(repo)
+ repo.requirements
+ - newreqs
+ - upgrade_actions.supportremovedrequirements(repo)
)
if noremovereqs:
raise error.Abort(
@@ -758,7 +114,11 @@
% _(b', ').join(sorted(noremovereqs))
)
- noaddreqs = newreqs - repo.requirements - allowednewrequirements(repo)
+ noaddreqs = (
+ newreqs
+ - repo.requirements
+ - upgrade_actions.allowednewrequirements(repo)
+ )
if noaddreqs:
raise error.Abort(
_(
@@ -768,7 +128,7 @@
% _(b', ').join(sorted(noaddreqs))
)
- unsupportedreqs = newreqs - supporteddestrequirements(repo)
+ unsupportedreqs = newreqs - upgrade_actions.supporteddestrequirements(repo)
if unsupportedreqs:
raise error.Abort(
_(
@@ -779,7 +139,7 @@
)
# Find and validate all improvements that can be made.
- alloptimizations = findoptimizations(repo)
+ alloptimizations = upgrade_actions.findoptimizations(repo)
# Apply and Validate arguments.
optimizations = []
@@ -795,8 +155,10 @@
hint=_(b'run without arguments to see valid optimizations'),
)
- deficiencies = finddeficiencies(repo)
- actions = determineactions(repo, deficiencies, repo.requirements, newreqs)
+ deficiencies = upgrade_actions.finddeficiencies(repo)
+ actions = upgrade_actions.determineactions(
+ repo, deficiencies, repo.requirements, newreqs
+ )
actions.extend(
o
for o in sorted(optimizations)
@@ -808,7 +170,9 @@
addedreqs = newreqs - repo.requirements
if revlogs != upgrade_engine.UPGRADE_ALL_REVLOGS:
- incompatible = RECLONES_REQUIREMENTS & (removedreqs | addedreqs)
+ incompatible = upgrade_actions.RECLONES_REQUIREMENTS & (
+ removedreqs | addedreqs
+ )
if incompatible:
msg = _(
b'ignoring revlogs selection flags, format requirements '
@@ -845,7 +209,9 @@
ui.write(b'\n')
def printoptimisations():
- optimisations = [a for a in actions if a.type == OPTIMISATION]
+ optimisations = [
+ a for a in actions if a.type == upgrade_actions.OPTIMISATION
+ ]
optimisations.sort(key=lambda a: a.name)
if optimisations:
ui.write(_(b'optimisations: '))
@@ -993,7 +359,7 @@
)
)
- if sharedsafe.name in addedreqs:
+ if upgrade_actions.sharesafe.name in addedreqs:
ui.warn(
_(
b'repository upgraded to share safe mode, existing'
@@ -1002,7 +368,7 @@
b' New shares will be created in safe mode.\n'
)
)
- if sharedsafe.name in removedreqs:
+ if upgrade_actions.sharesafe.name in removedreqs:
ui.warn(
_(
b'repository downgraded to not use share safe mode, '
diff --git a/hgext/lfs/wrapper.py b/hgext/lfs/wrapper.py
--- a/hgext/lfs/wrapper.py
+++ b/hgext/lfs/wrapper.py
@@ -28,13 +28,15 @@
pycompat,
revlog,
scmutil,
- upgrade,
util,
vfs as vfsmod,
wireprotov1server,
)
-from mercurial.upgrade_utils import engine as upgrade_engine
+from mercurial.upgrade_utils import (
+ actions as upgrade_actions,
+ engine as upgrade_engine,
+)
from mercurial.interfaces import repository
@@ -539,8 +541,8 @@
lfutil.link(srclfsvfs.join(oid), dstlfsvfs.join(oid))
- at eh.wrapfunction(upgrade, b'preservedrequirements')
- at eh.wrapfunction(upgrade, b'supporteddestrequirements')
+ at eh.wrapfunction(upgrade_actions, b'preservedrequirements')
+ at eh.wrapfunction(upgrade_actions, b'supporteddestrequirements')
def upgraderequirements(orig, repo):
reqs = orig(repo)
if b'lfs' in repo.requirements:
diff --git a/hgext/largefiles/overrides.py b/hgext/largefiles/overrides.py
--- a/hgext/largefiles/overrides.py
+++ b/hgext/largefiles/overrides.py
@@ -37,11 +37,14 @@
scmutil,
smartset,
subrepo,
- upgrade,
url as urlmod,
util,
)
+from mercurial.upgrade_utils import (
+ actions as upgrade_actions,
+)
+
from . import (
lfcommands,
lfutil,
@@ -1837,8 +1840,8 @@
return result
- at eh.wrapfunction(upgrade, b'preservedrequirements')
- at eh.wrapfunction(upgrade, b'supporteddestrequirements')
+ at eh.wrapfunction(upgrade_actions, b'preservedrequirements')
+ at eh.wrapfunction(upgrade_actions, b'supporteddestrequirements')
def upgraderequirements(orig, repo):
reqs = orig(repo)
if b'largefiles' in repo.requirements:
To: marmoute, #hg-reviewers
Cc: mercurial-patches
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.mercurial-scm.org/pipermail/mercurial-patches/attachments/20201204/67303859/attachment-0002.html>
More information about the Mercurial-patches
mailing list