annotate mercurial/wireproto.py @ 17644:9ae073f10572

histedit: fold in memory Update the folding code to works in memory instead of applying patches on the working directory. This is cleaner, faster and prepare the removal of the whole patching logic. This new collapse function will probably move into core sooner or later. A lot of other rewriting operation may benefit from it.
author Pierre-Yves David <pierre-yves.david@logilab.fr>
date Fri, 21 Sep 2012 19:24:31 +0200
parents a7fa5bd1c914
children 8474be4412ca
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
17192
1ac628cd7113 peer: introduce real peer classes
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 16683
diff changeset
12 import peer, error, encoding, util, store
17205
97eff00046de repo: move visibleheads and visiblebranchmap logic in discovery
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17192
diff changeset
13 import discovery, phases
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
14
14621
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
15 # abstract batching support
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
16
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
17 class future(object):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
18 '''placeholder for a value to be set later'''
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
19 def set(self, value):
14970
592e45b7d43e wireproto: use safehasattr or getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14623
diff changeset
20 if util.safehasattr(self, 'value'):
14621
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
21 raise error.RepoError("future is already set")
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
22 self.value = value
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
23
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
24 class batcher(object):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
25 '''base class for batches of commands submittable in a single request
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
26
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16535
diff changeset
27 All methods invoked on instances of this class are simply queued and
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16535
diff changeset
28 return a a future for the result. Once you call submit(), all the queued
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16535
diff changeset
29 calls are performed and the results set in their respective futures.
14621
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
30 '''
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
31 def __init__(self):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
32 self.calls = []
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
33 def __getattr__(self, name):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
34 def call(*args, **opts):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
35 resref = future()
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
36 self.calls.append((name, args, opts, resref,))
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
37 return resref
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
38 return call
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
39 def submit(self):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
40 pass
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
41
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
42 class localbatch(batcher):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
43 '''performs the queued calls directly'''
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
44 def __init__(self, local):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
45 batcher.__init__(self)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
46 self.local = local
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
47 def submit(self):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
48 for name, args, opts, resref in self.calls:
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
49 resref.set(getattr(self.local, name)(*args, **opts))
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
50
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
51 class remotebatch(batcher):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
52 '''batches the queued calls; uses as few roundtrips as possible'''
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
53 def __init__(self, remote):
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16535
diff changeset
54 '''remote must support _submitbatch(encbatch) and
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16535
diff changeset
55 _submitone(op, encargs)'''
14621
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
56 batcher.__init__(self)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
57 self.remote = remote
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
58 def submit(self):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
59 req, rsp = [], []
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
60 for name, args, opts, resref in self.calls:
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
61 mtd = getattr(self.remote, name)
14970
592e45b7d43e wireproto: use safehasattr or getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14623
diff changeset
62 batchablefn = getattr(mtd, 'batchable', None)
592e45b7d43e wireproto: use safehasattr or getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14623
diff changeset
63 if batchablefn is not None:
592e45b7d43e wireproto: use safehasattr or getattr instead of hasattr
Augie Fackler <durin42@gmail.com>
parents: 14623
diff changeset
64 batchable = batchablefn(mtd.im_self, *args, **opts)
14621
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
65 encargsorres, encresref = batchable.next()
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
66 if encresref:
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
67 req.append((name, encargsorres,))
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
68 rsp.append((batchable, encresref, resref,))
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
69 else:
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
70 resref.set(encargsorres)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
71 else:
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
72 if req:
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
73 self._submitreq(req, rsp)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
74 req, rsp = [], []
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
75 resref.set(mtd(*args, **opts))
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
76 if req:
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
77 self._submitreq(req, rsp)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
78 def _submitreq(self, req, rsp):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
79 encresults = self.remote._submitbatch(req)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
80 for encres, r in zip(encresults, rsp):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
81 batchable, encresref, resref = r
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
82 encresref.set(encres)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
83 resref.set(batchable.next())
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
84
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
85 def batchable(f):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
86 '''annotation for batchable methods
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
87
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
88 Such methods must implement a coroutine as follows:
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
89
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
90 @batchable
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
91 def sample(self, one, two=None):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
92 # Handle locally computable results first:
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
93 if not one:
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
94 yield "a local result", None
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
95 # Build list of encoded arguments suitable for your wire protocol:
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
96 encargs = [('one', encode(one),), ('two', encode(two),)]
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
97 # Create future for injection of encoded result:
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
98 encresref = future()
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
99 # Return encoded arguments and future:
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
100 yield encargs, encresref
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16535
diff changeset
101 # Assuming the future to be filled with the result from the batched
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16535
diff changeset
102 # request now. Decode it:
14621
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
103 yield decode(encresref.value)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
104
16683
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16535
diff changeset
105 The decorator returns a function which wraps this coroutine as a plain
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16535
diff changeset
106 method, but adds the original method as an attribute called "batchable",
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16535
diff changeset
107 which is used by remotebatch to split the call into separate encoding and
525fdb738975 cleanup: eradicate long lines
Brodie Rao <brodie@sf.io>
parents: 16535
diff changeset
108 decoding phases.
14621
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
109 '''
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
110 def plain(*args, **opts):
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
111 batchable = f(*args, **opts)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
112 encargsorres, encresref = batchable.next()
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
113 if not encresref:
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
114 return encargsorres # a local result in this case
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
115 self = args[0]
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
116 encresref.set(self._submitone(f.func_name, encargsorres))
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
117 return batchable.next()
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
118 setattr(plain, 'batchable', f)
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
119 return plain
84094c0d2724 wireproto: add basic command batching infrastructure
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14436
diff changeset
120
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
121 # list of nodes encoding / decoding
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
122
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
123 def decodelist(l, sep=' '):
13722
f4a85acef50c wireproto: fix decodelist to properly return empty list
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13721
diff changeset
124 if l:
f4a85acef50c wireproto: fix decodelist to properly return empty list
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13721
diff changeset
125 return map(bin, l.split(sep))
f4a85acef50c wireproto: fix decodelist to properly return empty list
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13721
diff changeset
126 return []
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
127
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
128 def encodelist(l, sep=' '):
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
129 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
130
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
131 # batched call argument encoding
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
132
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
133 def escapearg(plain):
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
134 return (plain
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
135 .replace(':', '::')
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
136 .replace(',', ':,')
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
137 .replace(';', ':;')
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
138 .replace('=', ':='))
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
139
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
140 def unescapearg(escaped):
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
141 return (escaped
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
142 .replace(':=', '=')
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
143 .replace(':;', ';')
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
144 .replace(':,', ',')
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
145 .replace('::', ':'))
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
146
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
147 # client side
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
148
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
149 def todict(**args):
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
150 return args
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
151
17192
1ac628cd7113 peer: introduce real peer classes
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 16683
diff changeset
152 class wirepeer(peer.peerrepository):
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
153
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
154 def batch(self):
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
155 return remotebatch(self)
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
156 def _submitbatch(self, req):
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
157 cmds = []
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
158 for op, argsdict in req:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
159 args = ','.join('%s=%s' % p for p in argsdict.iteritems())
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
160 cmds.append('%s %s' % (op, args))
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
161 rsp = self._call("batch", cmds=';'.join(cmds))
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
162 return rsp.split(';')
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
163 def _submitone(self, op, args):
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
164 return self._call(op, **args)
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
165
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
166 @batchable
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
167 def lookup(self, key):
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
168 self.requirecap('lookup', _('look up remote revision'))
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
169 f = future()
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
170 yield todict(key=encoding.fromlocal(key)), f
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
171 d = f.value
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
172 success, data = d[:-1].split(" ", 1)
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
173 if int(success):
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
174 yield bin(data)
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
175 self._abort(error.RepoError(data))
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
176
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
177 @batchable
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
178 def heads(self):
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
179 f = future()
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
180 yield {}, f
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
181 d = f.value
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
182 try:
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
183 yield decodelist(d[:-1])
13726
378522bdc059 wireproto: avoid naked excepts
Matt Mackall <mpm@selenic.com>
parents: 13723
diff changeset
184 except ValueError:
11879
4e804302d30c fix undefined variables, spotted by pylint
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11627
diff changeset
185 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
186
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
187 @batchable
13723
e615765fdcc7 wireproto: add known([id]) function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13722
diff changeset
188 def known(self, nodes):
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
189 f = future()
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
190 yield todict(nodes=encodelist(nodes)), f
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
191 d = f.value
13723
e615765fdcc7 wireproto: add known([id]) function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13722
diff changeset
192 try:
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
193 yield [bool(int(f)) for f in d]
13726
378522bdc059 wireproto: avoid naked excepts
Matt Mackall <mpm@selenic.com>
parents: 13723
diff changeset
194 except ValueError:
13723
e615765fdcc7 wireproto: add known([id]) function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13722
diff changeset
195 self._abort(error.ResponseError(_("unexpected response:"), d))
e615765fdcc7 wireproto: add known([id]) function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13722
diff changeset
196
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
197 @batchable
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
198 def branchmap(self):
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
199 f = future()
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
200 yield {}, f
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
201 d = f.value
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
202 try:
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
203 branchmap = {}
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
204 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
205 branchname, branchheads = branchpart.split(' ', 1)
13047
6c375e07d673 branch: operate on branch names in local string space where possible
Matt Mackall <mpm@selenic.com>
parents: 12703
diff changeset
206 branchname = encoding.tolocal(urllib.unquote(branchname))
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
207 branchheads = decodelist(branchheads)
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
208 branchmap[branchname] = branchheads
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
209 yield branchmap
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
210 except TypeError:
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
211 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
212
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
213 def branches(self, nodes):
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
214 n = encodelist(nodes)
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
215 d = self._call("branches", nodes=n)
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
216 try:
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
217 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
218 return br
13726
378522bdc059 wireproto: avoid naked excepts
Matt Mackall <mpm@selenic.com>
parents: 13723
diff changeset
219 except ValueError:
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
220 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
221
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
222 def between(self, pairs):
11587
a036f6bd1da3 protocol: unify basic http client requests
Matt Mackall <mpm@selenic.com>
parents: 11586
diff changeset
223 batch = 8 # avoid giant requests
a036f6bd1da3 protocol: unify basic http client requests
Matt Mackall <mpm@selenic.com>
parents: 11586
diff changeset
224 r = []
a036f6bd1da3 protocol: unify basic http client requests
Matt Mackall <mpm@selenic.com>
parents: 11586
diff changeset
225 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
226 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
227 d = self._call("between", pairs=n)
a036f6bd1da3 protocol: unify basic http client requests
Matt Mackall <mpm@selenic.com>
parents: 11586
diff changeset
228 try:
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
229 r.extend(l and decodelist(l) or [] for l in d.splitlines())
13726
378522bdc059 wireproto: avoid naked excepts
Matt Mackall <mpm@selenic.com>
parents: 13723
diff changeset
230 except ValueError:
11587
a036f6bd1da3 protocol: unify basic http client requests
Matt Mackall <mpm@selenic.com>
parents: 11586
diff changeset
231 self._abort(error.ResponseError(_("unexpected response:"), d))
a036f6bd1da3 protocol: unify basic http client requests
Matt Mackall <mpm@selenic.com>
parents: 11586
diff changeset
232 return r
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
233
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
234 @batchable
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
235 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
236 if not self.capable('pushkey'):
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
237 yield False, None
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
238 f = future()
17293
d3f84ccc5495 pushkey: add more verbose debug output regarding pushkey
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17205
diff changeset
239 self.ui.debug('preparing pushkey for "%s:%s"\n' % (namespace, key))
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
240 yield todict(namespace=encoding.fromlocal(namespace),
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
241 key=encoding.fromlocal(key),
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
242 old=encoding.fromlocal(old),
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
243 new=encoding.fromlocal(new)), f
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
244 d = f.value
15652
ca6accdad79c wireproto: handle other server output in pushkey
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15585
diff changeset
245 d, output = d.split('\n', 1)
13450
b3f9af7c22c5 wireproto: catch possible cast error in pushkey
David Soria Parra <dsp@php.net>
parents: 13050
diff changeset
246 try:
b3f9af7c22c5 wireproto: catch possible cast error in pushkey
David Soria Parra <dsp@php.net>
parents: 13050
diff changeset
247 d = bool(int(d))
b3f9af7c22c5 wireproto: catch possible cast error in pushkey
David Soria Parra <dsp@php.net>
parents: 13050
diff changeset
248 except ValueError:
b3f9af7c22c5 wireproto: catch possible cast error in pushkey
David Soria Parra <dsp@php.net>
parents: 13050
diff changeset
249 raise error.ResponseError(
b3f9af7c22c5 wireproto: catch possible cast error in pushkey
David Soria Parra <dsp@php.net>
parents: 13050
diff changeset
250 _('push failed (unexpected response):'), d)
15652
ca6accdad79c wireproto: handle other server output in pushkey
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15585
diff changeset
251 for l in output.splitlines(True):
ca6accdad79c wireproto: handle other server output in pushkey
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 15585
diff changeset
252 self.ui.status(_('remote: '), l)
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
253 yield d
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
254
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
255 @batchable
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
256 def listkeys(self, namespace):
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
257 if not self.capable('pushkey'):
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
258 yield {}, None
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
259 f = future()
17293
d3f84ccc5495 pushkey: add more verbose debug output regarding pushkey
Pierre-Yves David <pierre-yves.david@logilab.fr>
parents: 17205
diff changeset
260 self.ui.debug('preparing listkeys for "%s"\n' % namespace)
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
261 yield todict(namespace=encoding.fromlocal(namespace)), f
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
262 d = f.value
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
263 r = {}
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
264 for l in d.splitlines():
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
265 k, v = l.split('\t')
13050
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
266 r[encoding.tolocal(k)] = encoding.tolocal(v)
14623
e7c9fdbbb902 wireproto: make a number of commands batchable
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14622
diff changeset
267 yield r
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
268
11588
8a1f625e971d protocol: unify stream_out client code
Matt Mackall <mpm@selenic.com>
parents: 11587
diff changeset
269 def stream_out(self):
8a1f625e971d protocol: unify stream_out client code
Matt Mackall <mpm@selenic.com>
parents: 11587
diff changeset
270 return self._callstream('stream_out')
8a1f625e971d protocol: unify stream_out client code
Matt Mackall <mpm@selenic.com>
parents: 11587
diff changeset
271
11591
0d9cb3f3b0a1 protocol: unify client changegroup methods
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
272 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
273 n = encodelist(nodes)
11591
0d9cb3f3b0a1 protocol: unify client changegroup methods
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
274 f = self._callstream("changegroup", roots=n)
12337
6a6149487817 bundle: encapsulate all bundle streams in unbundle class
Matt Mackall <mpm@selenic.com>
parents: 12296
diff changeset
275 return changegroupmod.unbundle10(self._decompress(f), 'UN')
11591
0d9cb3f3b0a1 protocol: unify client changegroup methods
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
276
0d9cb3f3b0a1 protocol: unify client changegroup methods
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
277 def changegroupsubset(self, bases, heads, kind):
0d9cb3f3b0a1 protocol: unify client changegroup methods
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
278 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
279 bases = encodelist(bases)
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
280 heads = encodelist(heads)
12337
6a6149487817 bundle: encapsulate all bundle streams in unbundle class
Matt Mackall <mpm@selenic.com>
parents: 12296
diff changeset
281 f = self._callstream("changegroupsubset",
6a6149487817 bundle: encapsulate all bundle streams in unbundle class
Matt Mackall <mpm@selenic.com>
parents: 12296
diff changeset
282 bases=bases, heads=heads)
6a6149487817 bundle: encapsulate all bundle streams in unbundle class
Matt Mackall <mpm@selenic.com>
parents: 12296
diff changeset
283 return changegroupmod.unbundle10(self._decompress(f), 'UN')
11591
0d9cb3f3b0a1 protocol: unify client changegroup methods
Matt Mackall <mpm@selenic.com>
parents: 11588
diff changeset
284
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
285 def getbundle(self, source, heads=None, common=None):
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
286 self.requirecap('getbundle', _('look up remote changes'))
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
287 opts = {}
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
288 if heads is not None:
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
289 opts['heads'] = encodelist(heads)
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
290 if common is not None:
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
291 opts['common'] = encodelist(common)
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
292 f = self._callstream("getbundle", **opts)
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
293 return changegroupmod.unbundle10(self._decompress(f), 'UN')
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
294
11592
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
295 def unbundle(self, cg, heads, source):
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
296 '''Send cg (a readable file-like object representing the
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
297 changegroup to push, typically a chunkbuffer object) to the
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
298 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
299 result of the push (see localrepository.addchangegroup()).'''
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
300
14419
ede7cea1550f wireproto: do not hash when heads == ['force']
Martin Geisler <mg@aragost.com>
parents: 14093
diff changeset
301 if heads != ['force'] and self.capable('unbundlehash'):
13942
88f0e41d8802 wireproto: allow unbundle with hashed heads parameter (issue2126)
Shuhei Takahashi <takahashi.shuhei@gmail.com>
parents: 13741
diff changeset
302 heads = encodelist(['hashed',
88f0e41d8802 wireproto: allow unbundle with hashed heads parameter (issue2126)
Shuhei Takahashi <takahashi.shuhei@gmail.com>
parents: 13741
diff changeset
303 util.sha1(''.join(sorted(heads))).digest()])
88f0e41d8802 wireproto: allow unbundle with hashed heads parameter (issue2126)
Shuhei Takahashi <takahashi.shuhei@gmail.com>
parents: 13741
diff changeset
304 else:
88f0e41d8802 wireproto: allow unbundle with hashed heads parameter (issue2126)
Shuhei Takahashi <takahashi.shuhei@gmail.com>
parents: 13741
diff changeset
305 heads = encodelist(heads)
88f0e41d8802 wireproto: allow unbundle with hashed heads parameter (issue2126)
Shuhei Takahashi <takahashi.shuhei@gmail.com>
parents: 13741
diff changeset
306
88f0e41d8802 wireproto: allow unbundle with hashed heads parameter (issue2126)
Shuhei Takahashi <takahashi.shuhei@gmail.com>
parents: 13741
diff changeset
307 ret, output = self._callpush("unbundle", cg, heads=heads)
11592
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
308 if ret == "":
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
309 raise error.ResponseError(
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
310 _('push failed:'), output)
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
311 try:
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
312 ret = int(ret)
12063
516b000fbb7e cleanup: remove unused variables
Brodie Rao <brodie@bitheap.org>
parents: 12042
diff changeset
313 except ValueError:
11592
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
314 raise error.ResponseError(
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
315 _('push failed (unexpected response):'), ret)
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
316
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
317 for l in output.splitlines(True):
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
318 self.ui.status(_('remote: '), l)
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
319 return ret
26e0782b8380 protocol: unify client unbundle support
Matt Mackall <mpm@selenic.com>
parents: 11591
diff changeset
320
14048
58e58406ed19 wireproto: add test for new optional arg missing on server
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13942
diff changeset
321 def debugwireargs(self, one, two, three=None, four=None, five=None):
13720
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
322 # don't pass optional arguments left at their default value
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
323 opts = {}
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
324 if three is not None:
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
325 opts['three'] = three
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
326 if four is not None:
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
327 opts['four'] = four
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
328 return self._call('debugwireargs', one=one, two=two, **opts)
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
329
11586
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
330 # server side
ddaaaa23bb8f protocol: move basic ssh client commands to wirerepository
Matt Mackall <mpm@selenic.com>
parents: 11585
diff changeset
331
11625
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
332 class streamres(object):
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
333 def __init__(self, gen):
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
334 self.gen = gen
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
335
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
336 class pushres(object):
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
337 def __init__(self, res):
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
338 self.res = res
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
339
12703
40bb5853fc4b wireproto: introduce pusherr() to deal with "unsynced changes" error
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12702
diff changeset
340 class pusherr(object):
40bb5853fc4b wireproto: introduce pusherr() to deal with "unsynced changes" error
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12702
diff changeset
341 def __init__(self, res):
40bb5853fc4b wireproto: introduce pusherr() to deal with "unsynced changes" error
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12702
diff changeset
342 self.res = res
40bb5853fc4b wireproto: introduce pusherr() to deal with "unsynced changes" error
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12702
diff changeset
343
15017
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14970
diff changeset
344 class ooberror(object):
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14970
diff changeset
345 def __init__(self, message):
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14970
diff changeset
346 self.message = message
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14970
diff changeset
347
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
348 def dispatch(repo, proto, command):
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
349 func, spec = commands[command]
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
350 args = proto.getargs(spec)
11625
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
351 return func(repo, proto, *args)
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
352
13721
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
353 def options(cmd, keys, others):
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
354 opts = {}
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
355 for k in keys:
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
356 if k in others:
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
357 opts[k] = others[k]
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
358 del others[k]
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
359 if others:
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
360 sys.stderr.write("abort: %s got unexpected arguments %s\n"
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
361 % (cmd, ",".join(others)))
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
362 return opts
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
363
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
364 def batch(repo, proto, cmds, others):
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
365 res = []
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
366 for pair in cmds.split(';'):
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
367 op, args = pair.split(' ', 1)
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
368 vals = {}
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
369 for a in args.split(','):
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
370 if a:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
371 n, v = a.split('=')
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
372 vals[n] = unescapearg(v)
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
373 func, spec = commands[op]
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
374 if spec:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
375 keys = spec.split()
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
376 data = {}
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
377 for k in keys:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
378 if k == '*':
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
379 star = {}
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
380 for key in vals.keys():
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
381 if key not in keys:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
382 star[key] = vals[key]
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
383 data['*'] = star
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
384 else:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
385 data[k] = vals[k]
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
386 result = func(repo, proto, *[data[k] for k in keys])
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
387 else:
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
388 result = func(repo, proto)
15017
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14970
diff changeset
389 if isinstance(result, ooberror):
f4522df38c65 wireproto: add out-of-band error class to allow remote repo to report errors
Andrew Pritchard <andrewp@fogcreek.com>
parents: 14970
diff changeset
390 return result
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
391 res.append(escapearg(result))
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
392 return ';'.join(res)
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
393
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
394 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
395 pairs = [decodelist(p, '-') for p in pairs.split(" ")]
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
396 r = []
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
397 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
398 r.append(encodelist(b) + "\n")
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
399 return "".join(r)
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
400
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
401 def branchmap(repo, proto):
17205
97eff00046de repo: move visibleheads and visiblebranchmap logic in discovery
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17192
diff changeset
402 branchmap = discovery.visiblebranchmap(repo)
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
403 heads = []
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
404 for branch, nodes in branchmap.iteritems():
13047
6c375e07d673 branch: operate on branch names in local string space where possible
Matt Mackall <mpm@selenic.com>
parents: 12703
diff changeset
405 branchname = urllib.quote(encoding.fromlocal(branch))
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
406 branchnodes = encodelist(nodes)
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
407 heads.append('%s %s' % (branchname, branchnodes))
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
408 return '\n'.join(heads)
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
409
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
410 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
411 nodes = decodelist(nodes)
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
412 r = []
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
413 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
414 r.append(encodelist(b) + "\n")
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
415 return "".join(r)
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
416
11594
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
417 def capabilities(repo, proto):
13942
88f0e41d8802 wireproto: allow unbundle with hashed heads parameter (issue2126)
Shuhei Takahashi <takahashi.shuhei@gmail.com>
parents: 13741
diff changeset
418 caps = ('lookup changegroupsubset branchmap pushkey known getbundle '
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
419 'unbundlehash batch').split()
11627
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
420 if _allowstream(repo.ui):
16361
6097ede2be4d protocol: Add the stream-preferred capability
Benoit Allard <benoit@aeteurope.nl>
parents: 15925
diff changeset
421 if repo.ui.configbool('server', 'preferuncompressed', False):
6097ede2be4d protocol: Add the stream-preferred capability
Benoit Allard <benoit@aeteurope.nl>
parents: 15925
diff changeset
422 caps.append('stream-preferred')
12296
d7fff529d85d clone: only use stream when we understand the revlog format
Sune Foldager <cryo@cyanite.org>
parents: 12085
diff changeset
423 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
424 # 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
425 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
426 caps.append('stream')
d7fff529d85d clone: only use stream when we understand the revlog format
Sune Foldager <cryo@cyanite.org>
parents: 12085
diff changeset
427 # 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
428 else:
d7fff529d85d clone: only use stream when we understand the revlog format
Sune Foldager <cryo@cyanite.org>
parents: 12085
diff changeset
429 caps.append('streamreqs=%s' % ','.join(requiredformats))
11594
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
430 caps.append('unbundle=%s' % ','.join(changegroupmod.bundlepriority))
14093
ce99d887585f httprepo: long arguments support (issue2126)
Steven Brown <StevenGBrown@gmail.com>
parents: 14064
diff changeset
431 caps.append('httpheader=1024')
11594
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
432 return ' '.join(caps)
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
433
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
434 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
435 nodes = decodelist(roots)
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
436 cg = repo.changegroup(nodes, 'serve')
11625
cdeb861335d5 protocol: wrap non-string protocol responses in classes
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11623
diff changeset
437 return streamres(proto.groupchunks(cg))
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
438
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
439 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
440 bases = decodelist(bases)
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
441 heads = decodelist(heads)
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
442 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
443 return streamres(proto.groupchunks(cg))
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
444
13721
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
445 def debugwireargs(repo, proto, one, two, others):
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
446 # only accept optional args from the known set
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
447 opts = options('debugwireargs', ['three', 'four'], others)
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
448 return repo.debugwireargs(one, two, **opts)
13720
9c4e04fe267e debug: add debugwireargs to test argument passing over the wire
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13450
diff changeset
449
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
450 def getbundle(repo, proto, others):
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
451 opts = options('getbundle', ['heads', 'common'], others)
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
452 for k, v in opts.iteritems():
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
453 opts[k] = decodelist(v)
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
454 cg = repo.getbundle('serve', **opts)
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
455 return streamres(proto.groupchunks(cg))
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
456
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
457 def heads(repo, proto):
17205
97eff00046de repo: move visibleheads and visiblebranchmap logic in discovery
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17192
diff changeset
458 h = discovery.visibleheads(repo)
11597
9141d2c9e5a5 wireproto: refactor list of nodeid encoding / decoding
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 11594
diff changeset
459 return encodelist(h) + "\n"
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
460
11594
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
461 def hello(repo, proto):
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
462 '''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
463 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
464 Currently the only one defined is "capabilities", which
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
465 consists of a line in the form:
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
466
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
467 capabilities: space separated list of tokens
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
468 '''
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
469 return "capabilities: %s\n" % (capabilities(repo, proto))
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
470
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
471 def listkeys(repo, proto, namespace):
15217
42d0d4f63bf0 wireproto: do not call pushkey module directly (issue3041)
Andreas Freimuth <andreas.freimuth@united-bits.de>
parents: 15017
diff changeset
472 d = repo.listkeys(encoding.tolocal(namespace)).items()
13050
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
473 t = '\n'.join(['%s\t%s' % (encoding.fromlocal(k), encoding.fromlocal(v))
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
474 for k, v in d])
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
475 return t
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
476
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
477 def lookup(repo, proto, key):
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
478 try:
15925
f9fc46698352 wireproto: refuse to lookup secret csets
Matt Mackall <mpm@selenic.com>
parents: 15713
diff changeset
479 k = encoding.tolocal(key)
f9fc46698352 wireproto: refuse to lookup secret csets
Matt Mackall <mpm@selenic.com>
parents: 15713
diff changeset
480 c = repo[k]
f9fc46698352 wireproto: refuse to lookup secret csets
Matt Mackall <mpm@selenic.com>
parents: 15713
diff changeset
481 if c.phase() == phases.secret:
f9fc46698352 wireproto: refuse to lookup secret csets
Matt Mackall <mpm@selenic.com>
parents: 15713
diff changeset
482 raise error.RepoLookupError(_("unknown revision '%s'") % k)
f9fc46698352 wireproto: refuse to lookup secret csets
Matt Mackall <mpm@selenic.com>
parents: 15713
diff changeset
483 r = c.hex()
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
484 success = 1
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
485 except Exception, inst:
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
486 r = str(inst)
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
487 success = 0
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
488 return "%s %s\n" % (success, r)
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
489
14436
5adb52524779 wireproto: enable optional args for known() for future extensibility
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14419
diff changeset
490 def known(repo, proto, nodes, others):
13723
e615765fdcc7 wireproto: add known([id]) function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13722
diff changeset
491 return ''.join(b and "1" or "0" for b in repo.known(decodelist(nodes)))
e615765fdcc7 wireproto: add known([id]) function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13722
diff changeset
492
11583
944c23762c3c protocol: add proto to method prototypes
Matt Mackall <mpm@selenic.com>
parents: 11581
diff changeset
493 def pushkey(repo, proto, namespace, key, old, new):
13050
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
494 # compatibility with pre-1.8 clients which were accidentally
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
495 # sending raw binary nodes rather than utf-8-encoded hex
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
496 if len(new) == 20 and new.encode('string-escape') != new:
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
497 # looks like it could be a binary node
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
498 try:
14064
e4bfb9c337f3 remove unused imports and variables
Alexander Solovyov <alexander@solovyov.net>
parents: 14048
diff changeset
499 new.decode('utf-8')
13050
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
500 new = encoding.tolocal(new) # but cleanly decodes as UTF-8
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
501 except UnicodeDecodeError:
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
502 pass # binary, leave unmodified
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
503 else:
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
504 new = encoding.tolocal(new) # normal path
3790452d499b pushkey: use UTF-8
Matt Mackall <mpm@selenic.com>
parents: 13049
diff changeset
505
15217
42d0d4f63bf0 wireproto: do not call pushkey module directly (issue3041)
Andreas Freimuth <andreas.freimuth@united-bits.de>
parents: 15017
diff changeset
506 r = repo.pushkey(encoding.tolocal(namespace), encoding.tolocal(key),
42d0d4f63bf0 wireproto: do not call pushkey module directly (issue3041)
Andreas Freimuth <andreas.freimuth@united-bits.de>
parents: 15017
diff changeset
507 encoding.tolocal(old), new)
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
508 return '%s\n' % int(r)
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
509
11627
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
510 def _allowstream(ui):
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
511 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
512
11585
5d907fbb9703 protocol: unify stream_out command
Matt Mackall <mpm@selenic.com>
parents: 11584
diff changeset
513 def stream(repo, proto):
11627
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
514 '''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
515 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
516 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
517
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
518 The format is simple: the server writes out a line with the amount
17424
e7cfe3587ea4 fix trivial spelling errors
Mads Kiilerich <mads@kiilerich.com>
parents: 17293
diff changeset
519 of files, then the total amount of bytes to be transferred (separated
11627
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
520 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
521 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
522 '''
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
523
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
524 if not _allowstream(repo.ui):
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
525 return '1\n'
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
526
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
527 entries = []
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
528 total_bytes = 0
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
529 try:
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
530 # 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
531 lock = repo.lock()
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
532 try:
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
533 repo.ui.debug('scanning\n')
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
534 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
535 entries.append((name, size))
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
536 total_bytes += size
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
537 finally:
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
538 lock.release()
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
539 except error.LockError:
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
540 return '2\n' # error: 2
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
541
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
542 def streamer(repo, entries, total):
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
543 '''stream out all metadata files in repository.'''
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
544 yield '0\n' # success
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
545 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
546 (len(entries), total_bytes))
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
547 yield '%d %d\n' % (len(entries), total_bytes)
17556
39c6e349dfff wireproto: don't audit local paths during stream_out
Bryan O'Sullivan <bryano@fb.com>
parents: 17424
diff changeset
548
39c6e349dfff wireproto: don't audit local paths during stream_out
Bryan O'Sullivan <bryano@fb.com>
parents: 17424
diff changeset
549 sopener = repo.sopener
39c6e349dfff wireproto: don't audit local paths during stream_out
Bryan O'Sullivan <bryano@fb.com>
parents: 17424
diff changeset
550 oldaudit = sopener.mustaudit
17558
380a89413403 wireproto: don't format a debug string inside a hot loop
Bryan O'Sullivan <bryano@fb.com>
parents: 17557
diff changeset
551 debugflag = repo.ui.debugflag
17556
39c6e349dfff wireproto: don't audit local paths during stream_out
Bryan O'Sullivan <bryano@fb.com>
parents: 17424
diff changeset
552 sopener.mustaudit = False
39c6e349dfff wireproto: don't audit local paths during stream_out
Bryan O'Sullivan <bryano@fb.com>
parents: 17424
diff changeset
553
39c6e349dfff wireproto: don't audit local paths during stream_out
Bryan O'Sullivan <bryano@fb.com>
parents: 17424
diff changeset
554 try:
39c6e349dfff wireproto: don't audit local paths during stream_out
Bryan O'Sullivan <bryano@fb.com>
parents: 17424
diff changeset
555 for name, size in entries:
17558
380a89413403 wireproto: don't format a debug string inside a hot loop
Bryan O'Sullivan <bryano@fb.com>
parents: 17557
diff changeset
556 if debugflag:
380a89413403 wireproto: don't format a debug string inside a hot loop
Bryan O'Sullivan <bryano@fb.com>
parents: 17557
diff changeset
557 repo.ui.debug('sending %s (%d bytes)\n' % (name, size))
17556
39c6e349dfff wireproto: don't audit local paths during stream_out
Bryan O'Sullivan <bryano@fb.com>
parents: 17424
diff changeset
558 # partially encode name over the wire for backwards compat
39c6e349dfff wireproto: don't audit local paths during stream_out
Bryan O'Sullivan <bryano@fb.com>
parents: 17424
diff changeset
559 yield '%s\0%d\n' % (store.encodedir(name), size)
17557
6d97dd630d79 wireproto: bypass filechunkiter for small files when streaming
Bryan O'Sullivan <bryano@fb.com>
parents: 17556
diff changeset
560 if size <= 65536:
17567
2ee7281e5aaa wireproto: fix check-code.py breakage introduced by 6d97dd630d79
Patrick Mezard <patrick@mezard.eu>
parents: 17558
diff changeset
561 fp = sopener(name)
2ee7281e5aaa wireproto: fix check-code.py breakage introduced by 6d97dd630d79
Patrick Mezard <patrick@mezard.eu>
parents: 17558
diff changeset
562 try:
2ee7281e5aaa wireproto: fix check-code.py breakage introduced by 6d97dd630d79
Patrick Mezard <patrick@mezard.eu>
parents: 17558
diff changeset
563 data = fp.read(size)
2ee7281e5aaa wireproto: fix check-code.py breakage introduced by 6d97dd630d79
Patrick Mezard <patrick@mezard.eu>
parents: 17558
diff changeset
564 finally:
2ee7281e5aaa wireproto: fix check-code.py breakage introduced by 6d97dd630d79
Patrick Mezard <patrick@mezard.eu>
parents: 17558
diff changeset
565 fp.close()
2ee7281e5aaa wireproto: fix check-code.py breakage introduced by 6d97dd630d79
Patrick Mezard <patrick@mezard.eu>
parents: 17558
diff changeset
566 yield data
17557
6d97dd630d79 wireproto: bypass filechunkiter for small files when streaming
Bryan O'Sullivan <bryano@fb.com>
parents: 17556
diff changeset
567 else:
6d97dd630d79 wireproto: bypass filechunkiter for small files when streaming
Bryan O'Sullivan <bryano@fb.com>
parents: 17556
diff changeset
568 for chunk in util.filechunkiter(sopener(name), limit=size):
6d97dd630d79 wireproto: bypass filechunkiter for small files when streaming
Bryan O'Sullivan <bryano@fb.com>
parents: 17556
diff changeset
569 yield chunk
17603
a7fa5bd1c914 wireproto: workaround for yield inside try/finally incompatible with python2.4
Thomas Arendsen Hein <thomas@intevation.de>
parents: 17567
diff changeset
570 # replace with "finally:" when support for python 2.4 has been dropped
a7fa5bd1c914 wireproto: workaround for yield inside try/finally incompatible with python2.4
Thomas Arendsen Hein <thomas@intevation.de>
parents: 17567
diff changeset
571 except Exception:
17556
39c6e349dfff wireproto: don't audit local paths during stream_out
Bryan O'Sullivan <bryano@fb.com>
parents: 17424
diff changeset
572 sopener.mustaudit = oldaudit
17603
a7fa5bd1c914 wireproto: workaround for yield inside try/finally incompatible with python2.4
Thomas Arendsen Hein <thomas@intevation.de>
parents: 17567
diff changeset
573 raise
a7fa5bd1c914 wireproto: workaround for yield inside try/finally incompatible with python2.4
Thomas Arendsen Hein <thomas@intevation.de>
parents: 17567
diff changeset
574 sopener.mustaudit = oldaudit
11627
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
575
04f76a954842 protocol: move the streamclone implementation into wireproto
Dirkjan Ochtman <dirkjan@ochtman.nl>
parents: 11625
diff changeset
576 return streamres(streamer(repo, entries, total_bytes))
11585
5d907fbb9703 protocol: unify stream_out command
Matt Mackall <mpm@selenic.com>
parents: 11584
diff changeset
577
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
578 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
579 their_heads = decodelist(heads)
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
580
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
581 def check_heads():
17205
97eff00046de repo: move visibleheads and visiblebranchmap logic in discovery
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 17192
diff changeset
582 heads = discovery.visibleheads(repo)
13942
88f0e41d8802 wireproto: allow unbundle with hashed heads parameter (issue2126)
Shuhei Takahashi <takahashi.shuhei@gmail.com>
parents: 13741
diff changeset
583 heads_hash = util.sha1(''.join(sorted(heads))).digest()
88f0e41d8802 wireproto: allow unbundle with hashed heads parameter (issue2126)
Shuhei Takahashi <takahashi.shuhei@gmail.com>
parents: 13741
diff changeset
584 return (their_heads == ['force'] or their_heads == heads or
88f0e41d8802 wireproto: allow unbundle with hashed heads parameter (issue2126)
Shuhei Takahashi <takahashi.shuhei@gmail.com>
parents: 13741
diff changeset
585 their_heads == ['hashed', heads_hash])
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
586
12702
f747c085b789 wireproto: redirect the output earlier
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12701
diff changeset
587 proto.redirect()
f747c085b789 wireproto: redirect the output earlier
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12701
diff changeset
588
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
589 # fail early if possible
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
590 if not check_heads():
12703
40bb5853fc4b wireproto: introduce pusherr() to deal with "unsynced changes" error
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12702
diff changeset
591 return pusherr('unsynced changes')
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
592
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
593 # 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
594 fd, tempname = tempfile.mkstemp(prefix='hg-unbundle-')
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
595 fp = os.fdopen(fd, 'wb+')
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
596 r = 0
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
597 try:
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
598 proto.getfile(fp)
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
599 lock = repo.lock()
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
600 try:
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
601 if not check_heads():
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
602 # someone else committed/pushed/unbundled while we
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
603 # were transferring data
12703
40bb5853fc4b wireproto: introduce pusherr() to deal with "unsynced changes" error
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12702
diff changeset
604 return pusherr('unsynced changes')
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
605
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
606 # push can proceed
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
607 fp.seek(0)
12042
210049a8d16e bundle: unify/refactor unbundle/readbundle
Matt Mackall <mpm@selenic.com>
parents: 11879
diff changeset
608 gen = changegroupmod.readbundle(fp, None)
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
609
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
610 try:
15585
a348739da8f0 addchangegroup: remove the lock argument on the addchangegroup methods
Pierre-Yves David <pierre-yves.david@ens-lyon.org>
parents: 15217
diff changeset
611 r = repo.addchangegroup(gen, 'serve', proto._client())
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
612 except util.Abort, inst:
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
613 sys.stderr.write("abort: %s\n" % inst)
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
614 finally:
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
615 lock.release()
12701
cb9e1d1c34ea wireproto: return in finally was messing with the return inside the block
Benoit Boissinot <benoit.boissinot@ens-lyon.org>
parents: 12337
diff changeset
616 return pushres(r)
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
617
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
618 finally:
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
619 fp.close()
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
620 os.unlink(tempname)
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
621
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
622 commands = {
14622
bd88561afb4b wireproto: add batching support to wirerepository
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14621
diff changeset
623 'batch': (batch, 'cmds *'),
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
624 'between': (between, 'pairs'),
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
625 'branchmap': (branchmap, ''),
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
626 'branches': (branches, 'nodes'),
11594
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
627 'capabilities': (capabilities, ''),
11584
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
628 'changegroup': (changegroup, 'roots'),
1af96b090116 protocol: unify changegroup commands
Matt Mackall <mpm@selenic.com>
parents: 11583
diff changeset
629 'changegroupsubset': (changegroupsubset, 'bases heads'),
13721
3458c15ab2f0 wireproto: fix handling of '*' args for HTTP and SSH
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13720
diff changeset
630 'debugwireargs': (debugwireargs, 'one two *'),
13741
b51bf961b3cb wireproto: add getbundle() function
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 13726
diff changeset
631 'getbundle': (getbundle, '*'),
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
632 'heads': (heads, ''),
11594
67863f9d805f protocol: unify server-side capabilities functions
Matt Mackall <mpm@selenic.com>
parents: 11593
diff changeset
633 'hello': (hello, ''),
14436
5adb52524779 wireproto: enable optional args for known() for future extensibility
Peter Arrenbrecht <peter.arrenbrecht@gmail.com>
parents: 14419
diff changeset
634 'known': (known, 'nodes *'),
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
635 'listkeys': (listkeys, 'namespace'),
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
636 'lookup': (lookup, 'key'),
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
637 'pushkey': (pushkey, 'namespace key old new'),
11585
5d907fbb9703 protocol: unify stream_out command
Matt Mackall <mpm@selenic.com>
parents: 11584
diff changeset
638 'stream_out': (stream, ''),
11593
d054cc5c7737 protocol: unify unbundle on the server side
Matt Mackall <mpm@selenic.com>
parents: 11592
diff changeset
639 'unbundle': (unbundle, 'heads'),
11581
4530b3307fb9 protocol: introduce wireproto.py
Matt Mackall <mpm@selenic.com>
parents:
diff changeset
640 }