annotate mercurial/wireproto.py @ 12296:d7fff529d85d

clone: only use stream when we understand the revlog format This patch fixes issues with stream cloning in the presense of parentdelta, lwcopy and similar additions that change the interpretation of the revlog format, or the format itself. Currently, the stream capability is sent like this: stream=<version of changelog> But the client doesn't actually check the version number; also, it only checks the changelog and it doesn't capture the interpretation-changes and flag-changes in parentdelta and lwcopy. This patch removes the 'stream' capability whenever we use a non-basic revlog format, to prevent old clients from receiving incorrect data. In those cases, a new capability called 'streamreqs' is added instead. Instead of a revlog version, it comes with a list of revlog-format relevant requirements, which are a subset of the repository requirements, excluding things that are not relevant for stream. New clients use this to determine whether or not they can stream. Old clients only look for the 'stream' capability, as always. New servers will still send this when serving old repositories.
author Sune Foldager <cryo@cyanite.org>
date Wed, 15 Sep 2010 11:06:22 +0200
parents 6f833fc3ccab
children 6a6149487817
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
1 # wireproto.py - generic wire protocol support functions
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
2 #
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
3 # Copyright 2005-2010 Matt Mackall <mpm@selenic.com>
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
4 #
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
5 # This software may be used and distributed according to the terms of the
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
6 # GNU General Public License version 2 or any later version.
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
7
11879
4e804302d30c fix undefined variables, spotted by pylint
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11627
diff changeset
8 import urllib, tempfile, os, sys
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
9 from i18n import _
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
10 from node import bin, hex
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
11 import changegroup as changegroupmod
11627
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
12 import repo, error, encoding, util, store
12085
6f833fc3ccab Consistently import foo as foomod when foo to avoid shadowing
Martin Geisler <mg@aragost.com>
parents: 12063
diff changeset
13 import pushkey as pushkeymod
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
14
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
15 # list of nodes encoding / decoding
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
16
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
17 def decodelist(l, sep=' '):
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
18 return map(bin, l.split(sep))
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
19
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
20 def encodelist(l, sep=' '):
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
21 return sep.join(map(hex, l))
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
22
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
23 # client side
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
24
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
25 class wirerepository(repo.repository):
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
26 def lookup(self, key):
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
27 self.requirecap('lookup', _('look up remote revision'))
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
28 d = self._call("lookup", key=key)
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
29 success, data = d[:-1].split(" ", 1)
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
30 if int(success):
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
31 return bin(data)
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
32 self._abort(error.RepoError(data))
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
33
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
34 def heads(self):
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
35 d = self._call("heads")
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
36 try:
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
37 return decodelist(d[:-1])
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
38 except:
11879
4e804302d30c fix undefined variables, spotted by pylint
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11627
diff changeset
39 self._abort(error.ResponseError(_("unexpected response:"), d))
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
40
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
41 def branchmap(self):
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
42 d = self._call("branchmap")
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
43 try:
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
44 branchmap = {}
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
45 for branchpart in d.splitlines():
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
46 branchname, branchheads = branchpart.split(' ', 1)
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
47 branchname = urllib.unquote(branchname)
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
48 # Earlier servers (1.3.x) send branch names in (their) local
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
49 # charset. The best we can do is assume it's identical to our
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
50 # own local charset, in case it's not utf-8.
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
51 try:
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
52 branchname.decode('utf-8')
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
53 except UnicodeDecodeError:
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
54 branchname = encoding.fromlocal(branchname)
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
55 branchheads = decodelist(branchheads)
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
56 branchmap[branchname] = branchheads
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
57 return branchmap
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
58 except TypeError:
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
59 self._abort(error.ResponseError(_("unexpected response:"), d))
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
60
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
61 def branches(self, nodes):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
62 n = encodelist(nodes)
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
63 d = self._call("branches", nodes=n)
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
64 try:
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
65 br = [tuple(decodelist(b)) for b in d.splitlines()]
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
66 return br
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
67 except:
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
68 self._abort(error.ResponseError(_("unexpected response:"), d))
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
69
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
70 def between(self, pairs):
11587
a036f6bd1da3 protocol: unify basic http client requests
Matt Mackall <mpm@selenic.com>
parents: 11586
diff changeset
71 batch = 8 # avoid giant requests
a036f6bd1da3 protocol: unify basic http client requests
Matt Mackall <mpm@selenic.com>
parents: 11586
diff changeset
72 r = []
a036f6bd1da3 protocol: unify basic http client requests
Matt Mackall <mpm@selenic.com>
parents: 11586
diff changeset
73 for i in xrange(0, len(pairs), batch):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
74 n = " ".join([encodelist(p, '-') for p in pairs[i:i + batch]])
11587
a036f6bd1da3 protocol: unify basic http client requests
Matt Mackall <mpm@selenic.com>
parents: 11586
diff changeset
75 d = self._call("between", pairs=n)
a036f6bd1da3 protocol: unify basic http client requests
Matt Mackall <mpm@selenic.com>
parents: 11586
diff changeset
76 try:
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
77 r.extend(l and decodelist(l) or [] for l in d.splitlines())
11587
a036f6bd1da3 protocol: unify basic http client requests
Matt Mackall <mpm@selenic.com>
parents: 11586
diff changeset
78 except:
a036f6bd1da3 protocol: unify basic http client requests
Matt Mackall <mpm@selenic.com>
parents: 11586
diff changeset
79 self._abort(error.ResponseError(_("unexpected response:"), d))
a036f6bd1da3 protocol: unify basic http client requests
Matt Mackall <mpm@selenic.com>
parents: 11586
diff changeset
80 return r
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
81
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
82 def pushkey(self, namespace, key, old, new):
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
83 if not self.capable('pushkey'):
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
84 return False
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
85 d = self._call("pushkey",
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
86 namespace=namespace, key=key, old=old, new=new)
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
87 return bool(int(d))
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
88
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
89 def listkeys(self, namespace):
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
90 if not self.capable('pushkey'):
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
91 return {}
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
92 d = self._call("listkeys", namespace=namespace)
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
93 r = {}
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
94 for l in d.splitlines():
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
95 k, v = l.split('\t')
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
96 r[k.decode('string-escape')] = v.decode('string-escape')
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
97 return r
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
98
11588
8a1f625e971d protocol: unify stream_out client code
Matt Mackall <mpm@selenic.com>
parents: 11587
diff changeset
99 def stream_out(self):
8a1f625e971d protocol: unify stream_out client code
Matt Mackall <mpm@selenic.com>
parents: 11587
diff changeset
100 return self._callstream('stream_out')
8a1f625e971d protocol: unify stream_out client code
Matt Mackall <mpm@selenic.com>
parents: 11587
diff changeset
101
11591
0d9cb3f3b0a1 protocol: unify client changegroup methods
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
102 def changegroup(self, nodes, kind):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
103 n = encodelist(nodes)
11591
0d9cb3f3b0a1 protocol: unify client changegroup methods
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
104 f = self._callstream("changegroup", roots=n)
0d9cb3f3b0a1 protocol: unify client changegroup methods
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
105 return self._decompress(f)
0d9cb3f3b0a1 protocol: unify client changegroup methods
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
106
0d9cb3f3b0a1 protocol: unify client changegroup methods
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
107 def changegroupsubset(self, bases, heads, kind):
0d9cb3f3b0a1 protocol: unify client changegroup methods
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
108 self.requirecap('changegroupsubset', _('look up remote changes'))
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
109 bases = encodelist(bases)
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
110 heads = encodelist(heads)
11591
0d9cb3f3b0a1 protocol: unify client changegroup methods
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
111 return self._decompress(self._callstream("changegroupsubset",
0d9cb3f3b0a1 protocol: unify client changegroup methods
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
112 bases=bases, heads=heads))
0d9cb3f3b0a1 protocol: unify client changegroup methods
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
113
11592
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
114 def unbundle(self, cg, heads, source):
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
115 '''Send cg (a readable file-like object representing the
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
116 changegroup to push, typically a chunkbuffer object) to the
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
117 remote server as a bundle. Return an integer indicating the
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
118 result of the push (see localrepository.addchangegroup()).'''
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
119
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
120 ret, output = self._callpush("unbundle", cg, heads=encodelist(heads))
11592
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
121 if ret == "":
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
122 raise error.ResponseError(
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
123 _('push failed:'), output)
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
124 try:
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
125 ret = int(ret)
12063
516b000fbb7e cleanup: remove unused variables
Brodie Rao <brodie@bitheap.org>
parents: 12042
diff changeset
126 except ValueError:
11592
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
127 raise error.ResponseError(
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
128 _('push failed (unexpected response):'), ret)
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
129
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
130 for l in output.splitlines(True):
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
131 self.ui.status(_('remote: '), l)
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
132 return ret
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
133
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
134 # server side
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
135
11625
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
136 class streamres(object):
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
137 def __init__(self, gen):
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
138 self.gen = gen
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
139
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
140 class pushres(object):
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
141 def __init__(self, res):
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
142 self.res = res
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
143
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
144 def dispatch(repo, proto, command):
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
145 func, spec = commands[command]
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
146 args = proto.getargs(spec)
11625
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
147 return func(repo, proto, *args)
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
148
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
149 def between(repo, proto, pairs):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
150 pairs = [decodelist(p, '-') for p in pairs.split(" ")]
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
151 r = []
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
152 for b in repo.between(pairs):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
153 r.append(encodelist(b) + "\n")
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
154 return "".join(r)
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
155
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
156 def branchmap(repo, proto):
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
157 branchmap = repo.branchmap()
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
158 heads = []
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
159 for branch, nodes in branchmap.iteritems():
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
160 branchname = urllib.quote(branch)
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
161 branchnodes = encodelist(nodes)
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
162 heads.append('%s %s' % (branchname, branchnodes))
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
163 return '\n'.join(heads)
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
164
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
165 def branches(repo, proto, nodes):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
166 nodes = decodelist(nodes)
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
167 r = []
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
168 for b in repo.branches(nodes):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
169 r.append(encodelist(b) + "\n")
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
170 return "".join(r)
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
171
11594
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
172 def capabilities(repo, proto):
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
173 caps = 'lookup changegroupsubset branchmap pushkey'.split()
11627
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
174 if _allowstream(repo.ui):
12296
d7fff529d85d clone: only use stream when we understand the revlog format
Sune Foldager <cryo@cyanite.org>
parents: 12085
diff changeset
175 requiredformats = repo.requirements & repo.supportedformats
d7fff529d85d clone: only use stream when we understand the revlog format
Sune Foldager <cryo@cyanite.org>
parents: 12085
diff changeset
176 # if our local revlogs are just revlogv1, add 'stream' cap
d7fff529d85d clone: only use stream when we understand the revlog format
Sune Foldager <cryo@cyanite.org>
parents: 12085
diff changeset
177 if not requiredformats - set(('revlogv1',)):
d7fff529d85d clone: only use stream when we understand the revlog format
Sune Foldager <cryo@cyanite.org>
parents: 12085
diff changeset
178 caps.append('stream')
d7fff529d85d clone: only use stream when we understand the revlog format
Sune Foldager <cryo@cyanite.org>
parents: 12085
diff changeset
179 # otherwise, add 'streamreqs' detailing our local revlog format
d7fff529d85d clone: only use stream when we understand the revlog format
Sune Foldager <cryo@cyanite.org>
parents: 12085
diff changeset
180 else:
d7fff529d85d clone: only use stream when we understand the revlog format
Sune Foldager <cryo@cyanite.org>
parents: 12085
diff changeset
181 caps.append('streamreqs=%s' % ','.join(requiredformats))
11594
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
182 caps.append('unbundle=%s' % ','.join(changegroupmod.bundlepriority))
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
183 return ' '.join(caps)
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
184
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
185 def changegroup(repo, proto, roots):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
186 nodes = decodelist(roots)
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
187 cg = repo.changegroup(nodes, 'serve')
11625
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
188 return streamres(proto.groupchunks(cg))
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
189
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
190 def changegroupsubset(repo, proto, bases, heads):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
191 bases = decodelist(bases)
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
192 heads = decodelist(heads)
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
193 cg = repo.changegroupsubset(bases, heads, 'serve')
11625
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
194 return streamres(proto.groupchunks(cg))
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
195
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
196 def heads(repo, proto):
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
197 h = repo.heads()
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
198 return encodelist(h) + "\n"
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
199
11594
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
200 def hello(repo, proto):
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
201 '''the hello command returns a set of lines describing various
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
202 interesting things about the server, in an RFC822-like format.
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
203 Currently the only one defined is "capabilities", which
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
204 consists of a line in the form:
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
205
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
206 capabilities: space separated list of tokens
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
207 '''
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
208 return "capabilities: %s\n" % (capabilities(repo, proto))
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
209
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
210 def listkeys(repo, proto, namespace):
12085
6f833fc3ccab Consistently import foo as foomod when foo to avoid shadowing
Martin Geisler <mg@aragost.com>
parents: 12063
diff changeset
211 d = pushkeymod.list(repo, namespace).items()
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
212 t = '\n'.join(['%s\t%s' % (k.encode('string-escape'),
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
213 v.encode('string-escape')) for k, v in d])
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
214 return t
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
215
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
216 def lookup(repo, proto, key):
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
217 try:
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
218 r = hex(repo.lookup(key))
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
219 success = 1
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
220 except Exception, inst:
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
221 r = str(inst)
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
222 success = 0
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
223 return "%s %s\n" % (success, r)
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
224
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
225 def pushkey(repo, proto, namespace, key, old, new):
12085
6f833fc3ccab Consistently import foo as foomod when foo to avoid shadowing
Martin Geisler <mg@aragost.com>
parents: 12063
diff changeset
226 r = pushkeymod.push(repo, namespace, key, old, new)
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
227 return '%s\n' % int(r)
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
228
11627
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
229 def _allowstream(ui):
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
230 return ui.configbool('server', 'uncompressed', True, untrusted=True)
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
231
11585
5d907fbb9703 protocol: unify stream_out command
Matt Mackall <mpm@selenic.com>
parents: 11584
diff changeset
232 def stream(repo, proto):
11627
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
233 '''If the server supports streaming clone, it advertises the "stream"
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
234 capability with a value representing the version and flags of the repo
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
235 it is serving. Client checks to see if it understands the format.
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
236
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
237 The format is simple: the server writes out a line with the amount
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
238 of files, then the total amount of bytes to be transfered (separated
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
239 by a space). Then, for each file, the server first writes the filename
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
240 and filesize (separated by the null character), then the file contents.
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
241 '''
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
242
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
243 if not _allowstream(repo.ui):
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
244 return '1\n'
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
245
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
246 entries = []
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
247 total_bytes = 0
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
248 try:
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
249 # get consistent snapshot of repo, lock during scan
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
250 lock = repo.lock()
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
251 try:
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
252 repo.ui.debug('scanning\n')
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
253 for name, ename, size in repo.store.walk():
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
254 entries.append((name, size))
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
255 total_bytes += size
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
256 finally:
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
257 lock.release()
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
258 except error.LockError:
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
259 return '2\n' # error: 2
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
260
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
261 def streamer(repo, entries, total):
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
262 '''stream out all metadata files in repository.'''
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
263 yield '0\n' # success
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
264 repo.ui.debug('%d files, %d bytes to transfer\n' %
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
265 (len(entries), total_bytes))
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
266 yield '%d %d\n' % (len(entries), total_bytes)
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
267 for name, size in entries:
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
268 repo.ui.debug('sending %s (%d bytes)\n' % (name, size))
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
269 # partially encode name over the wire for backwards compat
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
270 yield '%s\0%d\n' % (store.encodedir(name), size)
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
271 for chunk in util.filechunkiter(repo.sopener(name), limit=size):
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
272 yield chunk
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
273
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
274 return streamres(streamer(repo, entries, total_bytes))
11585
5d907fbb9703 protocol: unify stream_out command
Matt Mackall <mpm@selenic.com>
parents: 11584
diff changeset
275
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
276 def unbundle(repo, proto, heads):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
277 their_heads = decodelist(heads)
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
278
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
279 def check_heads():
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
280 heads = repo.heads()
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
281 return their_heads == ['force'] or their_heads == heads
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
282
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
283 # fail early if possible
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
284 if not check_heads():
11620
86b49e0083a7 protocol: do not translate error messages on the remote side
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11619
diff changeset
285 return 'unsynced changes'
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
286
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
287 # write bundle data to temporary file because it can be big
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
288 fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-')
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
289 fp = os.fdopen(fd, 'wb+')
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
290 r = 0
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
291 proto.redirect()
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
292 try:
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
293 proto.getfile(fp)
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
294 lock = repo.lock()
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
295 try:
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
296 if not check_heads():
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
297 # someone else committed/pushed/unbundled while we
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
298 # were transferring data
11620
86b49e0083a7 protocol: do not translate error messages on the remote side
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11619
diff changeset
299 return 'unsynced changes'
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
300
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
301 # push can proceed
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
302 fp.seek(0)
12042
210049a8d16e bundle: unify/refactor unbundle/readbundle
Matt Mackall <mpm@selenic.com>
parents: 11879
diff changeset
303 gen = changegroupmod.readbundle(fp, None)
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
304
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
305 try:
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
306 r = repo.addchangegroup(gen, 'serve', proto._client(),
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
307 lock=lock)
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
308 except util.Abort, inst:
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
309 sys.stderr.write("abort: %s\n" % inst)
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
310 finally:
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
311 lock.release()
11625
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
312 return pushres(r)
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
313
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
314 finally:
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
315 fp.close()
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
316 os.unlink(tempname)
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
317
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
318 commands = {
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
319 'between': (between, 'pairs'),
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
320 'branchmap': (branchmap, ''),
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
321 'branches': (branches, 'nodes'),
11594
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
322 'capabilities': (capabilities, ''),
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
323 'changegroup': (changegroup, 'roots'),
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
324 'changegroupsubset': (changegroupsubset, 'bases heads'),
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
325 'heads': (heads, ''),
11594
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
326 'hello': (hello, ''),
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
327 'listkeys': (listkeys, 'namespace'),
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
328 'lookup': (lookup, 'key'),
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
329 'pushkey': (pushkey, 'namespace key old new'),
11585
5d907fbb9703 protocol: unify stream_out command
Matt Mackall <mpm@selenic.com>
parents: 11584
diff changeset
330 'stream_out': (stream, ''),
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
331 'unbundle': (unbundle, 'heads'),
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
332 }