Config introduced in previous patch was share.source-safe-mismatch. Let's
rename the warn as share.source-safe-mismatch.warn.
While we are here, made sure we have different configs for upgrade and
downgrade.
marmoute | |
mharbison72 |
hg-reviewers |
Config introduced in previous patch was share.source-safe-mismatch. Let's
rename the warn as share.source-safe-mismatch.warn.
While we are here, made sure we have different configs for upgrade and
downgrade.
No Linters Available |
No Unit Test Coverage |
That one looks good. Can we get a patch documenting these option and the share safe behavior above that series ?
Same as before, we will have two different option as one case (probably upgrade) migh be expected within an organization but not the other.
This looks good, thanks.
Maybe point to the warn config from the doc of the behavior ones ? Or maybe better, sort the section by alphabetical order so that the warn option directly follow the respective behavior one.
Path | Packages | |||
---|---|---|---|---|
M | mercurial/configitems.py (10 lines) | |||
M | mercurial/helptext/config.txt (5 lines) | |||
M | mercurial/localrepo.py (3 lines) | |||
M | mercurial/upgrade.py (15 lines) | |||
M | tests/test-share-safe.t (2 lines) |
Commit | Parents | Author | Summary | Date |
---|---|---|---|---|
e1bd784bfc65 | 3cd77184d087 | Pulkit Goyal | Jan 15 2021, 1:38 AM |
) | ) | ||||
coreconfigitem( | coreconfigitem( | ||||
b'experimental', | b'experimental', | ||||
b'server.stream-narrow-clones', | b'server.stream-narrow-clones', | ||||
default=False, | default=False, | ||||
) | ) | ||||
coreconfigitem( | coreconfigitem( | ||||
b'experimental', | b'experimental', | ||||
b'sharesafe-warn-outdated-shares', | |||||
default=True, | |||||
) | |||||
coreconfigitem( | |||||
b'experimental', | |||||
b'single-head-per-branch', | b'single-head-per-branch', | ||||
default=False, | default=False, | ||||
) | ) | ||||
coreconfigitem( | coreconfigitem( | ||||
b'experimental', | b'experimental', | ||||
b'single-head-per-branch:account-closed-heads', | b'single-head-per-branch:account-closed-heads', | ||||
default=False, | default=False, | ||||
) | ) | ||||
default=b'identity', | default=b'identity', | ||||
) | ) | ||||
coreconfigitem( | coreconfigitem( | ||||
b'share', | b'share', | ||||
b'source-safe-mismatch', | b'source-safe-mismatch', | ||||
default=b'abort', | default=b'abort', | ||||
) | ) | ||||
coreconfigitem( | coreconfigitem( | ||||
b'share', | |||||
b'source-safe-mismatch.warn', | |||||
default=True, | |||||
) | |||||
coreconfigitem( | |||||
b'shelve', | b'shelve', | ||||
b'maxbackups', | b'maxbackups', | ||||
default=10, | default=10, | ||||
) | ) | ||||
coreconfigitem( | coreconfigitem( | ||||
b'smtp', | b'smtp', | ||||
b'host', | b'host', | ||||
default=None, | default=None, |
Possible values are `abort` (default), `allow`, `upgrade-abort` and | Possible values are `abort` (default), `allow`, `upgrade-abort` and | ||||
`upgrade-abort`. | `upgrade-abort`. | ||||
`abort`: Disallows running any command and aborts | `abort`: Disallows running any command and aborts | ||||
`allow`: Respects the feature presence in share source | `allow`: Respects the feature presence in share source | ||||
`upgrade-abort`: tries to upgrade the share, if it fails aborts | `upgrade-abort`: tries to upgrade the share, if it fails aborts | ||||
`upgrade-allow`: tries to upgrade the share, if it fails continue by | `upgrade-allow`: tries to upgrade the share, if it fails continue by | ||||
respecting the share source setting | respecting the share source setting | ||||
``source-safe-mismatch.warn`` | |||||
Shows warning when upgrade fails and `upgrade-allow` is set. | |||||
(default: True) | |||||
``storage`` | ``storage`` | ||||
----------- | ----------- | ||||
Control the strategy Mercurial uses internally to store history. Options in this | Control the strategy Mercurial uses internally to store history. Options in this | ||||
category impact performance and repository size. | category impact performance and repository size. | ||||
``revlog.optimize-delta-parent-choice`` | ``revlog.optimize-delta-parent-choice`` | ||||
When storing a merge revision, both parents will be equally considered as | When storing a merge revision, both parents will be equally considered as |
# is present. We never write SHARESAFE_REQUIREMENT for a repo if store | # is present. We never write SHARESAFE_REQUIREMENT for a repo if store | ||||
# is not present, refer checkrequirementscompat() for that | # is not present, refer checkrequirementscompat() for that | ||||
# | # | ||||
# However, if SHARESAFE_REQUIREMENT is not present, it means that the | # However, if SHARESAFE_REQUIREMENT is not present, it means that the | ||||
# repository was shared the old way. We check the share source .hg/requires | # repository was shared the old way. We check the share source .hg/requires | ||||
# for SHARESAFE_REQUIREMENT to detect whether the current repository needs | # for SHARESAFE_REQUIREMENT to detect whether the current repository needs | ||||
# to be reshared | # to be reshared | ||||
mismatch_config = ui.config(b'share', b'source-safe-mismatch') | mismatch_config = ui.config(b'share', b'source-safe-mismatch') | ||||
mismatch_warn = ui.configbool(b'share', b'source-safe-mismatch.warn') | |||||
if requirementsmod.SHARESAFE_REQUIREMENT in requirements: | if requirementsmod.SHARESAFE_REQUIREMENT in requirements: | ||||
if ( | if ( | ||||
shared | shared | ||||
and requirementsmod.SHARESAFE_REQUIREMENT | and requirementsmod.SHARESAFE_REQUIREMENT | ||||
not in _readrequires(sharedvfs, True) | not in _readrequires(sharedvfs, True) | ||||
): | ): | ||||
if mismatch_config in ( | if mismatch_config in ( | ||||
b'upgrade-allow', | b'upgrade-allow', | ||||
b'allow', | b'allow', | ||||
b'upgrade-abort', | b'upgrade-abort', | ||||
): | ): | ||||
# prevent cyclic import localrepo -> upgrade -> localrepo | # prevent cyclic import localrepo -> upgrade -> localrepo | ||||
from . import upgrade | from . import upgrade | ||||
upgrade.downgrade_share_to_non_safe( | upgrade.downgrade_share_to_non_safe( | ||||
ui, | ui, | ||||
hgvfs, | hgvfs, | ||||
sharedvfs, | sharedvfs, | ||||
requirements, | requirements, | ||||
mismatch_config, | mismatch_config, | ||||
mismatch_warn, | |||||
) | ) | ||||
elif mismatch_config == b'abort': | elif mismatch_config == b'abort': | ||||
raise error.Abort( | raise error.Abort( | ||||
_( | _( | ||||
b"share source does not support exp-sharesafe requirement" | b"share source does not support exp-sharesafe requirement" | ||||
) | ) | ||||
) | ) | ||||
else: | else: | ||||
from . import upgrade | from . import upgrade | ||||
upgrade.upgrade_share_to_safe( | upgrade.upgrade_share_to_safe( | ||||
ui, | ui, | ||||
hgvfs, | hgvfs, | ||||
storevfs, | storevfs, | ||||
requirements, | requirements, | ||||
mismatch_config, | mismatch_config, | ||||
mismatch_warn, | |||||
) | ) | ||||
elif mismatch_config == b'abort': | elif mismatch_config == b'abort': | ||||
raise error.Abort( | raise error.Abort( | ||||
_( | _( | ||||
b'version mismatch: source uses share-safe' | b'version mismatch: source uses share-safe' | ||||
b' functionality while current share does not' | b' functionality while current share does not' | ||||
) | ) | ||||
) | ) |
b'repository is verified\n' | b'repository is verified\n' | ||||
) | ) | ||||
) | ) | ||||
upgrade_op.print_post_op_messages() | upgrade_op.print_post_op_messages() | ||||
def upgrade_share_to_safe( | def upgrade_share_to_safe( | ||||
ui, hgvfs, storevfs, current_requirements, mismatch_config | ui, | ||||
hgvfs, | |||||
storevfs, | |||||
current_requirements, | |||||
mismatch_config, | |||||
mismatch_warn, | |||||
): | ): | ||||
"""Upgrades a share to use share-safe mechanism""" | """Upgrades a share to use share-safe mechanism""" | ||||
wlock = None | wlock = None | ||||
store_requirements = localrepo._readrequires(storevfs, False) | store_requirements = localrepo._readrequires(storevfs, False) | ||||
# after upgrade, store requires will be shared, so lets find | # after upgrade, store requires will be shared, so lets find | ||||
# the requirements which are not present in store and | # the requirements which are not present in store and | ||||
# write them to share's .hg/requires | # write them to share's .hg/requires | ||||
diffrequires = current_requirements - store_requirements | diffrequires = current_requirements - store_requirements | ||||
scmutil.writerequires(hgvfs, diffrequires) | scmutil.writerequires(hgvfs, diffrequires) | ||||
ui.warn(_(b'repository upgraded to use share-safe mode\n')) | ui.warn(_(b'repository upgraded to use share-safe mode\n')) | ||||
except error.LockError as e: | except error.LockError as e: | ||||
if mismatch_config == b'upgrade-abort': | if mismatch_config == b'upgrade-abort': | ||||
raise error.Abort( | raise error.Abort( | ||||
_(b'failed to upgrade share, got error: %s') | _(b'failed to upgrade share, got error: %s') | ||||
% stringutil.forcebytestr(e.strerror) | % stringutil.forcebytestr(e.strerror) | ||||
) | ) | ||||
elif ui.configbool(b'experimental', b'sharesafe-warn-outdated-shares'): | elif mismatch_warn: | ||||
ui.warn( | ui.warn( | ||||
_(b'failed to upgrade share, got error: %s\n') | _(b'failed to upgrade share, got error: %s\n') | ||||
% stringutil.forcebytestr(e.strerror) | % stringutil.forcebytestr(e.strerror) | ||||
) | ) | ||||
finally: | finally: | ||||
if wlock: | if wlock: | ||||
wlock.release() | wlock.release() | ||||
def downgrade_share_to_non_safe( | def downgrade_share_to_non_safe( | ||||
ui, | ui, | ||||
hgvfs, | hgvfs, | ||||
sharedvfs, | sharedvfs, | ||||
current_requirements, | current_requirements, | ||||
mismatch_config, | mismatch_config, | ||||
mismatch_warn, | |||||
): | ): | ||||
"""Downgrades a share which use share-safe to not use it""" | """Downgrades a share which use share-safe to not use it""" | ||||
wlock = None | wlock = None | ||||
source_requirements = localrepo._readrequires(sharedvfs, True) | source_requirements = localrepo._readrequires(sharedvfs, True) | ||||
# we cannot be 100% sure on which requirements were present in store when | # we cannot be 100% sure on which requirements were present in store when | ||||
# the source supported share-safe. However, we do know that working | # the source supported share-safe. However, we do know that working | ||||
# directory requirements were not there. Hence we remove them | # directory requirements were not there. Hence we remove them | ||||
source_requirements -= requirementsmod.WORKING_DIR_REQUIREMENTS | source_requirements -= requirementsmod.WORKING_DIR_REQUIREMENTS | ||||
except error.LockError as e: | except error.LockError as e: | ||||
# If upgrade-abort is set, abort when upgrade fails, else let the | # If upgrade-abort is set, abort when upgrade fails, else let the | ||||
# process continue as `upgrade-allow` is set | # process continue as `upgrade-allow` is set | ||||
if mismatch_config == b'upgrade-abort': | if mismatch_config == b'upgrade-abort': | ||||
raise error.Abort( | raise error.Abort( | ||||
_(b'failed to downgrade share, got error: %s') | _(b'failed to downgrade share, got error: %s') | ||||
% stringutil.forcebytestr(e.strerror) | % stringutil.forcebytestr(e.strerror) | ||||
) | ) | ||||
elif mismatch_warn: | |||||
ui.warn( | |||||
_(b'failed to downgrade share, got error: %s\n') | |||||
% stringutil.forcebytestr(e.strerror) | |||||
) | |||||
finally: | finally: | ||||
if wlock: | if wlock: | ||||
wlock.release() | wlock.release() |
$ touch ../nss-share/.hg/wlock | $ touch ../nss-share/.hg/wlock | ||||
$ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.source-safe-mismatch=upgrade-allow | $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.source-safe-mismatch=upgrade-allow | ||||
failed to upgrade share, got error: Lock held | failed to upgrade share, got error: Lock held | ||||
@ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar | @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar | ||||
| | | | ||||
o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo | o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo | ||||
$ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.source-safe-mismatch=upgrade-allow --config experimental.sharesafe-warn-outdated-shares=false | $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.source-safe-mismatch=upgrade-allow --config share.source-safe-mismatch.warn=False | ||||
@ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar | @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar | ||||
| | | | ||||
o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo | o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo | ||||
$ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.source-safe-mismatch=upgrade-abort | $ 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 | abort: failed to upgrade share, got error: Lock held | ||||
[255] | [255] |