diff --git a/mercurial/configitems.py b/mercurial/configitems.py --- a/mercurial/configitems.py +++ b/mercurial/configitems.py @@ -1098,21 +1098,6 @@ ) coreconfigitem( b'experimental', - b'sharesafe-auto-downgrade-shares', - default=False, -) -coreconfigitem( - b'experimental', - b'sharesafe-auto-upgrade-shares', - default=False, -) -coreconfigitem( - b'experimental', - b'sharesafe-auto-upgrade-fail-error', - default=False, -) -coreconfigitem( - b'experimental', b'sharesafe-warn-outdated-shares', default=True, ) @@ -1926,6 +1911,11 @@ default=b'identity', ) coreconfigitem( + b'share', + b'source-safe-mismatch', + default=b'abort', +) +coreconfigitem( b'shelve', b'maxbackups', default=10, diff --git a/mercurial/helptext/config.txt b/mercurial/helptext/config.txt --- a/mercurial/helptext/config.txt +++ b/mercurial/helptext/config.txt @@ -1932,6 +1932,21 @@ Currently, only the rebase and absorb commands consider this configuration. (EXPERIMENTAL) +``share`` +--------- + +``source-safe-mismatch`` + + Control what happens when there is a mismatch between share-safe feature + presence with share source in a share. + Possible values are `abort` (default), `allow`, `upgrade-abort` and + `upgrade-abort`. + `abort`: Disallows running any command and aborts + `allow`: Respects the feature presence in share source + `upgrade-abort`: tries to upgrade the share, if it fails aborts + `upgrade-allow`: tries to upgrade the share, if it fails continue by + respecting the share source setting + ``storage`` ----------- diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -568,6 +568,7 @@ # repository was shared the old way. We check the share source .hg/requires # for SHARESAFE_REQUIREMENT to detect whether the current repository needs # to be reshared + mismatch_config = ui.config(b'share', b'source-safe-mismatch') if requirementsmod.SHARESAFE_REQUIREMENT in requirements: if ( @@ -575,8 +576,10 @@ and requirementsmod.SHARESAFE_REQUIREMENT not in _readrequires(sharedvfs, True) ): - if ui.configbool( - b'experimental', b'sharesafe-auto-downgrade-shares' + if mismatch_config in ( + b'upgrade-allow', + b'allow', + b'upgrade-abort', ): # prevent cyclic import localrepo -> upgrade -> localrepo from . import upgrade @@ -586,19 +589,33 @@ hgvfs, sharedvfs, requirements, + mismatch_config, ) - else: + elif mismatch_config == b'abort': raise error.Abort( _( b"share source does not support exp-sharesafe requirement" ) ) + else: + hint = _("run `hg help config.share.source-safe-mismatch`") + raise error.Abort( + _( + b"share-safe mismatch with source.\nUnrecognized" + b" value '%s 'of `share.source-safe-mismatch` set." + ) % mismatch_config, + hint=hint + ) else: requirements |= _readrequires(storevfs, False) elif shared: sourcerequires = _readrequires(sharedvfs, False) if requirementsmod.SHARESAFE_REQUIREMENT in sourcerequires: - if ui.configbool(b'experimental', b'sharesafe-auto-upgrade-shares'): + if mismatch_config in ( + b'upgrade-allow', + b'allow', + b'upgrade-abort', + ): # prevent cyclic import localrepo -> upgrade -> localrepo from . import upgrade @@ -607,14 +624,24 @@ hgvfs, storevfs, requirements, + mismatch_config, ) - else: + elif mismatch_config == b'abort': raise error.Abort( _( b'version mismatch: source uses share-safe' b' functionality while current share does not' ) ) + else: + hint = _("run `hg help config.share.source-safe-mismatch`") + raise error.Abort( + _( + b"share-safe mismatch with source.\nUnrecognized" + b" value '%s' of `share.source-safe-mismatch` set." + ) % mismatch_config, + hint=hint + ) # The .hg/hgrc file may load extensions or contain config options # that influence repository construction. Attempt to load it and diff --git a/mercurial/upgrade.py b/mercurial/upgrade.py --- a/mercurial/upgrade.py +++ b/mercurial/upgrade.py @@ -241,7 +241,9 @@ upgrade_op.print_post_op_messages() -def upgrade_share_to_safe(ui, hgvfs, storevfs, current_requirements): +def upgrade_share_to_safe( + ui, hgvfs, storevfs, current_requirements, mismatch_config +): """Upgrades a share to use share-safe mechanism""" wlock = None store_requirements = localrepo._readrequires(storevfs, False) @@ -252,6 +254,10 @@ # add share-safe requirement as it will mark the share as share-safe diffrequires.add(requirementsmod.SHARESAFE_REQUIREMENT) current_requirements.add(requirementsmod.SHARESAFE_REQUIREMENT) + # in `allow` case, we don't try to upgrade, we just respect the source + # state, update requirements and continue + if mismatch_config == b'allow': + return try: wlock = lockmod.trylock(ui, hgvfs, b'wlock', 0, 0) # some process might change the requirement in between, re-read @@ -270,7 +276,7 @@ scmutil.writerequires(hgvfs, diffrequires) ui.warn(_(b'repository upgraded to use share-safe mode\n')) except error.LockError as e: - if ui.configbool(b'experimental', b'sharesafe-auto-upgrade-fail-error'): + if mismatch_config == b'upgrade-abort': raise error.Abort( _(b'failed to upgrade share, got error: %s') % stringutil.forcebytestr(e.strerror) @@ -290,6 +296,7 @@ hgvfs, sharedvfs, current_requirements, + mismatch_config, ): """Downgrades a share which use share-safe to not use it""" wlock = None @@ -300,6 +307,8 @@ source_requirements -= requirementsmod.WORKING_DIR_REQUIREMENTS current_requirements |= source_requirements current_requirements.remove(requirementsmod.SHARESAFE_REQUIREMENT) + if mismatch_config == b'allow': + return try: wlock = lockmod.trylock(ui, hgvfs, b'wlock', 0, 0) @@ -317,12 +326,13 @@ scmutil.writerequires(hgvfs, current_requirements) ui.warn(_(b'repository downgraded to not use share-safe mode\n')) except error.LockError as e: - # raise error right away because if downgrade failed, we cannot load - # the repository because it does not have complete set of requirements - raise error.Abort( - _(b'failed to downgrade share, got error: %s') - % stringutil.forcebytestr(e.strerror) - ) + # If upgrade-abort is set, abort when upgrade fails, else let the + # process continue as `upgrade-allow` is set + if mismatch_config == b'upgrade-abort': + raise error.Abort( + _(b'failed to downgrade share, got error: %s') + % stringutil.forcebytestr(e.strerror) + ) finally: if wlock: wlock.release() 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 @@ -395,7 +395,7 @@ Make sure existing shares dont work with default config $ hg log -GT "{node}: {desc}\n" -R ../nss-share - abort: version mismatch: source use share-safe functionality while current share does not + abort: version mismatch: source uses share-safe functionality while current share does not [255] @@ -486,12 +486,12 @@ Testing automatic downgrade of shares when config is set $ touch ../ss-share/.hg/wlock - $ hg log -GT "{node}: {desc}\n" -R ../ss-share --config experimental.sharesafe-auto-downgrade-shares=true + $ hg log -GT "{node}: {desc}\n" -R ../ss-share --config share.source-safe-mismatch=upgrade-abort abort: failed to downgrade share, got error: Lock held [255] $ rm ../ss-share/.hg/wlock - $ hg log -GT "{node}: {desc}\n" -R ../ss-share --config experimental.sharesafe-auto-downgrade-shares=true + $ hg log -GT "{node}: {desc}\n" -R ../ss-share --config share.source-safe-mismatch=upgrade-abort repository downgraded to not use share-safe mode @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar | @@ -529,30 +529,35 @@ sparserevlog store $ hg log -GT "{node}: {desc}\n" -R ../nss-share - abort: version mismatch: source use share-safe functionality while current share does not + abort: version mismatch: source uses share-safe functionality while current share does not [255] Check that if lock is taken, upgrade fails but read operation are successful + $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.source-safe-mismatch=upgra + abort: share-safe mismatch with source. + Unrecognized value 'upgra' of `share.source-safe-mismatch` set. + (run `hg help config.share.source-safe-mismatch`) + [255] $ touch ../nss-share/.hg/wlock - $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config experimental.sharesafe-auto-upgrade-shares=true + $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.source-safe-mismatch=upgrade-allow failed to upgrade share, got error: Lock held @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar | o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo - $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config experimental.sharesafe-auto-upgrade-shares=true --config experimental.sharesafe-warn-outdated-shares=false + $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.source-safe-mismatch=upgrade-allow --config experimental.sharesafe-warn-outdated-shares=false @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar | o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo - $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config experimental.sharesafe-auto-upgrade-shares=true --config experimental.sharesafe-auto-upgrade-fail-error=true + $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.source-safe-mismatch=upgrade-abort abort: failed to upgrade share, got error: Lock held [255] $ rm ../nss-share/.hg/wlock - $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config experimental.sharesafe-auto-upgrade-shares=true + $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.source-safe-mismatch=upgrade-abort repository upgraded to use share-safe mode @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar |