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.
Automatic diff as part of commit; lint not applicable. |
Automatic diff as part of commit; unit tests not applicable. |
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 (15 lines) | |||
M | mercurial/helptext/config.txt (10 lines) | |||
M | mercurial/localrepo.py (8 lines) | |||
M | mercurial/upgrade.py (15 lines) | |||
M | tests/test-share-safe.t (2 lines) |
) | ) | ||||
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'abort', | default=b'abort', | ||||
) | ) | ||||
coreconfigitem( | coreconfigitem( | ||||
b'share', | b'share', | ||||
b'safe-mismatch.source-safe', | b'safe-mismatch.source-safe', | ||||
default=b'abort', | default=b'abort', | ||||
) | ) | ||||
coreconfigitem( | coreconfigitem( | ||||
b'share', | |||||
b'safe-mismatch.source-not-safe.warn', | |||||
default=True, | |||||
) | |||||
coreconfigitem( | |||||
b'share', | |||||
b'safe-mismatch.source-safe.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, |
`allow`: Respects the feature presence in the share source | `allow`: Respects the feature presence in the share source | ||||
`downgrade-abort`: tries to downgrade the share to not use share-safe; | `downgrade-abort`: tries to downgrade the share to not use share-safe; | ||||
if it fails, aborts | if it fails, aborts | ||||
`downgrade-allow`: tries to downgrade the share to not use share-safe; | `downgrade-allow`: tries to downgrade the share to not use share-safe; | ||||
if it fails, continue by respecting the shared | if it fails, continue by respecting the shared | ||||
source setting | source setting | ||||
``safe-mismatch.source-safe.warn`` | |||||
Shows a warning on operations if the shared repository does not use | |||||
share-safe, but the source repository does. | |||||
(default: True) | |||||
``safe-mismatch.source-not-safe.warn`` | |||||
Shows a warning on operations if the shared repository uses share-safe, | |||||
but the source repository does not. | |||||
(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 |
# to be reshared | # to be reshared | ||||
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) | ||||
): | ): | ||||
mismatch_warn = ui.configbool( | |||||
b'share', b'safe-mismatch.source-not-safe.warn' | |||||
) | |||||
mismatch_config = ui.config( | mismatch_config = ui.config( | ||||
b'share', b'safe-mismatch.source-not-safe' | b'share', b'safe-mismatch.source-not-safe' | ||||
) | ) | ||||
if mismatch_config in ( | if mismatch_config in ( | ||||
b'downgrade-allow', | b'downgrade-allow', | ||||
b'allow', | b'allow', | ||||
b'downgrade-abort', | b'downgrade-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: | ||||
hint=hint, | hint=hint, | ||||
) | ) | ||||
else: | else: | ||||
requirements |= _readrequires(storevfs, False) | requirements |= _readrequires(storevfs, False) | ||||
elif shared: | elif shared: | ||||
sourcerequires = _readrequires(sharedvfs, False) | sourcerequires = _readrequires(sharedvfs, False) | ||||
if requirementsmod.SHARESAFE_REQUIREMENT in sourcerequires: | if requirementsmod.SHARESAFE_REQUIREMENT in sourcerequires: | ||||
mismatch_config = ui.config(b'share', b'safe-mismatch.source-safe') | mismatch_config = ui.config(b'share', b'safe-mismatch.source-safe') | ||||
mismatch_warn = ui.configbool( | |||||
b'share', b'safe-mismatch.source-safe.warn' | |||||
) | |||||
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.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 the current share does not' | b' functionality while the 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) | ||||
original_crequirements = current_requirements.copy() | original_crequirements = current_requirements.copy() | ||||
# 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 | ||||
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) | ||||
original_crequirements = current_requirements.copy() | original_crequirements = current_requirements.copy() | ||||
# 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 | ||||
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'downgrade-abort': | if mismatch_config == b'downgrade-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.safe-mismatch.source-safe=upgrade-allow | $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.safe-mismatch.source-safe=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.safe-mismatch.source-safe=upgrade-allow --config experimental.sharesafe-warn-outdated-shares=false | $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.safe-mismatch.source-safe=upgrade-allow --config share.safe-mismatch.source-safe.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.safe-mismatch.source-safe=upgrade-abort | $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config share.safe-mismatch.source-safe=upgrade-abort | ||||
abort: failed to upgrade share, got error: Lock held | abort: failed to upgrade share, got error: Lock held | ||||
[255] | [255] |