D4480: exchangev2: start to implement pull with wire protocol v2
indygreg (Gregory Szorc)
phabricator at mercurial-scm.org
Wed Sep 12 17:13:02 UTC 2018
indygreg updated this revision to Diff 10961.
REPOSITORY
rHG Mercurial
CHANGES SINCE LAST UPDATE
https://phab.mercurial-scm.org/D4480?vs=10793&id=10961
REVISION DETAIL
https://phab.mercurial-scm.org/D4480
AFFECTED FILES
mercurial/exchange.py
mercurial/exchangev2.py
mercurial/httppeer.py
tests/test-wireproto-exchangev2.t
tests/wireprotohelpers.sh
CHANGE DETAILS
diff --git a/tests/wireprotohelpers.sh b/tests/wireprotohelpers.sh
--- a/tests/wireprotohelpers.sh
+++ b/tests/wireprotohelpers.sh
@@ -56,3 +56,10 @@
web.api.http-v2 = true
EOF
}
+
+enablehttpv2client() {
+ cat >> $HGRCPATH << EOF
+[experimental]
+httppeer.advertise-v2 = true
+EOF
+}
diff --git a/tests/test-wireproto-exchangev2.t b/tests/test-wireproto-exchangev2.t
new file mode 100644
--- /dev/null
+++ b/tests/test-wireproto-exchangev2.t
@@ -0,0 +1,53 @@
+Tests for wire protocol version 2 exchange.
+Tests in this file should be folded into existing tests once protocol
+v2 has enough features that it can be enabled via #testcase in existing
+tests.
+
+ $ . $TESTDIR/wireprotohelpers.sh
+ $ enablehttpv2client
+
+ $ hg init server-simple
+ $ enablehttpv2 server-simple
+ $ cd server-simple
+ $ cat >> .hg/hgrc << EOF
+ > [phases]
+ > publish = false
+ > EOF
+ $ echo a0 > a
+ $ echo b0 > b
+ $ hg -q commit -A -m 'commit 0'
+
+ $ echo a1 > a
+ $ hg commit -m 'commit 1'
+ $ hg phase --public -r .
+ $ echo a2 > a
+ $ hg commit -m 'commit 2'
+
+ $ hg -q up -r 0
+ $ echo b1 > b
+ $ hg -q commit -m 'head 2 commit 1'
+ $ echo b2 > b
+ $ hg -q commit -m 'head 2 commit 2'
+
+ $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
+ $ cat hg.pid > $DAEMON_PIDS
+
+ $ cd ..
+
+Test basic clone
+
+ $ hg --debug clone -U http://localhost:$HGPORT client-simple
+ using http://localhost:$HGPORT/
+ sending capabilities command
+ query 1; heads
+ sending 2 commands
+ sending command heads: {}
+ sending command known: {
+ 'nodes': []
+ }
+ received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
+ received frame(size=43; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
+ received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
+ received frame(size=11; request=3; stream=2; streamflags=; type=command-response; flags=continuation)
+ received frame(size=1; request=3; stream=2; streamflags=; type=command-response; flags=continuation)
+ received frame(size=0; request=3; stream=2; streamflags=; type=command-response; flags=eos)
diff --git a/mercurial/httppeer.py b/mercurial/httppeer.py
--- a/mercurial/httppeer.py
+++ b/mercurial/httppeer.py
@@ -802,7 +802,8 @@
return True
# Other concepts.
- if name in ('bundle2',):
+ # TODO remove exchangev2 once we have a command implemented.
+ if name in ('bundle2', 'exchangev2'):
return True
# Alias command-* to presence of command of that name.
diff --git a/mercurial/exchangev2.py b/mercurial/exchangev2.py
new file mode 100644
--- /dev/null
+++ b/mercurial/exchangev2.py
@@ -0,0 +1,55 @@
+# exchangev2.py - repository exchange for wire protocol version 2
+#
+# Copyright 2018 Gregory Szorc <gregory.szorc at gmail.com>
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+
+from __future__ import absolute_import
+
+from .node import (
+ nullid,
+)
+from . import (
+ setdiscovery,
+)
+
+def pull(pullop):
+ """Pull using wire protocol version 2."""
+ repo = pullop.repo
+ remote = pullop.remote
+
+ # Figure out what needs to be fetched.
+ common, fetch, remoteheads = _pullchangesetdiscovery(
+ repo, remote, pullop.heads, abortwhenunrelated=pullop.force)
+
+def _pullchangesetdiscovery(repo, remote, heads, abortwhenunrelated=True):
+ """Determine which changesets need to be pulled."""
+
+ if heads:
+ knownnode = repo.changelog.hasnode
+ if all(knownnode(head) for head in heads):
+ return heads, False, heads
+
+ # TODO wire protocol version 2 is capable of more efficient discovery
+ # than setdiscovery. Consider implementing something better.
+ common, fetch, remoteheads = setdiscovery.findcommonheads(
+ repo.ui, repo, remote, abortwhenunrelated=abortwhenunrelated)
+
+ common = set(common)
+ remoteheads = set(remoteheads)
+
+ # If a remote head is filtered locally, put it back in the common set.
+ # See the comment in exchange._pulldiscoverychangegroup() for more.
+
+ if fetch and remoteheads:
+ nodemap = repo.unfiltered().changelog.nodemap
+
+ common |= {head for head in remoteheads if head in nodemap}
+
+ if set(remoteheads).issubset(common):
+ fetch = []
+
+ common.discard(nullid)
+
+ return common, fetch, remoteheads
diff --git a/mercurial/exchange.py b/mercurial/exchange.py
--- a/mercurial/exchange.py
+++ b/mercurial/exchange.py
@@ -26,6 +26,7 @@
changegroup,
discovery,
error,
+ exchangev2,
lock as lockmod,
logexchange,
narrowspec,
@@ -1506,17 +1507,21 @@
pullop.trmanager = transactionmanager(repo, 'pull', remote.url())
with repo.wlock(), repo.lock(), pullop.trmanager:
- # This should ideally be in _pullbundle2(). However, it needs to run
- # before discovery to avoid extra work.
- _maybeapplyclonebundle(pullop)
- streamclone.maybeperformlegacystreamclone(pullop)
- _pulldiscovery(pullop)
- if pullop.canusebundle2:
- _fullpullbundle2(repo, pullop)
- _pullchangeset(pullop)
- _pullphase(pullop)
- _pullbookmarks(pullop)
- _pullobsolete(pullop)
+ # Use the modern wire protocol, if available.
+ if remote.capable('exchangev2'):
+ exchangev2.pull(pullop)
+ else:
+ # This should ideally be in _pullbundle2(). However, it needs to run
+ # before discovery to avoid extra work.
+ _maybeapplyclonebundle(pullop)
+ streamclone.maybeperformlegacystreamclone(pullop)
+ _pulldiscovery(pullop)
+ if pullop.canusebundle2:
+ _fullpullbundle2(repo, pullop)
+ _pullchangeset(pullop)
+ _pullphase(pullop)
+ _pullbookmarks(pullop)
+ _pullobsolete(pullop)
# storing remotenames
if repo.ui.configbool('experimental', 'remotenames'):
To: indygreg, #hg-reviewers
Cc: durin42, mercurial-devel
More information about the Mercurial-devel
mailing list