##// END OF EJS Templates
exchangev2: start to implement pull with wire protocol v2...
Gregory Szorc -
r39665:a86d21e7 default
parent child Browse files
Show More
@@ -0,0 +1,55 b''
1 # exchangev2.py - repository exchange for wire protocol version 2
2 #
3 # Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com>
4 #
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
7
8 from __future__ import absolute_import
9
10 from .node import (
11 nullid,
12 )
13 from . import (
14 setdiscovery,
15 )
16
17 def pull(pullop):
18 """Pull using wire protocol version 2."""
19 repo = pullop.repo
20 remote = pullop.remote
21
22 # Figure out what needs to be fetched.
23 common, fetch, remoteheads = _pullchangesetdiscovery(
24 repo, remote, pullop.heads, abortwhenunrelated=pullop.force)
25
26 def _pullchangesetdiscovery(repo, remote, heads, abortwhenunrelated=True):
27 """Determine which changesets need to be pulled."""
28
29 if heads:
30 knownnode = repo.changelog.hasnode
31 if all(knownnode(head) for head in heads):
32 return heads, False, heads
33
34 # TODO wire protocol version 2 is capable of more efficient discovery
35 # than setdiscovery. Consider implementing something better.
36 common, fetch, remoteheads = setdiscovery.findcommonheads(
37 repo.ui, repo, remote, abortwhenunrelated=abortwhenunrelated)
38
39 common = set(common)
40 remoteheads = set(remoteheads)
41
42 # If a remote head is filtered locally, put it back in the common set.
43 # See the comment in exchange._pulldiscoverychangegroup() for more.
44
45 if fetch and remoteheads:
46 nodemap = repo.unfiltered().changelog.nodemap
47
48 common |= {head for head in remoteheads if head in nodemap}
49
50 if set(remoteheads).issubset(common):
51 fetch = []
52
53 common.discard(nullid)
54
55 return common, fetch, remoteheads
@@ -0,0 +1,53 b''
1 Tests for wire protocol version 2 exchange.
2 Tests in this file should be folded into existing tests once protocol
3 v2 has enough features that it can be enabled via #testcase in existing
4 tests.
5
6 $ . $TESTDIR/wireprotohelpers.sh
7 $ enablehttpv2client
8
9 $ hg init server-simple
10 $ enablehttpv2 server-simple
11 $ cd server-simple
12 $ cat >> .hg/hgrc << EOF
13 > [phases]
14 > publish = false
15 > EOF
16 $ echo a0 > a
17 $ echo b0 > b
18 $ hg -q commit -A -m 'commit 0'
19
20 $ echo a1 > a
21 $ hg commit -m 'commit 1'
22 $ hg phase --public -r .
23 $ echo a2 > a
24 $ hg commit -m 'commit 2'
25
26 $ hg -q up -r 0
27 $ echo b1 > b
28 $ hg -q commit -m 'head 2 commit 1'
29 $ echo b2 > b
30 $ hg -q commit -m 'head 2 commit 2'
31
32 $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
33 $ cat hg.pid > $DAEMON_PIDS
34
35 $ cd ..
36
37 Test basic clone
38
39 $ hg --debug clone -U http://localhost:$HGPORT client-simple
40 using http://localhost:$HGPORT/
41 sending capabilities command
42 query 1; heads
43 sending 2 commands
44 sending command heads: {}
45 sending command known: {
46 'nodes': []
47 }
48 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
49 received frame(size=43; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
50 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
51 received frame(size=11; request=3; stream=2; streamflags=; type=command-response; flags=continuation)
52 received frame(size=1; request=3; stream=2; streamflags=; type=command-response; flags=continuation)
53 received frame(size=0; request=3; stream=2; streamflags=; type=command-response; flags=eos)
@@ -26,6 +26,7 b' from . import ('
26 26 changegroup,
27 27 discovery,
28 28 error,
29 exchangev2,
29 30 lock as lockmod,
30 31 logexchange,
31 32 narrowspec,
@@ -1506,17 +1507,21 b' def pull(repo, remote, heads=None, force'
1506 1507
1507 1508 pullop.trmanager = transactionmanager(repo, 'pull', remote.url())
1508 1509 with repo.wlock(), repo.lock(), pullop.trmanager:
1509 # This should ideally be in _pullbundle2(). However, it needs to run
1510 # before discovery to avoid extra work.
1511 _maybeapplyclonebundle(pullop)
1512 streamclone.maybeperformlegacystreamclone(pullop)
1513 _pulldiscovery(pullop)
1514 if pullop.canusebundle2:
1515 _fullpullbundle2(repo, pullop)
1516 _pullchangeset(pullop)
1517 _pullphase(pullop)
1518 _pullbookmarks(pullop)
1519 _pullobsolete(pullop)
1510 # Use the modern wire protocol, if available.
1511 if remote.capable('exchangev2'):
1512 exchangev2.pull(pullop)
1513 else:
1514 # This should ideally be in _pullbundle2(). However, it needs to run
1515 # before discovery to avoid extra work.
1516 _maybeapplyclonebundle(pullop)
1517 streamclone.maybeperformlegacystreamclone(pullop)
1518 _pulldiscovery(pullop)
1519 if pullop.canusebundle2:
1520 _fullpullbundle2(repo, pullop)
1521 _pullchangeset(pullop)
1522 _pullphase(pullop)
1523 _pullbookmarks(pullop)
1524 _pullobsolete(pullop)
1520 1525
1521 1526 # storing remotenames
1522 1527 if repo.ui.configbool('experimental', 'remotenames'):
@@ -802,7 +802,8 b' class httpv2peer(object):'
802 802 return True
803 803
804 804 # Other concepts.
805 if name in ('bundle2',):
805 # TODO remove exchangev2 once we have a command implemented.
806 if name in ('bundle2', 'exchangev2'):
806 807 return True
807 808
808 809 # Alias command-* to presence of command of that name.
@@ -56,3 +56,10 b' web.apiserver = true'
56 56 web.api.http-v2 = true
57 57 EOF
58 58 }
59
60 enablehttpv2client() {
61 cat >> $HGRCPATH << EOF
62 [experimental]
63 httppeer.advertise-v2 = true
64 EOF
65 }
General Comments 0
You need to be logged in to leave comments. Login now