diff --git a/mercurial/configitems.py b/mercurial/configitems.py --- a/mercurial/configitems.py +++ b/mercurial/configitems.py @@ -1074,6 +1074,11 @@ ) coreconfigitem( b'experimental', + b'sharesafe-auto-upgrade-shares', + default=False, +) +coreconfigitem( + b'experimental', b'single-head-per-branch', default=False, ) diff --git a/mercurial/localrepo.py b/mercurial/localrepo.py --- a/mercurial/localrepo.py +++ b/mercurial/localrepo.py @@ -582,12 +582,19 @@ elif shared: sourcerequires = _readrequires(sharedvfs, False) if requirementsmod.SHARESAFE_REQUIREMENT in sourcerequires: - ui.warn( - _( - b'warning: source repository supports share-safe functionality.' - b' Reshare to upgrade.\n' + if ui.configbool(b'experimental', b'sharesafe-auto-upgrade-shares'): + storerequires = _readrequires(storevfs, False) + requirements = scmutil.upgrade_share_to_safe( + hgvfs, requirements, storerequires ) - ) + ui.warn(_(b'repository upgraded to use share-safe mode\n')) + else: + ui.warn( + _( + b'warning: source repository supports share-safe functionality.' + b' Reshare to upgrade.\n' + ) + ) # The .hg/hgrc file may load extensions or contain config options # that influence repository construction. Attempt to load it and diff --git a/mercurial/scmutil.py b/mercurial/scmutil.py --- a/mercurial/scmutil.py +++ b/mercurial/scmutil.py @@ -1597,6 +1597,22 @@ fp.write(b"%s\n" % r) +def upgrade_share_to_safe(hgvfs, current_requirements, store_requirements): + """Upgrades a share to use share-safe mechanism + + Returns the set of new requirements for the repository + """ + # 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 - store_requirements + # add share-safe requirement as it will mark the share as share-safe + diffrequires.add(requirementsmod.SHARESAFE_REQUIREMENT) + writerequires(hgvfs, diffrequires) + current_requirements.add(requirementsmod.SHARESAFE_REQUIREMENT) + return current_requirements + + class filecachesubentry(object): def __init__(self, path, stat): self.path = path 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 @@ -479,8 +479,53 @@ | o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo - $ hg unshare -R ../nss-share $ hg log -GT "{node}: {desc}\n" -R ../ss-share abort: share source does not support exp-sharesafe requirement [255] + + +Testing automatic upgrade of shares when config is set + + $ hg debugupgraderepo -q --run --config format.exp-share-safe=True + upgrade will perform the following actions: + + requirements + preserved: dotencode, fncache, generaldelta, revlogv1, sparserevlog, store + added: exp-sharesafe + + processed revlogs: + - all-filelogs + - changelog + - manifest + + repository upgraded to share safe mode, existing shares will still work in old non-safe mode. Re-share existing shares to use them in safe mode New shares will be created in safe mode. + $ hg debugrequirements + dotencode + exp-sharesafe + fncache + generaldelta + revlogv1 + sparserevlog + store + $ hg log -GT "{node}: {desc}\n" -R ../nss-share + warning: source repository supports share-safe functionality. Reshare to upgrade. + @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar + | + o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo + + $ hg log -GT "{node}: {desc}\n" -R ../nss-share --config experimental.sharesafe-auto-upgrade-shares=true + repository upgraded to use share-safe mode + @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar + | + o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo + + +Test that unshare works + + $ hg unshare -R ../nss-share + $ hg log -GT "{node}: {desc}\n" -R ../nss-share + @ f63db81e6dde1d9c78814167f77fb1fb49283f4f: added bar + | + o f3ba8b99bb6f897c87bbc1c07b75c6ddf43a4f77: added foo +