diff --git a/mercurial/debugcommands.py b/mercurial/debugcommands.py --- a/mercurial/debugcommands.py +++ b/mercurial/debugcommands.py @@ -69,6 +69,7 @@ pycompat, registrar, repair, + requirements as requirementsmod, revlog, revset, revsetlang, @@ -3695,6 +3696,107 @@ @command( + b'debugsharesafe', + [ + (b'', b'upgrade', False, _(b'upgrade current share to share safe')), + (b'', b'downgrade', False, _(b'downgrade current share')), + (b'', b'force', False, _(b'forcefully perform operation')), + ], +) +def debugsharesafe(ui, repo, *args, **opts): + """upgrade or downgrade shares to enable/disable share-safe mode""" + if not repo.shared(): + raise error.InputError(_(b"current repository is not shared one")) + + cmdutil.check_at_most_one_arg(opts, 'upgrade', 'downgrade') + upgrade = opts.get('upgrade') + downgrade = opts.get('downgrade') + + if not upgrade and not downgrade: + raise error.InputError(_(b"nothing specified")) + + current_requirements = repo.requirements + if upgrade: + if requirementsmod.SHARESAFE_REQUIREMENT in current_requirements: + raise error.StateError( + _(b"repository already uses share-safe method") + ) + + sharesourcerequires = localrepo._readrequires( + localrepo._getsharedvfs(repo.vfs, current_requirements), False + ) + if requirementsmod.SHARESAFE_REQUIREMENT not in sharesourcerequires: + raise error.StateError( + _( + b"share source does not support share-safe, unable to upgrade" + ) + ) + + # share source has SHARESAFE requirement present, hence all the + # requirements will be store requires + storerequires = localrepo._readrequires(repo.svfs, False) + + # after upgrade, store requires will be shared, so lets find + # the requirements which are not present in store and + # write them to share's .hg/requires + diffrequires = current_requirements - storerequires + # add share-safe requirement as it will mark the share as share-safe + diffrequires.add(requirementsmod.SHARESAFE_REQUIREMENT) + scmutil.writerequires(repo.vfs, diffrequires) + ui.status(_(b"repository upgraded to use share-safe functionality\n")) + ui.status( + _( + b"requirements and configs of shared-source will be " + b"read from now onwards\n" + ) + ) + else: + if requirementsmod.SHARESAFE_REQUIREMENT not in current_requirements: + raise error.StateError( + _(b"repository does not uses share safe method, nothing to do") + ) + + sharesourcerequires = localrepo._readrequires( + localrepo._getsharedvfs(repo.vfs, current_requirements), False + ) + + if requirementsmod.SHARESAFE_REQUIREMENT in sharesourcerequires: + # we should copy the store requires in .hg/requires and remove + # share-safe requirement + storerequires = localrepo._readrequires(repo.svfs, False) + current_requirements |= storerequires + current_requirements.remove(requirementsmod.SHARESAFE_REQUIREMENT) + scmutil.writerequires(repo.vfs, current_requirements) + ui.status( + _( + b"repository downgraded to not use share-safe functionality\n" + ) + ) + else: + # share source does not use share-safe and has requirements in + # .hg/requires. We cannot be sure which requirement were shared + # earlier in share-safe mode. In other words, there can be wdir + # specific requirements which should not be copied but we have + # no way to detect them + if not opts.get('force'): + raise error.Abort( + _( + b"shared source does not support share-safe " + b"functionality, downgrading may not lead correct result" + ), + hint=_(b"use --force to still downgrade"), + ) + current_requirements |= sharesourcerequires + current_requirements.remove(requirementsmod.SHARESAFE_REQUIREMENT) + scmutil.writerequires(repo.vfs, current_requirements) + ui.status( + _( + b"repository downgraded to not use share-safe functionality\n" + ) + ) + + +@command( b'debugsub', [(b'r', b'rev', b'', _(b'revision to check'), _(b'REV'))], _(b'[-r REV] [REV]'), diff --git a/tests/test-completion.t b/tests/test-completion.t --- a/tests/test-completion.t +++ b/tests/test-completion.t @@ -129,6 +129,7 @@ debugrevspec debugserve debugsetparents + debugsharesafe debugsidedata debugssl debugstrip @@ -318,6 +319,7 @@ debugrevspec: optimize, show-revs, show-set, show-stage, no-optimized, verify-optimized debugserve: sshstdio, logiofd, logiofile debugsetparents: + debugsharesafe: upgrade, downgrade, force debugsidedata: changelog, manifest, dir debugssl: debugstrip: rev, force, no-backup, nobackup, , keep, bookmark, soft diff --git a/tests/test-help.t b/tests/test-help.t --- a/tests/test-help.t +++ b/tests/test-help.t @@ -1068,6 +1068,8 @@ debugserve run a server with advanced settings debugsetparents manually set the parents of the current working directory + debugsharesafe + upgrade or downgrade shares to enable/disable share-safe mode debugsidedata dump the side data for a cl/manifest/file revision debugssl test a secure connection to a server diff --git a/tests/test-share-safe.t b/tests/test-share-safe.t --- a/tests/test-share-safe.t +++ b/tests/test-share-safe.t @@ -70,6 +70,16 @@ $ echo c > c $ hg ci -Aqm "added c" + $ hg debugsharesafe + abort: nothing specified + [10] + $ hg debugsharesafe --upgrade --downgrade + abort: cannot specify both --upgrade and --downgrade + [10] + $ hg debugsharesafe --upgrade + abort: repository already uses share-safe method + [20] + Check that config of the source repository is also loaded $ hg showconfig ui.curses @@ -399,6 +409,26 @@ o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo + $ hg debugsharesafe -R ../nss-share --downgrade + warning: source repository supports share-safe functionality. Reshare to upgrade. + abort: repository does not uses share safe method, nothing to do + [20] + + $ hg debugsharesafe -R ../nss-share --upgrade + warning: source repository supports share-safe functionality. Reshare to upgrade. + repository upgraded to use share-safe functionality + requirements and configs of shared-source will be read from now onwards + + $ hg log -GT "{node}: {desc}\n" -R ../nss-share + @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar + | + o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo + + + $ hg debugsharesafe -R ../nss-share --downgrade + repository downgraded to not use share-safe functionality + + Create a safe share from upgrade one