##// END OF EJS Templates
hg: add user-site to `sys.path` on Windows to allow pip-installed extensions...
hg: add user-site to `sys.path` on Windows to allow pip-installed extensions This has been in the TortoiseHg builds for several cycles now on Windows, and even longer on macOS. It allows an extension to be configured with `ext =` syntax, instead of requiring the full path to be specified. It's confusing for a user to be hit with messages about not being able to load extensions, based solely on which `hg.exe` is being run. This only applies to py2exe binaries, since wrapper.exe already sees into the user site area. There are no frozen binaries on other platforms (that I'm aware of), and an equivalent change will need to be made to `dispatch.py` in order to work with PyOxidizer, since it bypasses this module completely. (It also has the ability to use the `site` module, so it will look completely different.) Differential Revision: https://phab.mercurial-scm.org/D9531

File last commit:

r46666:72b7b4bf default
r46670:feae6f6d default
Show More
upgrade.py
320 lines | 10.4 KiB | text/x-python | PythonLexer
Pierre-Yves David
upgrade: update the header comment
r31894 # upgrade.py - functions for in place upgrade of Mercurial repository
Pierre-Yves David
upgrade: extract code in its own module...
r31864 #
Pierre-Yves David
upgrade: update the copyright statement
r31895 # Copyright (c) 2016-present, Gregory Szorc
Pierre-Yves David
upgrade: extract code in its own module...
r31864 #
# This software may be used and distributed according to the terms of the
# GNU General Public License version 2 or any later version.
from __future__ import absolute_import
from .i18n import _
from . import (
error,
Boris Feld
upgrade: more standard creation of the temporary repository...
r35344 hg,
Pierre-Yves David
upgrade: import 'localrepo' globally...
r31893 localrepo,
Yuya Nishihara
py3: wrap tempfile.mkdtemp() to use bytes path...
r38183 pycompat,
upgrade: split actual upgrade code away from the main module...
r46661 )
from .upgrade_utils import (
upgrade: split definition and management of the actions from the main code...
r46662 actions as upgrade_actions,
upgrade: split actual upgrade code away from the main module...
r46661 engine as upgrade_engine,
Pierre-Yves David
upgrade: extract code in its own module...
r31864 )
upgrade: split definition and management of the actions from the main code...
r46662 allformatvariant = upgrade_actions.allformatvariant
Augie Fackler
formatting: blacken the codebase...
r43346
Boris Feld
upgrade: add '-' in optimization name...
r41120 # 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 = {
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'redeltaparent': b're-delta-parent',
b'redeltamultibase': b're-delta-multibase',
b'redeltaall': b're-delta-all',
b'redeltafulladd': b're-delta-fulladd',
Boris Feld
upgrade: add '-' in optimization name...
r41120 }
Augie Fackler
formatting: blacken the codebase...
r43346
def upgraderepo(
ui,
repo,
run=False,
optimize=None,
backup=True,
manifest=None,
changelog=None,
upgrade: add an explicite --filelogs arguments...
r46612 filelogs=None,
Augie Fackler
formatting: blacken the codebase...
r43346 ):
Pierre-Yves David
upgrade: extract code in its own module...
r31864 """Upgrade a repository in place."""
Boris Feld
upgrade: add '-' in optimization name...
r41120 if optimize is None:
optimize = []
Augie Fackler
cleanup: run pyupgrade on our source tree to clean up varying things...
r44937 optimize = {legacy_opts_map.get(o, o) for o in optimize}
Pierre-Yves David
upgrade: extract code in its own module...
r31864 repo = repo.unfiltered()
upgrade: split actual upgrade code away from the main module...
r46661 revlogs = set(upgrade_engine.UPGRADE_ALL_REVLOGS)
upgrade: directly use the upgrade action constant...
r46595 specentries = (
upgrade: split actual upgrade code away from the main module...
r46661 (upgrade_engine.UPGRADE_CHANGELOG, changelog),
(upgrade_engine.UPGRADE_MANIFEST, manifest),
(upgrade_engine.UPGRADE_FILELOGS, filelogs),
upgrade: directly use the upgrade action constant...
r46595 )
upgrade: add an argument to control manifest upgrade...
r43098 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()
upgrade: directly use the upgrade action constant...
r46595 for upgrade, enabled in specified:
upgrade: add an argument to control manifest upgrade...
r43098 if enabled:
upgrade: directly use the upgrade action constant...
r46595 revlogs.add(upgrade)
upgrade: add an argument to control manifest upgrade...
r43098 else:
# none are enabled
upgrade: directly use the upgrade action constant...
r46595 for upgrade, __ in specified:
revlogs.discard(upgrade)
upgrade: add an argument to control manifest upgrade...
r43098
Pierre-Yves David
upgrade: extract code in its own module...
r31864 # Ensure the repository can be upgraded.
upgrade: move requirements checking in a dedicated function...
r46663 upgrade_actions.check_source_requirements(repo)
Pierre-Yves David
upgrade: extract code in its own module...
r31864
upgrade: extract the checking of target requirements change...
r46666 default_options = localrepo.defaultcreateopts(repo.ui)
newreqs = localrepo.newreporequirements(repo.ui, default_options)
upgrade: split definition and management of the actions from the main code...
r46662 newreqs.update(upgrade_actions.preservedrequirements(repo))
Pierre-Yves David
upgrade: extract code in its own module...
r31864
upgrade: extract the checking of target requirements change...
r46666 upgrade_actions.check_requirements_changes(repo, newreqs)
Pierre-Yves David
upgrade: extract code in its own module...
r31864
# Find and validate all improvements that can be made.
upgrade: split definition and management of the actions from the main code...
r46662 alloptimizations = upgrade_actions.findoptimizations(repo)
Pierre-Yves David
upgrade: extract code in its own module...
r31864
Pierre-Yves David
upgrade: filter optimizations outside of 'determineactions'...
r31899 # Apply and Validate arguments.
optimizations = []
for o in alloptimizations:
if o.name in optimize:
optimizations.append(o)
optimize.discard(o.name)
Augie Fackler
formatting: blacken the codebase...
r43346 if optimize: # anything left is unknown
raise error.Abort(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'unknown optimization action requested: %s')
% b', '.join(sorted(optimize)),
Martin von Zweigbergk
cleanup: join string literals that are already on one line...
r43387 hint=_(b'run without arguments to see valid optimizations'),
Augie Fackler
formatting: blacken the codebase...
r43346 )
Pierre-Yves David
upgrade: extract code in its own module...
r31864
upgrade: split definition and management of the actions from the main code...
r46662 deficiencies = upgrade_actions.finddeficiencies(repo)
actions = upgrade_actions.determineactions(
repo, deficiencies, repo.requirements, newreqs
)
Augie Fackler
formatting: blacken the codebase...
r43346 actions.extend(
o
for o in sorted(optimizations)
# determineactions could have added optimisation
if o not in actions
)
Pierre-Yves David
upgrade: extract code in its own module...
r31864
upgrade: make sure we reclone all revlogs when updating to some format...
r43100 removedreqs = repo.requirements - newreqs
addedreqs = newreqs - repo.requirements
upgrade: split actual upgrade code away from the main module...
r46661 if revlogs != upgrade_engine.UPGRADE_ALL_REVLOGS:
upgrade: split definition and management of the actions from the main code...
r46662 incompatible = upgrade_actions.RECLONES_REQUIREMENTS & (
removedreqs | addedreqs
)
upgrade: make sure we reclone all revlogs when updating to some format...
r43100 if incompatible:
Augie Fackler
formatting: blacken the codebase...
r43346 msg = _(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'ignoring revlogs selection flags, format requirements '
b'change: %s\n'
Augie Fackler
formatting: blacken the codebase...
r43346 )
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.warn(msg % b', '.join(sorted(incompatible)))
upgrade: split actual upgrade code away from the main module...
r46661 revlogs = upgrade_engine.UPGRADE_ALL_REVLOGS
upgrade: make sure we reclone all revlogs when updating to some format...
r43100
upgrade-repo: colorize some of the output...
r44257 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
Pierre-Yves David
upgrade: extract code in its own module...
r31864 def printrequirements():
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.write(_(b'requirements\n'))
upgrade-repo: colorize some of the output...
r44257 ui.write(_(b' preserved: '))
write_labeled(
newreqs & repo.requirements, "upgrade-repo.requirement.preserved"
Augie Fackler
formatting: blacken the codebase...
r43346 )
upgrade-repo: colorize some of the output...
r44257 ui.write((b'\n'))
removed = repo.requirements - newreqs
Pierre-Yves David
upgrade: extract code in its own module...
r31864 if repo.requirements - newreqs:
upgrade-repo: colorize some of the output...
r44257 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'))
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.write(b'\n')
Pierre-Yves David
upgrade: extract code in its own module...
r31864
upgrade: clearly list optimisations...
r45301 def printoptimisations():
upgrade: split definition and management of the actions from the main code...
r46662 optimisations = [
a for a in actions if a.type == upgrade_actions.OPTIMISATION
]
upgrade: clearly list optimisations...
r45301 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')
Pierre-Yves David
upgrade: extract code in its own module...
r31864 def printupgradeactions():
Pierre-Yves David
upgrade: use 'improvement' object for action too...
r31903 for a in actions:
upgrade: support the --quiet flag...
r45302 ui.status(b'%s\n %s\n\n' % (a.name, a.upgrademessage))
Pierre-Yves David
upgrade: extract code in its own module...
r31864
upgrade: display the list of processed revlog before proceeding...
r46649 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'))
Pierre-Yves David
upgrade: extract code in its own module...
r31864 if not run:
fromconfig = []
Pierre-Yves David
upgrade: simplify the "origin" dispatch in dry run...
r31904 onlydefault = []
Pierre-Yves David
upgrade: extract code in its own module...
r31864
Pierre-Yves David
upgrade: simplify some of the initial dispatch for dry run...
r31901 for d in deficiencies:
Pierre-Yves David
upgrade: move descriptions and selection logic in individual classes...
r32031 if d.fromconfig(repo):
Pierre-Yves David
upgrade: simplify some of the initial dispatch for dry run...
r31901 fromconfig.append(d)
Pierre-Yves David
upgrade: move descriptions and selection logic in individual classes...
r32031 elif d.default:
Pierre-Yves David
upgrade: simplify the "origin" dispatch in dry run...
r31904 onlydefault.append(d)
Pierre-Yves David
upgrade: extract code in its own module...
r31864
Pierre-Yves David
upgrade: simplify the "origin" dispatch in dry run...
r31904 if fromconfig or onlydefault:
Pierre-Yves David
upgrade: extract code in its own module...
r31864
if fromconfig:
upgrade: support the --quiet flag...
r45302 ui.status(
Augie Fackler
formatting: blacken the codebase...
r43346 _(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'repository lacks features recommended by '
b'current config options:\n\n'
Augie Fackler
formatting: blacken the codebase...
r43346 )
)
Pierre-Yves David
upgrade: extract code in its own module...
r31864 for i in fromconfig:
upgrade: support the --quiet flag...
r45302 ui.status(b'%s\n %s\n\n' % (i.name, i.description))
Pierre-Yves David
upgrade: extract code in its own module...
r31864
if onlydefault:
upgrade: support the --quiet flag...
r45302 ui.status(
Augie Fackler
formatting: blacken the codebase...
r43346 _(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'repository lacks features used by the default '
b'config options:\n\n'
Augie Fackler
formatting: blacken the codebase...
r43346 )
)
Pierre-Yves David
upgrade: extract code in its own module...
r31864 for i in onlydefault:
upgrade: support the --quiet flag...
r45302 ui.status(b'%s\n %s\n\n' % (i.name, i.description))
Pierre-Yves David
upgrade: extract code in its own module...
r31864
upgrade: support the --quiet flag...
r45302 ui.status(b'\n')
Pierre-Yves David
upgrade: extract code in its own module...
r31864 else:
upgrade: support the --quiet flag...
r45302 ui.status(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(
b'(no feature deficiencies found in existing '
b'repository)\n'
)
Augie Fackler
formatting: blacken the codebase...
r43346 )
Pierre-Yves David
upgrade: extract code in its own module...
r31864
upgrade: support the --quiet flag...
r45302 ui.status(
Augie Fackler
formatting: blacken the codebase...
r43346 _(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'performing an upgrade with "--run" will make the following '
b'changes:\n\n'
Augie Fackler
formatting: blacken the codebase...
r43346 )
)
Pierre-Yves David
upgrade: extract code in its own module...
r31864
printrequirements()
upgrade: clearly list optimisations...
r45301 printoptimisations()
Pierre-Yves David
upgrade: extract code in its own module...
r31864 printupgradeactions()
upgrade: display the list of processed revlog before proceeding...
r46649 print_affected_revlogs()
Pierre-Yves David
upgrade: extract code in its own module...
r31864
Pierre-Yves David
upgrade: use 'improvement' object for action too...
r31903 unusedoptimize = [i for i in alloptimizations if i not in actions]
Pierre-Yves David
upgrade: extract code in its own module...
r31864 if unusedoptimize:
upgrade: support the --quiet flag...
r45302 ui.status(
Augie Fackler
formatting: blacken the codebase...
r43346 _(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'additional optimizations are available by specifying '
b'"--optimize <name>":\n\n'
Augie Fackler
formatting: blacken the codebase...
r43346 )
)
Pierre-Yves David
upgrade: extract code in its own module...
r31864 for i in unusedoptimize:
upgrade: support the --quiet flag...
r45302 ui.status(_(b'%s\n %s\n\n') % (i.name, i.description))
Pierre-Yves David
upgrade: extract code in its own module...
r31864 return
# Else we're in the run=true case.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 ui.write(_(b'upgrade will perform the following actions:\n\n'))
Pierre-Yves David
upgrade: extract code in its own module...
r31864 printrequirements()
upgrade: clearly list optimisations...
r45301 printoptimisations()
Pierre-Yves David
upgrade: extract code in its own module...
r31864 printupgradeactions()
upgrade: display the list of processed revlog before proceeding...
r46649 print_affected_revlogs()
Pierre-Yves David
upgrade: extract code in its own module...
r31864
Pierre-Yves David
upgrade: use 'improvement' object for action too...
r31903 upgradeactions = [a.name for a in actions]
upgrade: support the --quiet flag...
r45302 ui.status(_(b'beginning upgrade...\n'))
Jun Wu
codemod: simplify nested withs...
r33438 with repo.wlock(), repo.lock():
upgrade: support the --quiet flag...
r45302 ui.status(_(b'repository locked and read-only\n'))
Jun Wu
codemod: simplify nested withs...
r33438 # 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.
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 tmppath = pycompat.mkdtemp(prefix=b'upgrade.', dir=repo.path)
Jun Wu
codemod: simplify nested withs...
r33438 backuppath = None
try:
upgrade: support the --quiet flag...
r45302 ui.status(
Augie Fackler
formatting: blacken the codebase...
r43346 _(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'creating temporary repository to stage migrated '
b'data: %s\n'
Augie Fackler
formatting: blacken the codebase...
r43346 )
% tmppath
)
Boris Feld
upgrade: use the repository 'ui' as the base for the new repository...
r35343
Yuya Nishihara
upgrade: simplify workaround for repo.ui.copy()...
r35380 # 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)
Pierre-Yves David
upgrade: extract code in its own module...
r31864
Jun Wu
codemod: simplify nested withs...
r33438 with dstrepo.wlock(), dstrepo.lock():
upgrade: split actual upgrade code away from the main module...
r46661 backuppath = upgrade_engine.upgrade(
Augie Fackler
formatting: blacken the codebase...
r43346 ui, repo, dstrepo, newreqs, upgradeactions, revlogs=revlogs
)
Boris Feld
debugupgraderepo: add a --no-backup mode...
r41121 if not (backup or backuppath is None):
upgrade: support the --quiet flag...
r45302 ui.status(
_(b'removing old repository content%s\n') % backuppath
)
Boris Feld
debugupgraderepo: add a --no-backup mode...
r41121 repo.vfs.rmtree(backuppath, forcibly=True)
backuppath = None
Pierre-Yves David
upgrade: extract code in its own module...
r31864
Jun Wu
codemod: simplify nested withs...
r33438 finally:
upgrade: support the --quiet flag...
r45302 ui.status(_(b'removing temporary repository %s\n') % tmppath)
Jun Wu
codemod: simplify nested withs...
r33438 repo.vfs.rmtree(tmppath, forcibly=True)
Pierre-Yves David
upgrade: extract code in its own module...
r31864
upgrade: support the --quiet flag...
r45302 if backuppath and not ui.quiet:
Augie Fackler
formatting: blacken the codebase...
r43346 ui.warn(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 _(b'copy of old repository backed up at %s\n') % backuppath
Augie Fackler
formatting: blacken the codebase...
r43346 )
ui.warn(
_(
Augie Fackler
formatting: byteify all mercurial/ and hgext/ string literals...
r43347 b'the old repository will not be deleted; remove '
b'it to free up disk space once the upgraded '
b'repository is verified\n'
Augie Fackler
formatting: blacken the codebase...
r43346 )
)
Pulkit Goyal
upgrade: add support for experimental safe share mode...
r46617
upgrade: split definition and management of the actions from the main code...
r46662 if upgrade_actions.sharesafe.name in addedreqs:
Pulkit Goyal
upgrade: add support for experimental safe share mode...
r46617 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'
)
)
upgrade: split definition and management of the actions from the main code...
r46662 if upgrade_actions.sharesafe.name in removedreqs:
Pulkit Goyal
upgrade: add support to downgrade share safe mode...
r46618 ui.warn(
_(
b'repository downgraded to not use share safe mode, '
b'existing shares will not work and needs to'
b' be reshared.\n'
)
)