Show More
@@ -0,0 +1,108 b'' | |||||
|
1 | # sshprotoext.py - Extension to test behavior of SSH protocol | |||
|
2 | # | |||
|
3 | # Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com> | |||
|
4 | # | |||
|
5 | # This software may be used and distributed according to the terms of the | |||
|
6 | # GNU General Public License version 2 or any later version. | |||
|
7 | ||||
|
8 | # This extension replaces the SSH server started via `hg serve --stdio`. | |||
|
9 | # The server behaves differently depending on environment variables. | |||
|
10 | ||||
|
11 | from __future__ import absolute_import | |||
|
12 | ||||
|
13 | from mercurial import ( | |||
|
14 | error, | |||
|
15 | registrar, | |||
|
16 | sshpeer, | |||
|
17 | wireproto, | |||
|
18 | wireprotoserver, | |||
|
19 | ) | |||
|
20 | ||||
|
21 | configtable = {} | |||
|
22 | configitem = registrar.configitem(configtable) | |||
|
23 | ||||
|
24 | configitem('sshpeer', 'mode', default=None) | |||
|
25 | configitem('sshpeer', 'handshake-mode', default=None) | |||
|
26 | ||||
|
27 | class bannerserver(wireprotoserver.sshserver): | |||
|
28 | """Server that sends a banner to stdout.""" | |||
|
29 | def serve_forever(self): | |||
|
30 | for i in range(10): | |||
|
31 | self._fout.write(b'banner: line %d\n' % i) | |||
|
32 | ||||
|
33 | super(bannerserver, self).serve_forever() | |||
|
34 | ||||
|
35 | class prehelloserver(wireprotoserver.sshserver): | |||
|
36 | """Tests behavior when connecting to <0.9.1 servers. | |||
|
37 | ||||
|
38 | The ``hello`` wire protocol command was introduced in Mercurial | |||
|
39 | 0.9.1. Modern clients send the ``hello`` command when connecting | |||
|
40 | to SSH servers. This mock server tests behavior of the handshake | |||
|
41 | when ``hello`` is not supported. | |||
|
42 | """ | |||
|
43 | def serve_forever(self): | |||
|
44 | l = self._fin.readline() | |||
|
45 | assert l == b'hello\n' | |||
|
46 | # Respond to unknown commands with an empty reply. | |||
|
47 | self._sendresponse(b'') | |||
|
48 | l = self._fin.readline() | |||
|
49 | assert l == b'between\n' | |||
|
50 | rsp = wireproto.dispatch(self._repo, self, b'between') | |||
|
51 | self._handlers[rsp.__class__](self, rsp) | |||
|
52 | ||||
|
53 | super(prehelloserver, self).serve_forever() | |||
|
54 | ||||
|
55 | class extrahandshakecommandspeer(sshpeer.sshpeer): | |||
|
56 | """An ssh peer that sends extra commands as part of initial handshake.""" | |||
|
57 | # There isn't a good hook point. So we wrap _callstream() and inject | |||
|
58 | # logic when the peer says "hello". | |||
|
59 | def _callstream(self, cmd, **args): | |||
|
60 | if cmd != b'hello': | |||
|
61 | return super(extrahandshakecommandspeer, self)._callstream(cmd, | |||
|
62 | **args) | |||
|
63 | ||||
|
64 | mode = self._ui.config(b'sshpeer', b'handshake-mode') | |||
|
65 | if mode == b'pre-no-args': | |||
|
66 | self._callstream(b'no-args') | |||
|
67 | return super(extrahandshakecommandspeer, self)._callstream( | |||
|
68 | cmd, **args) | |||
|
69 | elif mode == b'pre-multiple-no-args': | |||
|
70 | self._callstream(b'unknown1') | |||
|
71 | self._callstream(b'unknown2') | |||
|
72 | self._callstream(b'unknown3') | |||
|
73 | return super(extrahandshakecommandspeer, self)._callstream( | |||
|
74 | cmd, **args) | |||
|
75 | else: | |||
|
76 | raise error.ProgrammingError(b'unknown HANDSHAKECOMMANDMODE: %s' % | |||
|
77 | mode) | |||
|
78 | ||||
|
79 | def registercommands(): | |||
|
80 | def dummycommand(repo, proto): | |||
|
81 | raise error.ProgrammingError('this should never be called') | |||
|
82 | ||||
|
83 | wireproto.wireprotocommand(b'no-args', b'')(dummycommand) | |||
|
84 | wireproto.wireprotocommand(b'unknown1', b'')(dummycommand) | |||
|
85 | wireproto.wireprotocommand(b'unknown2', b'')(dummycommand) | |||
|
86 | wireproto.wireprotocommand(b'unknown3', b'')(dummycommand) | |||
|
87 | ||||
|
88 | def extsetup(ui): | |||
|
89 | # It's easier for tests to define the server behavior via environment | |||
|
90 | # variables than config options. This is because `hg serve --stdio` | |||
|
91 | # has to be invoked with a certain form for security reasons and | |||
|
92 | # `dummyssh` can't just add `--config` flags to the command line. | |||
|
93 | servermode = ui.environ.get(b'SSHSERVERMODE') | |||
|
94 | ||||
|
95 | if servermode == b'banner': | |||
|
96 | wireprotoserver.sshserver = bannerserver | |||
|
97 | elif servermode == b'no-hello': | |||
|
98 | wireprotoserver.sshserver = prehelloserver | |||
|
99 | elif servermode: | |||
|
100 | raise error.ProgrammingError(b'unknown server mode: %s' % servermode) | |||
|
101 | ||||
|
102 | peermode = ui.config(b'sshpeer', b'mode') | |||
|
103 | ||||
|
104 | if peermode == b'extra-handshake-commands': | |||
|
105 | sshpeer.sshpeer = extrahandshakecommandspeer | |||
|
106 | registercommands() | |||
|
107 | elif peermode: | |||
|
108 | raise error.ProgrammingError(b'unknown peer mode: %s' % peermode) |
@@ -0,0 +1,398 b'' | |||||
|
1 | $ cat >> $HGRCPATH << EOF | |||
|
2 | > [ui] | |||
|
3 | > ssh = $PYTHON "$TESTDIR/dummyssh" | |||
|
4 | > [devel] | |||
|
5 | > debug.peer-request = true | |||
|
6 | > [extensions] | |||
|
7 | > sshprotoext = $TESTDIR/sshprotoext.py | |||
|
8 | > EOF | |||
|
9 | ||||
|
10 | $ hg init server | |||
|
11 | $ cd server | |||
|
12 | $ echo 0 > foo | |||
|
13 | $ hg -q add foo | |||
|
14 | $ hg commit -m initial | |||
|
15 | $ cd .. | |||
|
16 | ||||
|
17 | Test a normal behaving server, for sanity | |||
|
18 | ||||
|
19 | $ hg --debug debugpeer ssh://user@dummy/server | |||
|
20 | running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) | |||
|
21 | devel-peer-request: hello | |||
|
22 | sending hello command | |||
|
23 | devel-peer-request: between | |||
|
24 | devel-peer-request: pairs: 81 bytes | |||
|
25 | sending between command | |||
|
26 | remote: 384 | |||
|
27 | remote: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN | |||
|
28 | remote: 1 | |||
|
29 | url: ssh://user@dummy/server | |||
|
30 | local: no | |||
|
31 | pushable: yes | |||
|
32 | ||||
|
33 | Server should answer the "hello" command in isolation | |||
|
34 | ||||
|
35 | $ hg -R server serve --stdio << EOF | |||
|
36 | > hello | |||
|
37 | > EOF | |||
|
38 | 384 | |||
|
39 | capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN | |||
|
40 | ||||
|
41 | >=0.9.1 clients send a "hello" + "between" for the null range as part of handshake. | |||
|
42 | Server should reply with capabilities and should send "1\n\n" as a successful | |||
|
43 | reply with empty response to the "between". | |||
|
44 | ||||
|
45 | $ hg -R server serve --stdio << EOF | |||
|
46 | > hello | |||
|
47 | > between | |||
|
48 | > pairs 81 | |||
|
49 | > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000 | |||
|
50 | > EOF | |||
|
51 | 384 | |||
|
52 | capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN | |||
|
53 | 1 | |||
|
54 | ||||
|
55 | ||||
|
56 | SSH banner is not printed by default, ignored by clients | |||
|
57 | ||||
|
58 | $ SSHSERVERMODE=banner hg debugpeer ssh://user@dummy/server | |||
|
59 | url: ssh://user@dummy/server | |||
|
60 | local: no | |||
|
61 | pushable: yes | |||
|
62 | ||||
|
63 | --debug will print the banner | |||
|
64 | ||||
|
65 | $ SSHSERVERMODE=banner hg --debug debugpeer ssh://user@dummy/server | |||
|
66 | running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) | |||
|
67 | devel-peer-request: hello | |||
|
68 | sending hello command | |||
|
69 | devel-peer-request: between | |||
|
70 | devel-peer-request: pairs: 81 bytes | |||
|
71 | sending between command | |||
|
72 | remote: banner: line 0 | |||
|
73 | remote: banner: line 1 | |||
|
74 | remote: banner: line 2 | |||
|
75 | remote: banner: line 3 | |||
|
76 | remote: banner: line 4 | |||
|
77 | remote: banner: line 5 | |||
|
78 | remote: banner: line 6 | |||
|
79 | remote: banner: line 7 | |||
|
80 | remote: banner: line 8 | |||
|
81 | remote: banner: line 9 | |||
|
82 | remote: 384 | |||
|
83 | remote: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN | |||
|
84 | remote: 1 | |||
|
85 | url: ssh://user@dummy/server | |||
|
86 | local: no | |||
|
87 | pushable: yes | |||
|
88 | ||||
|
89 | And test the banner with the raw protocol | |||
|
90 | ||||
|
91 | $ SSHSERVERMODE=banner hg -R server serve --stdio << EOF | |||
|
92 | > hello | |||
|
93 | > between | |||
|
94 | > pairs 81 | |||
|
95 | > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000 | |||
|
96 | > EOF | |||
|
97 | banner: line 0 | |||
|
98 | banner: line 1 | |||
|
99 | banner: line 2 | |||
|
100 | banner: line 3 | |||
|
101 | banner: line 4 | |||
|
102 | banner: line 5 | |||
|
103 | banner: line 6 | |||
|
104 | banner: line 7 | |||
|
105 | banner: line 8 | |||
|
106 | banner: line 9 | |||
|
107 | 384 | |||
|
108 | capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN | |||
|
109 | 1 | |||
|
110 | ||||
|
111 | ||||
|
112 | Connecting to a <0.9.1 server that doesn't support the hello command | |||
|
113 | ||||
|
114 | $ SSHSERVERMODE=no-hello hg --debug debugpeer ssh://user@dummy/server | |||
|
115 | running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) | |||
|
116 | devel-peer-request: hello | |||
|
117 | sending hello command | |||
|
118 | devel-peer-request: between | |||
|
119 | devel-peer-request: pairs: 81 bytes | |||
|
120 | sending between command | |||
|
121 | remote: 0 | |||
|
122 | remote: 1 | |||
|
123 | url: ssh://user@dummy/server | |||
|
124 | local: no | |||
|
125 | pushable: yes | |||
|
126 | ||||
|
127 | The client should interpret this as no capabilities | |||
|
128 | ||||
|
129 | $ SSHSERVERMODE=no-hello hg debugcapabilities ssh://user@dummy/server | |||
|
130 | Main capabilities: | |||
|
131 | ||||
|
132 | Sending an unknown command to the server results in an empty response to that command | |||
|
133 | ||||
|
134 | $ hg -R server serve --stdio << EOF | |||
|
135 | > pre-hello | |||
|
136 | > hello | |||
|
137 | > between | |||
|
138 | > pairs 81 | |||
|
139 | > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000 | |||
|
140 | > EOF | |||
|
141 | 0 | |||
|
142 | 384 | |||
|
143 | capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN | |||
|
144 | 1 | |||
|
145 | ||||
|
146 | ||||
|
147 | $ hg --config sshpeer.mode=extra-handshake-commands --config sshpeer.handshake-mode=pre-no-args --debug debugpeer ssh://user@dummy/server | |||
|
148 | running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) | |||
|
149 | devel-peer-request: no-args | |||
|
150 | sending no-args command | |||
|
151 | devel-peer-request: hello | |||
|
152 | sending hello command | |||
|
153 | devel-peer-request: between | |||
|
154 | devel-peer-request: pairs: 81 bytes | |||
|
155 | sending between command | |||
|
156 | remote: 0 | |||
|
157 | remote: 384 | |||
|
158 | remote: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN | |||
|
159 | remote: 1 | |||
|
160 | url: ssh://user@dummy/server | |||
|
161 | local: no | |||
|
162 | pushable: yes | |||
|
163 | ||||
|
164 | Send multiple unknown commands before hello | |||
|
165 | ||||
|
166 | $ hg -R server serve --stdio << EOF | |||
|
167 | > unknown1 | |||
|
168 | > unknown2 | |||
|
169 | > unknown3 | |||
|
170 | > hello | |||
|
171 | > between | |||
|
172 | > pairs 81 | |||
|
173 | > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000 | |||
|
174 | > EOF | |||
|
175 | 0 | |||
|
176 | 0 | |||
|
177 | 0 | |||
|
178 | 384 | |||
|
179 | capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN | |||
|
180 | 1 | |||
|
181 | ||||
|
182 | ||||
|
183 | $ hg --config sshpeer.mode=extra-handshake-commands --config sshpeer.handshake-mode=pre-multiple-no-args --debug debugpeer ssh://user@dummy/server | |||
|
184 | running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) | |||
|
185 | devel-peer-request: unknown1 | |||
|
186 | sending unknown1 command | |||
|
187 | devel-peer-request: unknown2 | |||
|
188 | sending unknown2 command | |||
|
189 | devel-peer-request: unknown3 | |||
|
190 | sending unknown3 command | |||
|
191 | devel-peer-request: hello | |||
|
192 | sending hello command | |||
|
193 | devel-peer-request: between | |||
|
194 | devel-peer-request: pairs: 81 bytes | |||
|
195 | sending between command | |||
|
196 | remote: 0 | |||
|
197 | remote: 0 | |||
|
198 | remote: 0 | |||
|
199 | remote: 384 | |||
|
200 | remote: capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN | |||
|
201 | remote: 1 | |||
|
202 | url: ssh://user@dummy/server | |||
|
203 | local: no | |||
|
204 | pushable: yes | |||
|
205 | ||||
|
206 | Send an unknown command before hello that has arguments | |||
|
207 | ||||
|
208 | $ hg -R server serve --stdio << EOF | |||
|
209 | > with-args | |||
|
210 | > foo 13 | |||
|
211 | > value for foo | |||
|
212 | > bar 13 | |||
|
213 | > value for bar | |||
|
214 | > hello | |||
|
215 | > between | |||
|
216 | > pairs 81 | |||
|
217 | > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000 | |||
|
218 | > EOF | |||
|
219 | 0 | |||
|
220 | 0 | |||
|
221 | 0 | |||
|
222 | 0 | |||
|
223 | 0 | |||
|
224 | 384 | |||
|
225 | capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN | |||
|
226 | 1 | |||
|
227 | ||||
|
228 | ||||
|
229 | Send an unknown command having an argument that looks numeric | |||
|
230 | ||||
|
231 | $ hg -R server serve --stdio << EOF | |||
|
232 | > unknown | |||
|
233 | > foo 1 | |||
|
234 | > 0 | |||
|
235 | > hello | |||
|
236 | > between | |||
|
237 | > pairs 81 | |||
|
238 | > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000 | |||
|
239 | > EOF | |||
|
240 | 0 | |||
|
241 | 0 | |||
|
242 | 0 | |||
|
243 | 384 | |||
|
244 | capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN | |||
|
245 | 1 | |||
|
246 | ||||
|
247 | ||||
|
248 | $ hg -R server serve --stdio << EOF | |||
|
249 | > unknown | |||
|
250 | > foo 1 | |||
|
251 | > 1 | |||
|
252 | > hello | |||
|
253 | > between | |||
|
254 | > pairs 81 | |||
|
255 | > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000 | |||
|
256 | > EOF | |||
|
257 | 0 | |||
|
258 | 0 | |||
|
259 | 0 | |||
|
260 | 384 | |||
|
261 | capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN | |||
|
262 | 1 | |||
|
263 | ||||
|
264 | ||||
|
265 | When sending a dict argument value, it is serialized to | |||
|
266 | "<arg> <item count>" followed by "<key> <len>\n<value>" for each item | |||
|
267 | in the dict. | |||
|
268 | ||||
|
269 | Dictionary value for unknown command | |||
|
270 | ||||
|
271 | $ hg -R server serve --stdio << EOF | |||
|
272 | > unknown | |||
|
273 | > dict 3 | |||
|
274 | > key1 3 | |||
|
275 | > foo | |||
|
276 | > key2 3 | |||
|
277 | > bar | |||
|
278 | > key3 3 | |||
|
279 | > baz | |||
|
280 | > hello | |||
|
281 | > EOF | |||
|
282 | 0 | |||
|
283 | 0 | |||
|
284 | 0 | |||
|
285 | 0 | |||
|
286 | 0 | |||
|
287 | 0 | |||
|
288 | 0 | |||
|
289 | 0 | |||
|
290 | 384 | |||
|
291 | capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN | |||
|
292 | ||||
|
293 | Incomplete dictionary send | |||
|
294 | ||||
|
295 | $ hg -R server serve --stdio << EOF | |||
|
296 | > unknown | |||
|
297 | > dict 3 | |||
|
298 | > key1 3 | |||
|
299 | > foo | |||
|
300 | > EOF | |||
|
301 | 0 | |||
|
302 | 0 | |||
|
303 | 0 | |||
|
304 | 0 | |||
|
305 | ||||
|
306 | Incomplete value send | |||
|
307 | ||||
|
308 | $ hg -R server serve --stdio << EOF | |||
|
309 | > unknown | |||
|
310 | > dict 3 | |||
|
311 | > key1 3 | |||
|
312 | > fo | |||
|
313 | > EOF | |||
|
314 | 0 | |||
|
315 | 0 | |||
|
316 | 0 | |||
|
317 | 0 | |||
|
318 | ||||
|
319 | Send a command line with spaces | |||
|
320 | ||||
|
321 | $ hg -R server serve --stdio << EOF | |||
|
322 | > unknown withspace | |||
|
323 | > hello | |||
|
324 | > between | |||
|
325 | > pairs 81 | |||
|
326 | > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000 | |||
|
327 | > EOF | |||
|
328 | 0 | |||
|
329 | 384 | |||
|
330 | capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN | |||
|
331 | 1 | |||
|
332 | ||||
|
333 | ||||
|
334 | $ hg -R server serve --stdio << EOF | |||
|
335 | > unknown with multiple spaces | |||
|
336 | > hello | |||
|
337 | > between | |||
|
338 | > pairs 81 | |||
|
339 | > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000 | |||
|
340 | > EOF | |||
|
341 | 0 | |||
|
342 | 384 | |||
|
343 | capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN | |||
|
344 | 1 | |||
|
345 | ||||
|
346 | ||||
|
347 | $ hg -R server serve --stdio << EOF | |||
|
348 | > unknown with spaces | |||
|
349 | > key 10 | |||
|
350 | > some value | |||
|
351 | > hello | |||
|
352 | > between | |||
|
353 | > pairs 81 | |||
|
354 | > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000 | |||
|
355 | > EOF | |||
|
356 | 0 | |||
|
357 | 0 | |||
|
358 | 0 | |||
|
359 | 384 | |||
|
360 | capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN | |||
|
361 | 1 | |||
|
362 | ||||
|
363 | ||||
|
364 | Send an unknown command after the "between" | |||
|
365 | ||||
|
366 | $ hg -R server serve --stdio << EOF | |||
|
367 | > hello | |||
|
368 | > between | |||
|
369 | > pairs 81 | |||
|
370 | > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000unknown | |||
|
371 | > EOF | |||
|
372 | 384 | |||
|
373 | capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN | |||
|
374 | 1 | |||
|
375 | ||||
|
376 | 0 | |||
|
377 | ||||
|
378 | And one with arguments | |||
|
379 | ||||
|
380 | $ hg -R server serve --stdio << EOF | |||
|
381 | > hello | |||
|
382 | > between | |||
|
383 | > pairs 81 | |||
|
384 | > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000unknown | |||
|
385 | > foo 5 | |||
|
386 | > value | |||
|
387 | > bar 3 | |||
|
388 | > baz | |||
|
389 | > EOF | |||
|
390 | 384 | |||
|
391 | capabilities: lookup changegroupsubset branchmap pushkey known getbundle unbundlehash batch streamreqs=generaldelta,revlogv1 $USUAL_BUNDLE2_CAPS_SERVER$ unbundle=HG10GZ,HG10BZ,HG10UN | |||
|
392 | 1 | |||
|
393 | ||||
|
394 | 0 | |||
|
395 | 0 | |||
|
396 | 0 | |||
|
397 | 0 | |||
|
398 | 0 |
General Comments 0
You need to be logged in to leave comments.
Login now