D11982: stream-clone: only consider store requirements
marmoute (Pierre-Yves David)
phabricator at mercurial-scm.org
Wed Jan 12 14:11:35 UTC 2022
marmoute created this revision.
Herald added a reviewer: hg-reviewers.
Herald added a subscriber: mercurial-patches.
REVISION SUMMARY
They are different kind of requirements, the one which impact the store and are
relevant to the files being streamed and the one which does not. For example
some requirements are only relevant to the working copy, like sparse, or
dirstate-v2.
Since they are irrelevant to the content being streamed, they should not
prevent the receiving side to use streaming clone. So we no longer advertise
them over the wire.
In addition, the client side can decide to use whichever format it desire for
the part that does not affect the store itself. So the configuration related to
these format are not used when doing a streaming clone.
REPOSITORY
rHG Mercurial
BRANCH
default
REVISION DETAIL
https://phab.mercurial-scm.org/D11982
AFFECTED FILES
mercurial/bundle2.py
mercurial/streamclone.py
mercurial/wireprotov1server.py
tests/test-clone-stream.t
CHANGE DETAILS
diff --git a/tests/test-clone-stream.t b/tests/test-clone-stream.t
--- a/tests/test-clone-stream.t
+++ b/tests/test-clone-stream.t
@@ -905,3 +905,52 @@
$ killdaemons.py
#endif
+
+Stream clone regarding non-store format variant
+-----------------------------------------------
+
+ $ cat << EOF >> $HGRCPATH
+ > [storage]
+ > dirstate-v2.slow-path=allow
+ > EOF
+
+
+We can add dirstate-v2 when cloning (or any other non-store format change actually)
+
+ $ hg init server-no-dirstate-v2 --config format.exp-rc-dirstate-v2=no
+ $ hg debugbuilddag .+5 -R server-no-dirstate-v2
+ $ hg serve -p $HGPORT -d --pid-file=hg.pid -R server-no-dirstate-v2
+ $ cat hg.pid > $DAEMON_PIDS
+ $ hg debugcapabilities http://localhost:$HGPORT | grep streamreqs
+ streamreqs=generaldelta,revlogv1,sparserevlog (no-rust !)
+ streamreqs=generaldelta,persistent-nodemap,revlogv1,sparserevlog (rust !)
+ $ hg clone --quiet -U --stream --config format.exp-rc-dirstate-v2=yes http://localhost:$HGPORT clone-added-d2
+ $ hg debugrequirement -R server-no-dirstate-v2 | grep dirstate-v2
+ [1]
+ $ hg debugformat -R server-no-dirstate-v2 | grep dirstate-v2
+ dirstate-v2: no
+ $ hg debugrequirement -R clone-added-d2 | grep dirstate-v2
+ dirstate-v2
+ $ hg debugformat -R clone-added-d2 | grep dirstate-v2
+ dirstate-v2: yes
+ $ killdaemons.py
+
+We can drop it when cloning too.
+
+ $ hg init server-dirstate-v2 --config format.exp-rc-dirstate-v2=yes
+ $ hg debugbuilddag .+5 -R server-dirstate-v2
+ $ hg serve -p $HGPORT -d --pid-file=hg.pid -R server-dirstate-v2
+ $ cat hg.pid > $DAEMON_PIDS
+ $ hg debugcapabilities http://localhost:$HGPORT | grep streamreqs
+ streamreqs=generaldelta,revlogv1,sparserevlog (no-rust !)
+ streamreqs=generaldelta,persistent-nodemap,revlogv1,sparserevlog (rust !)
+ $ hg clone --quiet -U --stream --config format.exp-rc-dirstate-v2=no http://localhost:$HGPORT clone-dropped-d2
+ $ hg debugrequirement -R server-dirstate-v2 | grep dirstate-v2
+ dirstate-v2
+ $ hg debugformat -R server-dirstate-v2 | grep dirstate-v2
+ dirstate-v2: yes
+ $ hg debugrequirement -R clone-dropped-d2 | grep dirstate-v2
+ [1]
+ $ hg debugformat -R clone-dropped-d2 | grep dirstate-v2
+ dirstate-v2: no
+ $ killdaemons.py
diff --git a/mercurial/wireprotov1server.py b/mercurial/wireprotov1server.py
--- a/mercurial/wireprotov1server.py
+++ b/mercurial/wireprotov1server.py
@@ -301,6 +301,7 @@
if repo.ui.configbool(b'server', b'preferuncompressed'):
caps.append(b'stream-preferred')
requiredformats = repo.requirements & repo.supportedformats
+ requiredformats -= requirementsmod.WORKING_DIR_REQUIREMENTS
# if our local revlogs are just revlogv1, add 'stream' cap
if not requiredformats - {requirementsmod.REVLOGV1_REQUIREMENT}:
caps.append(b'stream')
diff --git a/mercurial/streamclone.py b/mercurial/streamclone.py
--- a/mercurial/streamclone.py
+++ b/mercurial/streamclone.py
@@ -184,13 +184,13 @@
with repo.lock():
consumev1(repo, fp, filecount, bytecount)
-
- # new requirements = old non-format requirements +
- # new format-related remote requirements
- # requirements from the streamed-in repository
- repo.requirements = requirements | (
- repo.requirements - repo.supportedformats
- )
+ # new requirements = old non-(store)-format requirements +
+ # new (store) format-related remote requirements
+ kept_requirements = set(repo.requirements)
+ kept_requirements -= repo.supportedformats
+ wc_req = requirementsmod.WORKING_DIR_REQUIREMENTS
+ kept_requirements |= repo.requirements & wc_req
+ repo.requirements = kept_requirements | set(requirements)
repo.svfs.options = localrepo.resolvestorevfsoptions(
repo.ui, repo.requirements, repo.features
)
@@ -334,6 +334,7 @@
raise ValueError(b'we do not support the compression argument yet')
requirements = repo.requirements & repo.supportedformats
+ requirements -= requirementsmod.WORKING_DIR_REQUIREMENTS
requires = b','.join(sorted(requirements))
def gen():
@@ -797,12 +798,14 @@
consumev2(repo, fp, filecount, filesize)
- # new requirements = old non-format requirements +
- # new format-related remote requirements
+ # new requirements = old non-(store)-format requirements +
+ # new (store) format-related remote requirements
# requirements from the streamed-in repository
- repo.requirements = set(requirements) | (
- repo.requirements - repo.supportedformats
- )
+ kept_requirements = set(repo.requirements)
+ kept_requirements -= repo.supportedformats
+ wc_req = requirementsmod.WORKING_DIR_REQUIREMENTS
+ kept_requirements |= repo.requirements & wc_req
+ repo.requirements = kept_requirements | set(requirements)
repo.svfs.options = localrepo.resolvestorevfsoptions(
repo.ui, repo.requirements, repo.features
)
diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py
--- a/mercurial/bundle2.py
+++ b/mercurial/bundle2.py
@@ -1804,9 +1804,11 @@
bundler.newpart(b'cache:rev-branch-cache', data=generate(), mandatory=False)
-def _formatrequirementsspec(requirements):
- requirements = [req for req in requirements if req != b"shared"]
- return urlreq.quote(b','.join(sorted(requirements)))
+def _formatrequirementsspec(requs):
+ requs = [
+ req for req in requs if req not in requirements.WORKING_DIR_REQUIREMENTS
+ ]
+ return urlreq.quote(b','.join(sorted(requs)))
def _formatrequirementsparams(requirements):
To: marmoute, #hg-reviewers
Cc: mercurial-patches, mercurial-devel
More information about the Mercurial-devel
mailing list