##// END OF EJS Templates
wireprotov2: allow multiple fields to follow revision maps...
Gregory Szorc -
r39839:d059cb66 default
parent child Browse files
Show More

The requested changes are too big and content was truncated. Show full diff

@@ -1,396 +1,411 b''
1 1 # exchangev2.py - repository exchange for wire protocol version 2
2 2 #
3 3 # Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com>
4 4 #
5 5 # This software may be used and distributed according to the terms of the
6 6 # GNU General Public License version 2 or any later version.
7 7
8 8 from __future__ import absolute_import
9 9
10 10 import collections
11 11 import weakref
12 12
13 13 from .i18n import _
14 14 from .node import (
15 15 nullid,
16 16 short,
17 17 )
18 18 from . import (
19 19 bookmarks,
20 20 error,
21 21 mdiff,
22 22 phases,
23 23 pycompat,
24 24 setdiscovery,
25 25 )
26 26
27 27 def pull(pullop):
28 28 """Pull using wire protocol version 2."""
29 29 repo = pullop.repo
30 30 remote = pullop.remote
31 31 tr = pullop.trmanager.transaction()
32 32
33 33 # Figure out what needs to be fetched.
34 34 common, fetch, remoteheads = _pullchangesetdiscovery(
35 35 repo, remote, pullop.heads, abortwhenunrelated=pullop.force)
36 36
37 37 # And fetch the data.
38 38 pullheads = pullop.heads or remoteheads
39 39 csetres = _fetchchangesets(repo, tr, remote, common, fetch, pullheads)
40 40
41 41 # New revisions are written to the changelog. But all other updates
42 42 # are deferred. Do those now.
43 43
44 44 # Ensure all new changesets are draft by default. If the repo is
45 45 # publishing, the phase will be adjusted by the loop below.
46 46 if csetres['added']:
47 47 phases.registernew(repo, tr, phases.draft, csetres['added'])
48 48
49 49 # And adjust the phase of all changesets accordingly.
50 50 for phase in phases.phasenames:
51 51 if phase == b'secret' or not csetres['nodesbyphase'][phase]:
52 52 continue
53 53
54 54 phases.advanceboundary(repo, tr, phases.phasenames.index(phase),
55 55 csetres['nodesbyphase'][phase])
56 56
57 57 # Write bookmark updates.
58 58 bookmarks.updatefromremote(repo.ui, repo, csetres['bookmarks'],
59 59 remote.url(), pullop.gettransaction,
60 60 explicit=pullop.explicitbookmarks)
61 61
62 62 manres = _fetchmanifests(repo, tr, remote, csetres['manifestnodes'])
63 63
64 64 # Find all file nodes referenced by added manifests and fetch those
65 65 # revisions.
66 66 fnodes = _derivefilesfrommanifests(repo, manres['added'])
67 67 _fetchfiles(repo, tr, remote, fnodes, manres['linkrevs'])
68 68
69 69 def _pullchangesetdiscovery(repo, remote, heads, abortwhenunrelated=True):
70 70 """Determine which changesets need to be pulled."""
71 71
72 72 if heads:
73 73 knownnode = repo.changelog.hasnode
74 74 if all(knownnode(head) for head in heads):
75 75 return heads, False, heads
76 76
77 77 # TODO wire protocol version 2 is capable of more efficient discovery
78 78 # than setdiscovery. Consider implementing something better.
79 79 common, fetch, remoteheads = setdiscovery.findcommonheads(
80 80 repo.ui, repo, remote, abortwhenunrelated=abortwhenunrelated)
81 81
82 82 common = set(common)
83 83 remoteheads = set(remoteheads)
84 84
85 85 # If a remote head is filtered locally, put it back in the common set.
86 86 # See the comment in exchange._pulldiscoverychangegroup() for more.
87 87
88 88 if fetch and remoteheads:
89 89 nodemap = repo.unfiltered().changelog.nodemap
90 90
91 91 common |= {head for head in remoteheads if head in nodemap}
92 92
93 93 if set(remoteheads).issubset(common):
94 94 fetch = []
95 95
96 96 common.discard(nullid)
97 97
98 98 return common, fetch, remoteheads
99 99
100 100 def _fetchchangesets(repo, tr, remote, common, fetch, remoteheads):
101 101 # TODO consider adding a step here where we obtain the DAG shape first
102 102 # (or ask the server to slice changesets into chunks for us) so that
103 103 # we can perform multiple fetches in batches. This will facilitate
104 104 # resuming interrupted clones, higher server-side cache hit rates due
105 105 # to smaller segments, etc.
106 106 with remote.commandexecutor() as e:
107 107 objs = e.callcommand(b'changesetdata', {
108 108 b'noderange': [sorted(common), sorted(remoteheads)],
109 109 b'fields': {b'bookmarks', b'parents', b'phase', b'revision'},
110 110 }).result()
111 111
112 112 # The context manager waits on all response data when exiting. So
113 113 # we need to remain in the context manager in order to stream data.
114 114 return _processchangesetdata(repo, tr, objs)
115 115
116 116 def _processchangesetdata(repo, tr, objs):
117 117 repo.hook('prechangegroup', throw=True,
118 118 **pycompat.strkwargs(tr.hookargs))
119 119
120 120 urepo = repo.unfiltered()
121 121 cl = urepo.changelog
122 122
123 123 cl.delayupdate(tr)
124 124
125 125 # The first emitted object is a header describing the data that
126 126 # follows.
127 127 meta = next(objs)
128 128
129 129 progress = repo.ui.makeprogress(_('changesets'),
130 130 unit=_('chunks'),
131 131 total=meta.get(b'totalitems'))
132 132
133 133 manifestnodes = {}
134 134
135 135 def linkrev(node):
136 136 repo.ui.debug('add changeset %s\n' % short(node))
137 137 # Linkrev for changelog is always self.
138 138 return len(cl)
139 139
140 140 def onchangeset(cl, node):
141 141 progress.increment()
142 142
143 143 revision = cl.changelogrevision(node)
144 144
145 145 # We need to preserve the mapping of changelog revision to node
146 146 # so we can set the linkrev accordingly when manifests are added.
147 147 manifestnodes[cl.rev(node)] = revision.manifest
148 148
149 149 nodesbyphase = {phase: set() for phase in phases.phasenames}
150 150 remotebookmarks = {}
151 151
152 152 # addgroup() expects a 7-tuple describing revisions. This normalizes
153 153 # the wire data to that format.
154 154 #
155 155 # This loop also aggregates non-revision metadata, such as phase
156 156 # data.
157 157 def iterrevisions():
158 158 for cset in objs:
159 159 node = cset[b'node']
160 160
161 161 if b'phase' in cset:
162 162 nodesbyphase[cset[b'phase']].add(node)
163 163
164 164 for mark in cset.get(b'bookmarks', []):
165 165 remotebookmarks[mark] = node
166 166
167 167 # TODO add mechanism for extensions to examine records so they
168 168 # can siphon off custom data fields.
169 169
170 extrafields = {}
171
172 for field, size in cset.get(b'fieldsfollowing', []):
173 extrafields[field] = next(objs)
174
170 175 # Some entries might only be metadata only updates.
171 if b'revisionsize' not in cset:
176 if b'revision' not in extrafields:
172 177 continue
173 178
174 data = next(objs)
179 data = extrafields[b'revision']
175 180
176 181 yield (
177 182 node,
178 183 cset[b'parents'][0],
179 184 cset[b'parents'][1],
180 185 # Linknode is always itself for changesets.
181 186 cset[b'node'],
182 187 # We always send full revisions. So delta base is not set.
183 188 nullid,
184 189 mdiff.trivialdiffheader(len(data)) + data,
185 190 # Flags not yet supported.
186 191 0,
187 192 )
188 193
189 194 added = cl.addgroup(iterrevisions(), linkrev, weakref.proxy(tr),
190 195 addrevisioncb=onchangeset)
191 196
192 197 progress.complete()
193 198
194 199 return {
195 200 'added': added,
196 201 'nodesbyphase': nodesbyphase,
197 202 'bookmarks': remotebookmarks,
198 203 'manifestnodes': manifestnodes,
199 204 }
200 205
201 206 def _fetchmanifests(repo, tr, remote, manifestnodes):
202 207 rootmanifest = repo.manifestlog.getstorage(b'')
203 208
204 209 # Some manifests can be shared between changesets. Filter out revisions
205 210 # we already know about.
206 211 fetchnodes = []
207 212 linkrevs = {}
208 213 seen = set()
209 214
210 215 for clrev, node in sorted(manifestnodes.iteritems()):
211 216 if node in seen:
212 217 continue
213 218
214 219 try:
215 220 rootmanifest.rev(node)
216 221 except error.LookupError:
217 222 fetchnodes.append(node)
218 223 linkrevs[node] = clrev
219 224
220 225 seen.add(node)
221 226
222 227 # TODO handle tree manifests
223 228
224 229 # addgroup() expects 7-tuple describing revisions. This normalizes
225 230 # the wire data to that format.
226 231 def iterrevisions(objs, progress):
227 232 for manifest in objs:
228 233 node = manifest[b'node']
229 234
230 if b'deltasize' in manifest:
235 extrafields = {}
236
237 for field, size in manifest.get(b'fieldsfollowing', []):
238 extrafields[field] = next(objs)
239
240 if b'delta' in extrafields:
231 241 basenode = manifest[b'deltabasenode']
232 delta = next(objs)
233 elif b'revisionsize' in manifest:
242 delta = extrafields[b'delta']
243 elif b'revision' in extrafields:
234 244 basenode = nullid
235 revision = next(objs)
245 revision = extrafields[b'revision']
236 246 delta = mdiff.trivialdiffheader(len(revision)) + revision
237 247 else:
238 248 continue
239 249
240 250 yield (
241 251 node,
242 252 manifest[b'parents'][0],
243 253 manifest[b'parents'][1],
244 254 # The value passed in is passed to the lookup function passed
245 255 # to addgroup(). We already have a map of manifest node to
246 256 # changelog revision number. So we just pass in the
247 257 # manifest node here and use linkrevs.__getitem__ as the
248 258 # resolution function.
249 259 node,
250 260 basenode,
251 261 delta,
252 262 # Flags not yet supported.
253 263 0
254 264 )
255 265
256 266 progress.increment()
257 267
258 268 progress = repo.ui.makeprogress(_('manifests'), unit=_('chunks'),
259 269 total=len(fetchnodes))
260 270
261 271 # Fetch manifests 10,000 per command.
262 272 # TODO have server advertise preferences?
263 273 # TODO make size configurable on client?
264 274 batchsize = 10000
265 275
266 276 # We send commands 1 at a time to the remote. This is not the most
267 277 # efficient because we incur a round trip at the end of each batch.
268 278 # However, the existing frame-based reactor keeps consuming server
269 279 # data in the background. And this results in response data buffering
270 280 # in memory. This can consume gigabytes of memory.
271 281 # TODO send multiple commands in a request once background buffering
272 282 # issues are resolved.
273 283
274 284 added = []
275 285
276 286 for i in pycompat.xrange(0, len(fetchnodes), batchsize):
277 287 batch = [node for node in fetchnodes[i:i + batchsize]]
278 288 if not batch:
279 289 continue
280 290
281 291 with remote.commandexecutor() as e:
282 292 objs = e.callcommand(b'manifestdata', {
283 293 b'tree': b'',
284 294 b'nodes': batch,
285 295 b'fields': {b'parents', b'revision'},
286 296 b'haveparents': True,
287 297 }).result()
288 298
289 299 # Chomp off header object.
290 300 next(objs)
291 301
292 302 added.extend(rootmanifest.addgroup(
293 303 iterrevisions(objs, progress),
294 304 linkrevs.__getitem__,
295 305 weakref.proxy(tr)))
296 306
297 307 progress.complete()
298 308
299 309 return {
300 310 'added': added,
301 311 'linkrevs': linkrevs,
302 312 }
303 313
304 314 def _derivefilesfrommanifests(repo, manifestnodes):
305 315 """Determine what file nodes are relevant given a set of manifest nodes.
306 316
307 317 Returns a dict mapping file paths to dicts of file node to first manifest
308 318 node.
309 319 """
310 320 ml = repo.manifestlog
311 321 fnodes = collections.defaultdict(dict)
312 322
313 323 for manifestnode in manifestnodes:
314 324 m = ml.get(b'', manifestnode)
315 325
316 326 # TODO this will pull in unwanted nodes because it takes the storage
317 327 # delta into consideration. What we really want is something that takes
318 328 # the delta between the manifest's parents. And ideally we would
319 329 # ignore file nodes that are known locally. For now, ignore both
320 330 # these limitations. This will result in incremental fetches requesting
321 331 # data we already have. So this is far from ideal.
322 332 md = m.readfast()
323 333
324 334 for path, fnode in md.items():
325 335 fnodes[path].setdefault(fnode, manifestnode)
326 336
327 337 return fnodes
328 338
329 339 def _fetchfiles(repo, tr, remote, fnodes, linkrevs):
330 340 def iterrevisions(objs, progress):
331 341 for filerevision in objs:
332 342 node = filerevision[b'node']
333 343
334 if b'deltasize' in filerevision:
344 extrafields = {}
345
346 for field, size in filerevision.get(b'fieldsfollowing', []):
347 extrafields[field] = next(objs)
348
349 if b'delta' in extrafields:
335 350 basenode = filerevision[b'deltabasenode']
336 delta = next(objs)
337 elif b'revisionsize' in filerevision:
351 delta = extrafields[b'delta']
352 elif b'revision' in extrafields:
338 353 basenode = nullid
339 revision = next(objs)
354 revision = extrafields[b'revision']
340 355 delta = mdiff.trivialdiffheader(len(revision)) + revision
341 356 else:
342 357 continue
343 358
344 359 yield (
345 360 node,
346 361 filerevision[b'parents'][0],
347 362 filerevision[b'parents'][1],
348 363 node,
349 364 basenode,
350 365 delta,
351 366 # Flags not yet supported.
352 367 0,
353 368 )
354 369
355 370 progress.increment()
356 371
357 372 progress = repo.ui.makeprogress(
358 373 _('files'), unit=_('chunks'),
359 374 total=sum(len(v) for v in fnodes.itervalues()))
360 375
361 376 # TODO make batch size configurable
362 377 batchsize = 10000
363 378 fnodeslist = [x for x in sorted(fnodes.items())]
364 379
365 380 for i in pycompat.xrange(0, len(fnodeslist), batchsize):
366 381 batch = [x for x in fnodeslist[i:i + batchsize]]
367 382 if not batch:
368 383 continue
369 384
370 385 with remote.commandexecutor() as e:
371 386 fs = []
372 387 locallinkrevs = {}
373 388
374 389 for path, nodes in batch:
375 390 fs.append((path, e.callcommand(b'filedata', {
376 391 b'path': path,
377 392 b'nodes': sorted(nodes),
378 393 b'fields': {b'parents', b'revision'},
379 394 b'haveparents': True,
380 395 })))
381 396
382 397 locallinkrevs[path] = {
383 398 node: linkrevs[manifestnode]
384 399 for node, manifestnode in nodes.iteritems()}
385 400
386 401 for path, f in fs:
387 402 objs = f.result()
388 403
389 404 # Chomp off header objects.
390 405 next(objs)
391 406
392 407 store = repo.file(path)
393 408 store.addgroup(
394 409 iterrevisions(objs, progress),
395 410 locallinkrevs[path].__getitem__,
396 411 weakref.proxy(tr))
@@ -1,464 +1,501 b''
1 1 **Experimental and under active development**
2 2
3 3 This section documents the wire protocol commands exposed to transports
4 4 using the frame-based protocol. The set of commands exposed through
5 5 these transports is distinct from the set of commands exposed to legacy
6 6 transports.
7 7
8 8 The frame-based protocol uses CBOR to encode command execution requests.
9 9 All command arguments must be mapped to a specific or set of CBOR data
10 10 types.
11 11
12 12 The response to many commands is also CBOR. There is no common response
13 13 format: each command defines its own response format.
14 14
15 15 TODOs
16 16 =====
17 17
18 18 * Add "node namespace" support to each command. In order to support
19 19 SHA-1 hash transition, we want servers to be able to expose different
20 20 "node namespaces" for the same data. Every command operating on nodes
21 21 should specify which "node namespace" it is operating on and responses
22 22 should encode the "node namespace" accordingly.
23 23
24 24 Commands
25 25 ========
26 26
27 27 The sections below detail all commands available to wire protocol version
28 28 2.
29 29
30 30 branchmap
31 31 ---------
32 32
33 33 Obtain heads in named branches.
34 34
35 35 Receives no arguments.
36 36
37 37 The response is a map with bytestring keys defining the branch name.
38 38 Values are arrays of bytestring defining raw changeset nodes.
39 39
40 40 capabilities
41 41 ------------
42 42
43 43 Obtain the server's capabilities.
44 44
45 45 Receives no arguments.
46 46
47 47 This command is typically called only as part of the handshake during
48 48 initial connection establishment.
49 49
50 50 The response is a map with bytestring keys defining server information.
51 51
52 52 The defined keys are:
53 53
54 54 commands
55 55 A map defining available wire protocol commands on this server.
56 56
57 57 Keys in the map are the names of commands that can be invoked. Values
58 58 are maps defining information about that command. The bytestring keys
59 59 are:
60 60
61 61 args
62 62 (map) Describes arguments accepted by the command.
63 63
64 64 Keys are bytestrings denoting the argument name.
65 65
66 66 Values are maps describing the argument. The map has the following
67 67 bytestring keys:
68 68
69 69 default
70 70 (varied) The default value for this argument if not specified. Only
71 71 present if ``required`` is not true.
72 72
73 73 required
74 74 (boolean) Whether the argument must be specified. Failure to send
75 75 required arguments will result in an error executing the command.
76 76
77 77 type
78 78 (bytestring) The type of the argument. e.g. ``bytes`` or ``bool``.
79 79
80 80 validvalues
81 81 (set) Values that are recognized for this argument. Some arguments
82 82 only allow a fixed set of values to be specified. These arguments
83 83 may advertise that set in this key. If this set is advertised and
84 84 a value not in this set is specified, the command should result
85 85 in error.
86 86
87 87 permissions
88 88 An array of permissions required to execute this command.
89 89
90 90 compression
91 91 An array of maps defining available compression format support.
92 92
93 93 The array is sorted from most preferred to least preferred.
94 94
95 95 Each entry has the following bytestring keys:
96 96
97 97 name
98 98 Name of the compression engine. e.g. ``zstd`` or ``zlib``.
99 99
100 100 framingmediatypes
101 101 An array of bytestrings defining the supported framing protocol
102 102 media types. Servers will not accept media types not in this list.
103 103
104 104 pathfilterprefixes
105 105 (set of bytestring) Matcher prefixes that are recognized when performing
106 106 path filtering. Specifying a path filter whose type/prefix does not
107 107 match one in this set will likely be rejected by the server.
108 108
109 109 rawrepoformats
110 110 An array of storage formats the repository is using. This set of
111 111 requirements can be used to determine whether a client can read a
112 112 *raw* copy of file data available.
113 113
114 114 changesetdata
115 115 -------------
116 116
117 117 Obtain various data related to changesets.
118 118
119 119 The command accepts the following arguments:
120 120
121 121 noderange
122 122 (array of arrays of bytestrings) An array of 2 elements, each being an
123 123 array of node bytestrings. The first array denotes the changelog revisions
124 124 that are already known to the client. The second array denotes the changelog
125 125 revision DAG heads to fetch. The argument essentially defines a DAG range
126 126 bounded by root and head nodes to fetch.
127 127
128 128 The roots array may be empty. The heads array must be defined.
129 129
130 130 nodes
131 131 (array of bytestrings) Changelog revisions to request explicitly.
132 132
133 133 fields
134 134 (set of bytestring) Which data associated with changelog revisions to
135 135 fetch. The following values are recognized:
136 136
137 137 bookmarks
138 138 Bookmarks associated with a revision.
139 139
140 140 parents
141 141 Parent revisions.
142 142
143 143 phase
144 144 The phase state of a revision.
145 145
146 146 revision
147 147 The raw, revision data for the changelog entry. The hash of this data
148 148 will match the revision's node value.
149 149
150 150 The server resolves the set of revisions relevant to the request by taking
151 151 the union of the ``noderange`` and ``nodes`` arguments. At least one of these
152 152 arguments must be defined.
153 153
154 154 The response bytestream starts with a CBOR map describing the data that follows.
155 155 This map has the following bytestring keys:
156 156
157 157 totalitems
158 158 (unsigned integer) Total number of changelog revisions whose data is being
159 159 transferred. This maps to the set of revisions in the requested node
160 160 range, not the total number of records that follow (see below for why).
161 161
162 162 Following the map header is a series of 0 or more CBOR values. If values
163 163 are present, the first value will always be a map describing a single changeset
164 revision. If revision data is requested, the raw revision data (encoded as
165 a CBOR bytestring) will follow the map describing it. Otherwise, another CBOR
166 map describing the next changeset revision will occur.
164 revision.
167 165
168 Each map has the following bytestring keys:
166 If the ``fieldsfollowing`` key is present, the map will immediately be followed
167 by N CBOR bytestring values, where N is the number of elements in
168 ``fieldsfollowing``. Each bytestring value corresponds to a field denoted
169 by ``fieldsfollowing``.
170
171 Following the optional bytestring field values is the next revision descriptor
172 map, or end of stream.
173
174 Each revision descriptor map has the following bytestring keys:
169 175
170 176 node
171 177 (bytestring) The node value for this revision. This is the SHA-1 hash of
172 178 the raw revision data.
173 179
174 180 bookmarks (optional)
175 181 (array of bytestrings) Bookmarks attached to this revision. Only present
176 182 if ``bookmarks`` data is being requested and the revision has bookmarks
177 183 attached.
178 184
185 fieldsfollowing (optional)
186 (array of 2-array) Denotes what fields immediately follow this map. Each
187 value is an array with 2 elements: the bytestring field name and an unsigned
188 integer describing the length of the data, in bytes.
189
190 If this key isn't present, no special fields will follow this map.
191
192 The following fields may be present:
193
194 revision
195 Raw, revision data for the changelog entry. Contains a serialized form
196 of the changeset data, including the author, date, commit message, set
197 of changed files, manifest node, and other metadata.
198
199 Only present if the ``revision`` field was requested.
200
179 201 parents (optional)
180 202 (array of bytestrings) The nodes representing the parent revisions of this
181 203 revision. Only present if ``parents`` data is being requested.
182 204
183 205 phase (optional)
184 206 (bytestring) The phase that a revision is in. Recognized values are
185 207 ``secret``, ``draft``, and ``public``. Only present if ``phase`` data
186 208 is being requested.
187 209
188 revisionsize (optional)
189 (unsigned integer) Indicates the size of raw revision data that follows this
190 map. The following data contains a serialized form of the changeset data,
191 including the author, date, commit message, set of changed files, manifest
192 node, and other metadata.
193
194 Only present if ``revision`` data was requested and the data follows this
195 map.
196
197 210 If nodes are requested via ``noderange``, they will be emitted in DAG order,
198 211 parents always before children.
199 212
200 213 If nodes are requested via ``nodes``, they will be emitted in requested order.
201 214
202 215 Nodes from ``nodes`` are emitted before nodes from ``noderange``.
203 216
204 217 The set of changeset revisions emitted may not match the exact set of
205 218 changesets requested. Furthermore, the set of keys present on each
206 219 map may vary. This is to facilitate emitting changeset updates as well
207 220 as new revisions.
208 221
209 222 For example, if the request wants ``phase`` and ``revision`` data,
210 223 the response may contain entries for each changeset in the common nodes
211 224 set with the ``phase`` key and without the ``revision`` key in order
212 225 to reflect a phase-only update.
213 226
214 227 TODO support different revision selection mechanisms (e.g. non-public, specific
215 228 revisions)
216 229 TODO support different hash "namespaces" for revisions (e.g. sha-1 versus other)
217 230 TODO support emitting obsolescence data
218 231 TODO support filtering based on relevant paths (narrow clone)
219 232 TODO support depth limiting
220 233 TODO support hgtagsfnodes cache / tags data
221 234 TODO support branch heads cache
222 235
223 236 filedata
224 237 --------
225 238
226 239 Obtain various data related to an individual tracked file.
227 240
228 241 The command accepts the following arguments:
229 242
230 243 fields
231 244 (set of bytestring) Which data associated with a file to fetch.
232 245 The following values are recognized:
233 246
234 247 parents
235 248 Parent nodes for the revision.
236 249
237 250 revision
238 251 The raw revision data for a file.
239 252
240 253 haveparents
241 254 (bool) Whether the client has the parent revisions of all requested
242 255 nodes. If set, the server may emit revision data as deltas against
243 256 any parent revision. If not set, the server MUST only emit deltas for
244 257 revisions previously emitted by this command.
245 258
246 259 False is assumed in the absence of any value.
247 260
248 261 nodes
249 262 (array of bytestrings) File nodes whose data to retrieve.
250 263
251 264 path
252 265 (bytestring) Path of the tracked file whose data to retrieve.
253 266
254 267 TODO allow specifying revisions via alternate means (such as from
255 268 changeset revisions or ranges)
256 269
257 270 The response bytestream starts with a CBOR map describing the data that
258 271 follows. It has the following bytestream keys:
259 272
260 273 totalitems
261 274 (unsigned integer) Total number of file revisions whose data is
262 275 being returned.
263 276
264 Following the header map is a series of 0 or more CBOR values. The first
265 value is always a map describing a file revision. If this map has the
266 ``deltasize`` or ``revisionsize`` keys, a bytestring containing the delta
267 or revision, respectively, will immediately follow the map. Otherwise
268 the next value will be a map describing the next file revision.
277 Following the map header is a series of 0 or more CBOR values. If values
278 are present, the first value will always be a map describing a single changeset
279 revision.
280
281 If the ``fieldsfollowing`` key is present, the map will immediately be followed
282 by N CBOR bytestring values, where N is the number of elements in
283 ``fieldsfollowing``. Each bytestring value corresponds to a field denoted
284 by ``fieldsfollowing``.
285
286 Following the optional bytestring field values is the next revision descriptor
287 map, or end of stream.
288
289 Each revision descriptor map has the following bytestring keys:
269 290
270 291 Each map has the following bytestring keys:
271 292
272 293 node
273 294 (bytestring) The node of the file revision whose data is represented.
274 295
275 296 deltabasenode
276 297 (bytestring) Node of the file revision the following delta is against.
277 298
278 299 Only present if the ``revision`` field is requested and delta data
279 300 follows this map.
280 301
281 deltasize
282 (unsigned integer) The size of the delta data that follows this map.
302 fieldsfollowing
303 (array of 2-array) Denotes extra bytestring fields that following this map.
304 See the documentation for ``changesetdata`` for semantics.
305
306 The following named fields may be present:
283 307
284 Only present if the ``revision`` field is requested and delta data
285 follows this map.
308 ``delta``
309 The delta data to use to construct the fulltext revision.
310
311 Only present if the ``revision`` field is requested and a delta is
312 being emitted. The ``deltabasenode`` top-level key will also be
313 present if this field is being emitted.
314
315 ``revision``
316 The fulltext revision data for this manifest. Only present if the
317 ``revision`` field is requested and a fulltext revision is being emitted.
286 318
287 319 parents
288 320 (array of bytestring) The nodes of the parents of this file revision.
289 321
290 322 Only present if the ``parents`` field is requested.
291 323
292 revisionsize
293 (unsigned integer) The size of the fulltext revision data that follows
294 this map.
295
296 Only present if the ``revision`` field is requested and fulltext revision
297 data follows this map.
298
299 324 When ``revision`` data is requested, the server chooses to emit either fulltext
300 325 revision data or a delta. What the server decides can be inferred by looking
301 for the presence of the ``deltasize`` or ``revisionsize`` keys in the map.
302 Servers MUST NOT define both keys.
326 for the presence of the ``delta`` or ``revision`` keys in the
327 ``fieldsfollowing`` array.
303 328
304 329 heads
305 330 -----
306 331
307 332 Obtain DAG heads in the repository.
308 333
309 334 The command accepts the following arguments:
310 335
311 336 publiconly (optional)
312 337 (boolean) If set, operate on the DAG for public phase changesets only.
313 338 Non-public (i.e. draft) phase DAG heads will not be returned.
314 339
315 340 The response is a CBOR array of bytestrings defining changeset nodes
316 341 of DAG heads. The array can be empty if the repository is empty or no
317 342 changesets satisfied the request.
318 343
319 344 TODO consider exposing phase of heads in response
320 345
321 346 known
322 347 -----
323 348
324 349 Determine whether a series of changeset nodes is known to the server.
325 350
326 351 The command accepts the following arguments:
327 352
328 353 nodes
329 354 (array of bytestrings) List of changeset nodes whose presence to
330 355 query.
331 356
332 357 The response is a bytestring where each byte contains a 0 or 1 for the
333 358 corresponding requested node at the same index.
334 359
335 360 TODO use a bit array for even more compact response
336 361
337 362 listkeys
338 363 --------
339 364
340 365 List values in a specified ``pushkey`` namespace.
341 366
342 367 The command receives the following arguments:
343 368
344 369 namespace
345 370 (bytestring) Pushkey namespace to query.
346 371
347 372 The response is a map with bytestring keys and values.
348 373
349 374 TODO consider using binary to represent nodes in certain pushkey namespaces.
350 375
351 376 lookup
352 377 ------
353 378
354 379 Try to resolve a value to a changeset revision.
355 380
356 381 Unlike ``known`` which operates on changeset nodes, lookup operates on
357 382 node fragments and other names that a user may use.
358 383
359 384 The command receives the following arguments:
360 385
361 386 key
362 387 (bytestring) Value to try to resolve.
363 388
364 389 On success, returns a bytestring containing the resolved node.
365 390
366 391 manifestdata
367 392 ------------
368 393
369 394 Obtain various data related to manifests (which are lists of files in
370 395 a revision).
371 396
372 397 The command accepts the following arguments:
373 398
374 399 fields
375 400 (set of bytestring) Which data associated with manifests to fetch.
376 401 The following values are recognized:
377 402
378 403 parents
379 404 Parent nodes for the manifest.
380 405
381 406 revision
382 407 The raw revision data for the manifest.
383 408
384 409 haveparents
385 410 (bool) Whether the client has the parent revisions of all requested
386 411 nodes. If set, the server may emit revision data as deltas against
387 412 any parent revision. If not set, the server MUST only emit deltas for
388 413 revisions previously emitted by this command.
389 414
390 415 False is assumed in the absence of any value.
391 416
392 417 nodes
393 418 (array of bytestring) Manifest nodes whose data to retrieve.
394 419
395 420 tree
396 421 (bytestring) Path to manifest to retrieve. The empty bytestring represents
397 422 the root manifest. All other values represent directories/trees within
398 423 the repository.
399 424
400 425 TODO allow specifying revisions via alternate means (such as from changeset
401 426 revisions or ranges)
402 427 TODO consider recursive expansion of manifests (with path filtering for
403 428 narrow use cases)
404 429
405 430 The response bytestream starts with a CBOR map describing the data that
406 431 follows. It has the following bytestring keys:
407 432
408 433 totalitems
409 434 (unsigned integer) Total number of manifest revisions whose data is
410 435 being returned.
411 436
412 Following the header map is a series of 0 or more CBOR values. The first
413 value is always a map describing a manifest revision. If this map has the
414 ``deltasize`` or ``revisionsize`` keys, a bytestring containing the delta
415 or revision, respectively, will immediately follow the map. Otherwise
416 the next value will be a map describing the next manifest revision.
437 Following the map header is a series of 0 or more CBOR values. If values
438 are present, the first value will always be a map describing a single manifest
439 revision.
417 440
418 Each map has the following bytestring keys:
441 If the ``fieldsfollowing`` key is present, the map will immediately be followed
442 by N CBOR bytestring values, where N is the number of elements in
443 ``fieldsfollowing``. Each bytestring value corresponds to a field denoted
444 by ``fieldsfollowing``.
445
446 Following the optional bytestring field values is the next revision descriptor
447 map, or end of stream.
448
449 Each revision descriptor map has the following bytestring keys:
419 450
420 451 node
421 452 (bytestring) The node of the manifest revision whose data is represented.
422 453
423 454 deltabasenode
424 455 (bytestring) The node that the delta representation of this revision is
425 456 computed against. Only present if the ``revision`` field is requested and
426 457 a delta is being emitted.
427 458
428 deltasize
429 (unsigned integer) The size of the delta data that follows this map.
430 Only present if the ``revision`` field is requested and a delta is
431 being emitted.
459 fieldsfollowing
460 (array of 2-array) Denotes extra bytestring fields that following this map.
461 See the documentation for ``changesetdata`` for semantics.
462
463 The following named fields may be present:
464
465 ``delta``
466 The delta data to use to construct the fulltext revision.
467
468 Only present if the ``revision`` field is requested and a delta is
469 being emitted. The ``deltabasenode`` top-level key will also be
470 present if this field is being emitted.
471
472 ``revision``
473 The fulltext revision data for this manifest. Only present if the
474 ``revision`` field is requested and a fulltext revision is being emitted.
432 475
433 476 parents
434 477 (array of bytestring) The nodes of the parents of this manifest revision.
435 478 Only present if the ``parents`` field is requested.
436 479
437 revisionsize
438 (unsigned integer) The size of the fulltext revision data that follows
439 this map. Only present if the ``revision`` field is requested and a fulltext
440 revision is being emitted.
441
442 480 When ``revision`` data is requested, the server chooses to emit either fulltext
443 481 revision data or a delta. What the server decides can be inferred by looking
444 for the presence of the ``deltasize`` or ``revisionsize`` keys in the map.
445 Servers MUST NOT define both keys.
482 for the presence of ``delta`` or ``revision`` in the ``fieldsfollowing`` array.
446 483
447 484 pushkey
448 485 -------
449 486
450 487 Set a value using the ``pushkey`` protocol.
451 488
452 489 The command receives the following arguments:
453 490
454 491 namespace
455 492 (bytestring) Pushkey namespace to operate on.
456 493 key
457 494 (bytestring) The pushkey key to set.
458 495 old
459 496 (bytestring) Old value for this key.
460 497 new
461 498 (bytestring) New value for this key.
462 499
463 500 TODO consider using binary to represent nodes is certain pushkey namespaces.
464 501 TODO better define response type and meaning.
@@ -1,354 +1,354 b''
1 1 # Copyright 2018 Gregory Szorc <gregory.szorc@gmail.com>
2 2 #
3 3 # This software may be used and distributed according to the terms of the
4 4 # GNU General Public License version 2 or any later version.
5 5
6 6 from __future__ import absolute_import
7 7
8 8 from .node import (
9 9 bin,
10 10 hex,
11 11 )
12 12 from .i18n import _
13 13 from . import (
14 14 error,
15 15 util,
16 16 )
17 17 from .utils import (
18 18 interfaceutil,
19 19 )
20 20
21 21 # Names of the SSH protocol implementations.
22 22 SSHV1 = 'ssh-v1'
23 23 # These are advertised over the wire. Increment the counters at the end
24 24 # to reflect BC breakages.
25 SSHV2 = 'exp-ssh-v2-0001'
26 HTTP_WIREPROTO_V2 = 'exp-http-v2-0001'
25 SSHV2 = 'exp-ssh-v2-0002'
26 HTTP_WIREPROTO_V2 = 'exp-http-v2-0002'
27 27
28 28 # All available wire protocol transports.
29 29 TRANSPORTS = {
30 30 SSHV1: {
31 31 'transport': 'ssh',
32 32 'version': 1,
33 33 },
34 34 SSHV2: {
35 35 'transport': 'ssh',
36 36 # TODO mark as version 2 once all commands are implemented.
37 37 'version': 1,
38 38 },
39 39 'http-v1': {
40 40 'transport': 'http',
41 41 'version': 1,
42 42 },
43 43 HTTP_WIREPROTO_V2: {
44 44 'transport': 'http',
45 45 'version': 2,
46 46 }
47 47 }
48 48
49 49 class bytesresponse(object):
50 50 """A wire protocol response consisting of raw bytes."""
51 51 def __init__(self, data):
52 52 self.data = data
53 53
54 54 class ooberror(object):
55 55 """wireproto reply: failure of a batch of operation
56 56
57 57 Something failed during a batch call. The error message is stored in
58 58 `self.message`.
59 59 """
60 60 def __init__(self, message):
61 61 self.message = message
62 62
63 63 class pushres(object):
64 64 """wireproto reply: success with simple integer return
65 65
66 66 The call was successful and returned an integer contained in `self.res`.
67 67 """
68 68 def __init__(self, res, output):
69 69 self.res = res
70 70 self.output = output
71 71
72 72 class pusherr(object):
73 73 """wireproto reply: failure
74 74
75 75 The call failed. The `self.res` attribute contains the error message.
76 76 """
77 77 def __init__(self, res, output):
78 78 self.res = res
79 79 self.output = output
80 80
81 81 class streamres(object):
82 82 """wireproto reply: binary stream
83 83
84 84 The call was successful and the result is a stream.
85 85
86 86 Accepts a generator containing chunks of data to be sent to the client.
87 87
88 88 ``prefer_uncompressed`` indicates that the data is expected to be
89 89 uncompressable and that the stream should therefore use the ``none``
90 90 engine.
91 91 """
92 92 def __init__(self, gen=None, prefer_uncompressed=False):
93 93 self.gen = gen
94 94 self.prefer_uncompressed = prefer_uncompressed
95 95
96 96 class streamreslegacy(object):
97 97 """wireproto reply: uncompressed binary stream
98 98
99 99 The call was successful and the result is a stream.
100 100
101 101 Accepts a generator containing chunks of data to be sent to the client.
102 102
103 103 Like ``streamres``, but sends an uncompressed data for "version 1" clients
104 104 using the application/mercurial-0.1 media type.
105 105 """
106 106 def __init__(self, gen=None):
107 107 self.gen = gen
108 108
109 109 # list of nodes encoding / decoding
110 110 def decodelist(l, sep=' '):
111 111 if l:
112 112 return [bin(v) for v in l.split(sep)]
113 113 return []
114 114
115 115 def encodelist(l, sep=' '):
116 116 try:
117 117 return sep.join(map(hex, l))
118 118 except TypeError:
119 119 raise
120 120
121 121 # batched call argument encoding
122 122
123 123 def escapebatcharg(plain):
124 124 return (plain
125 125 .replace(':', ':c')
126 126 .replace(',', ':o')
127 127 .replace(';', ':s')
128 128 .replace('=', ':e'))
129 129
130 130 def unescapebatcharg(escaped):
131 131 return (escaped
132 132 .replace(':e', '=')
133 133 .replace(':s', ';')
134 134 .replace(':o', ',')
135 135 .replace(':c', ':'))
136 136
137 137 # mapping of options accepted by getbundle and their types
138 138 #
139 139 # Meant to be extended by extensions. It is extensions responsibility to ensure
140 140 # such options are properly processed in exchange.getbundle.
141 141 #
142 142 # supported types are:
143 143 #
144 144 # :nodes: list of binary nodes
145 145 # :csv: list of comma-separated values
146 146 # :scsv: list of comma-separated values return as set
147 147 # :plain: string with no transformation needed.
148 148 GETBUNDLE_ARGUMENTS = {
149 149 'heads': 'nodes',
150 150 'bookmarks': 'boolean',
151 151 'common': 'nodes',
152 152 'obsmarkers': 'boolean',
153 153 'phases': 'boolean',
154 154 'bundlecaps': 'scsv',
155 155 'listkeys': 'csv',
156 156 'cg': 'boolean',
157 157 'cbattempted': 'boolean',
158 158 'stream': 'boolean',
159 159 }
160 160
161 161 class baseprotocolhandler(interfaceutil.Interface):
162 162 """Abstract base class for wire protocol handlers.
163 163
164 164 A wire protocol handler serves as an interface between protocol command
165 165 handlers and the wire protocol transport layer. Protocol handlers provide
166 166 methods to read command arguments, redirect stdio for the duration of
167 167 the request, handle response types, etc.
168 168 """
169 169
170 170 name = interfaceutil.Attribute(
171 171 """The name of the protocol implementation.
172 172
173 173 Used for uniquely identifying the transport type.
174 174 """)
175 175
176 176 def getargs(args):
177 177 """return the value for arguments in <args>
178 178
179 179 For version 1 transports, returns a list of values in the same
180 180 order they appear in ``args``. For version 2 transports, returns
181 181 a dict mapping argument name to value.
182 182 """
183 183
184 184 def getprotocaps():
185 185 """Returns the list of protocol-level capabilities of client
186 186
187 187 Returns a list of capabilities as declared by the client for
188 188 the current request (or connection for stateful protocol handlers)."""
189 189
190 190 def getpayload():
191 191 """Provide a generator for the raw payload.
192 192
193 193 The caller is responsible for ensuring that the full payload is
194 194 processed.
195 195 """
196 196
197 197 def mayberedirectstdio():
198 198 """Context manager to possibly redirect stdio.
199 199
200 200 The context manager yields a file-object like object that receives
201 201 stdout and stderr output when the context manager is active. Or it
202 202 yields ``None`` if no I/O redirection occurs.
203 203
204 204 The intent of this context manager is to capture stdio output
205 205 so it may be sent in the response. Some transports support streaming
206 206 stdio to the client in real time. For these transports, stdio output
207 207 won't be captured.
208 208 """
209 209
210 210 def client():
211 211 """Returns a string representation of this client (as bytes)."""
212 212
213 213 def addcapabilities(repo, caps):
214 214 """Adds advertised capabilities specific to this protocol.
215 215
216 216 Receives the list of capabilities collected so far.
217 217
218 218 Returns a list of capabilities. The passed in argument can be returned.
219 219 """
220 220
221 221 def checkperm(perm):
222 222 """Validate that the client has permissions to perform a request.
223 223
224 224 The argument is the permission required to proceed. If the client
225 225 doesn't have that permission, the exception should raise or abort
226 226 in a protocol specific manner.
227 227 """
228 228
229 229 class commandentry(object):
230 230 """Represents a declared wire protocol command."""
231 231 def __init__(self, func, args='', transports=None,
232 232 permission='push'):
233 233 self.func = func
234 234 self.args = args
235 235 self.transports = transports or set()
236 236 self.permission = permission
237 237
238 238 def _merge(self, func, args):
239 239 """Merge this instance with an incoming 2-tuple.
240 240
241 241 This is called when a caller using the old 2-tuple API attempts
242 242 to replace an instance. The incoming values are merged with
243 243 data not captured by the 2-tuple and a new instance containing
244 244 the union of the two objects is returned.
245 245 """
246 246 return commandentry(func, args=args, transports=set(self.transports),
247 247 permission=self.permission)
248 248
249 249 # Old code treats instances as 2-tuples. So expose that interface.
250 250 def __iter__(self):
251 251 yield self.func
252 252 yield self.args
253 253
254 254 def __getitem__(self, i):
255 255 if i == 0:
256 256 return self.func
257 257 elif i == 1:
258 258 return self.args
259 259 else:
260 260 raise IndexError('can only access elements 0 and 1')
261 261
262 262 class commanddict(dict):
263 263 """Container for registered wire protocol commands.
264 264
265 265 It behaves like a dict. But __setitem__ is overwritten to allow silent
266 266 coercion of values from 2-tuples for API compatibility.
267 267 """
268 268 def __setitem__(self, k, v):
269 269 if isinstance(v, commandentry):
270 270 pass
271 271 # Cast 2-tuples to commandentry instances.
272 272 elif isinstance(v, tuple):
273 273 if len(v) != 2:
274 274 raise ValueError('command tuples must have exactly 2 elements')
275 275
276 276 # It is common for extensions to wrap wire protocol commands via
277 277 # e.g. ``wireproto.commands[x] = (newfn, args)``. Because callers
278 278 # doing this aren't aware of the new API that uses objects to store
279 279 # command entries, we automatically merge old state with new.
280 280 if k in self:
281 281 v = self[k]._merge(v[0], v[1])
282 282 else:
283 283 # Use default values from @wireprotocommand.
284 284 v = commandentry(v[0], args=v[1],
285 285 transports=set(TRANSPORTS),
286 286 permission='push')
287 287 else:
288 288 raise ValueError('command entries must be commandentry instances '
289 289 'or 2-tuples')
290 290
291 291 return super(commanddict, self).__setitem__(k, v)
292 292
293 293 def commandavailable(self, command, proto):
294 294 """Determine if a command is available for the requested protocol."""
295 295 assert proto.name in TRANSPORTS
296 296
297 297 entry = self.get(command)
298 298
299 299 if not entry:
300 300 return False
301 301
302 302 if proto.name not in entry.transports:
303 303 return False
304 304
305 305 return True
306 306
307 307 def supportedcompengines(ui, role):
308 308 """Obtain the list of supported compression engines for a request."""
309 309 assert role in (util.CLIENTROLE, util.SERVERROLE)
310 310
311 311 compengines = util.compengines.supportedwireengines(role)
312 312
313 313 # Allow config to override default list and ordering.
314 314 if role == util.SERVERROLE:
315 315 configengines = ui.configlist('server', 'compressionengines')
316 316 config = 'server.compressionengines'
317 317 else:
318 318 # This is currently implemented mainly to facilitate testing. In most
319 319 # cases, the server should be in charge of choosing a compression engine
320 320 # because a server has the most to lose from a sub-optimal choice. (e.g.
321 321 # CPU DoS due to an expensive engine or a network DoS due to poor
322 322 # compression ratio).
323 323 configengines = ui.configlist('experimental',
324 324 'clientcompressionengines')
325 325 config = 'experimental.clientcompressionengines'
326 326
327 327 # No explicit config. Filter out the ones that aren't supposed to be
328 328 # advertised and return default ordering.
329 329 if not configengines:
330 330 attr = 'serverpriority' if role == util.SERVERROLE else 'clientpriority'
331 331 return [e for e in compengines
332 332 if getattr(e.wireprotosupport(), attr) > 0]
333 333
334 334 # If compression engines are listed in the config, assume there is a good
335 335 # reason for it (like server operators wanting to achieve specific
336 336 # performance characteristics). So fail fast if the config references
337 337 # unusable compression engines.
338 338 validnames = set(e.name() for e in compengines)
339 339 invalidnames = set(e for e in configengines if e not in validnames)
340 340 if invalidnames:
341 341 raise error.Abort(_('invalid compression engine defined in %s: %s') %
342 342 (config, ', '.join(sorted(invalidnames))))
343 343
344 344 compengines = [e for e in compengines if e.name() in configengines]
345 345 compengines = sorted(compengines,
346 346 key=lambda e: configengines.index(e.name()))
347 347
348 348 if not compengines:
349 349 raise error.Abort(_('%s config option does not specify any known '
350 350 'compression engines') % config,
351 351 hint=_('usable compression engines: %s') %
352 352 ', '.sorted(validnames))
353 353
354 354 return compengines
@@ -1,1080 +1,1093 b''
1 1 # Copyright 21 May 2005 - (c) 2005 Jake Edge <jake@edge2.net>
2 2 # Copyright 2005-2007 Matt Mackall <mpm@selenic.com>
3 3 #
4 4 # This software may be used and distributed according to the terms of the
5 5 # GNU General Public License version 2 or any later version.
6 6
7 7 from __future__ import absolute_import
8 8
9 9 import contextlib
10 10
11 11 from .i18n import _
12 12 from .node import (
13 13 hex,
14 14 nullid,
15 15 nullrev,
16 16 )
17 17 from . import (
18 18 changegroup,
19 19 dagop,
20 20 discovery,
21 21 encoding,
22 22 error,
23 23 narrowspec,
24 24 pycompat,
25 25 streamclone,
26 26 util,
27 27 wireprotoframing,
28 28 wireprototypes,
29 29 )
30 30 from .utils import (
31 31 interfaceutil,
32 32 )
33 33
34 34 FRAMINGTYPE = b'application/mercurial-exp-framing-0005'
35 35
36 36 HTTP_WIREPROTO_V2 = wireprototypes.HTTP_WIREPROTO_V2
37 37
38 38 COMMANDS = wireprototypes.commanddict()
39 39
40 40 def handlehttpv2request(rctx, req, res, checkperm, urlparts):
41 41 from .hgweb import common as hgwebcommon
42 42
43 43 # URL space looks like: <permissions>/<command>, where <permission> can
44 44 # be ``ro`` or ``rw`` to signal read-only or read-write, respectively.
45 45
46 46 # Root URL does nothing meaningful... yet.
47 47 if not urlparts:
48 48 res.status = b'200 OK'
49 49 res.headers[b'Content-Type'] = b'text/plain'
50 50 res.setbodybytes(_('HTTP version 2 API handler'))
51 51 return
52 52
53 53 if len(urlparts) == 1:
54 54 res.status = b'404 Not Found'
55 55 res.headers[b'Content-Type'] = b'text/plain'
56 56 res.setbodybytes(_('do not know how to process %s\n') %
57 57 req.dispatchpath)
58 58 return
59 59
60 60 permission, command = urlparts[0:2]
61 61
62 62 if permission not in (b'ro', b'rw'):
63 63 res.status = b'404 Not Found'
64 64 res.headers[b'Content-Type'] = b'text/plain'
65 65 res.setbodybytes(_('unknown permission: %s') % permission)
66 66 return
67 67
68 68 if req.method != 'POST':
69 69 res.status = b'405 Method Not Allowed'
70 70 res.headers[b'Allow'] = b'POST'
71 71 res.setbodybytes(_('commands require POST requests'))
72 72 return
73 73
74 74 # At some point we'll want to use our own API instead of recycling the
75 75 # behavior of version 1 of the wire protocol...
76 76 # TODO return reasonable responses - not responses that overload the
77 77 # HTTP status line message for error reporting.
78 78 try:
79 79 checkperm(rctx, req, 'pull' if permission == b'ro' else 'push')
80 80 except hgwebcommon.ErrorResponse as e:
81 81 res.status = hgwebcommon.statusmessage(e.code, pycompat.bytestr(e))
82 82 for k, v in e.headers:
83 83 res.headers[k] = v
84 84 res.setbodybytes('permission denied')
85 85 return
86 86
87 87 # We have a special endpoint to reflect the request back at the client.
88 88 if command == b'debugreflect':
89 89 _processhttpv2reflectrequest(rctx.repo.ui, rctx.repo, req, res)
90 90 return
91 91
92 92 # Extra commands that we handle that aren't really wire protocol
93 93 # commands. Think extra hard before making this hackery available to
94 94 # extension.
95 95 extracommands = {'multirequest'}
96 96
97 97 if command not in COMMANDS and command not in extracommands:
98 98 res.status = b'404 Not Found'
99 99 res.headers[b'Content-Type'] = b'text/plain'
100 100 res.setbodybytes(_('unknown wire protocol command: %s\n') % command)
101 101 return
102 102
103 103 repo = rctx.repo
104 104 ui = repo.ui
105 105
106 106 proto = httpv2protocolhandler(req, ui)
107 107
108 108 if (not COMMANDS.commandavailable(command, proto)
109 109 and command not in extracommands):
110 110 res.status = b'404 Not Found'
111 111 res.headers[b'Content-Type'] = b'text/plain'
112 112 res.setbodybytes(_('invalid wire protocol command: %s') % command)
113 113 return
114 114
115 115 # TODO consider cases where proxies may add additional Accept headers.
116 116 if req.headers.get(b'Accept') != FRAMINGTYPE:
117 117 res.status = b'406 Not Acceptable'
118 118 res.headers[b'Content-Type'] = b'text/plain'
119 119 res.setbodybytes(_('client MUST specify Accept header with value: %s\n')
120 120 % FRAMINGTYPE)
121 121 return
122 122
123 123 if req.headers.get(b'Content-Type') != FRAMINGTYPE:
124 124 res.status = b'415 Unsupported Media Type'
125 125 # TODO we should send a response with appropriate media type,
126 126 # since client does Accept it.
127 127 res.headers[b'Content-Type'] = b'text/plain'
128 128 res.setbodybytes(_('client MUST send Content-Type header with '
129 129 'value: %s\n') % FRAMINGTYPE)
130 130 return
131 131
132 132 _processhttpv2request(ui, repo, req, res, permission, command, proto)
133 133
134 134 def _processhttpv2reflectrequest(ui, repo, req, res):
135 135 """Reads unified frame protocol request and dumps out state to client.
136 136
137 137 This special endpoint can be used to help debug the wire protocol.
138 138
139 139 Instead of routing the request through the normal dispatch mechanism,
140 140 we instead read all frames, decode them, and feed them into our state
141 141 tracker. We then dump the log of all that activity back out to the
142 142 client.
143 143 """
144 144 import json
145 145
146 146 # Reflection APIs have a history of being abused, accidentally disclosing
147 147 # sensitive data, etc. So we have a config knob.
148 148 if not ui.configbool('experimental', 'web.api.debugreflect'):
149 149 res.status = b'404 Not Found'
150 150 res.headers[b'Content-Type'] = b'text/plain'
151 151 res.setbodybytes(_('debugreflect service not available'))
152 152 return
153 153
154 154 # We assume we have a unified framing protocol request body.
155 155
156 156 reactor = wireprotoframing.serverreactor()
157 157 states = []
158 158
159 159 while True:
160 160 frame = wireprotoframing.readframe(req.bodyfh)
161 161
162 162 if not frame:
163 163 states.append(b'received: <no frame>')
164 164 break
165 165
166 166 states.append(b'received: %d %d %d %s' % (frame.typeid, frame.flags,
167 167 frame.requestid,
168 168 frame.payload))
169 169
170 170 action, meta = reactor.onframerecv(frame)
171 171 states.append(json.dumps((action, meta), sort_keys=True,
172 172 separators=(', ', ': ')))
173 173
174 174 action, meta = reactor.oninputeof()
175 175 meta['action'] = action
176 176 states.append(json.dumps(meta, sort_keys=True, separators=(', ',': ')))
177 177
178 178 res.status = b'200 OK'
179 179 res.headers[b'Content-Type'] = b'text/plain'
180 180 res.setbodybytes(b'\n'.join(states))
181 181
182 182 def _processhttpv2request(ui, repo, req, res, authedperm, reqcommand, proto):
183 183 """Post-validation handler for HTTPv2 requests.
184 184
185 185 Called when the HTTP request contains unified frame-based protocol
186 186 frames for evaluation.
187 187 """
188 188 # TODO Some HTTP clients are full duplex and can receive data before
189 189 # the entire request is transmitted. Figure out a way to indicate support
190 190 # for that so we can opt into full duplex mode.
191 191 reactor = wireprotoframing.serverreactor(deferoutput=True)
192 192 seencommand = False
193 193
194 194 outstream = reactor.makeoutputstream()
195 195
196 196 while True:
197 197 frame = wireprotoframing.readframe(req.bodyfh)
198 198 if not frame:
199 199 break
200 200
201 201 action, meta = reactor.onframerecv(frame)
202 202
203 203 if action == 'wantframe':
204 204 # Need more data before we can do anything.
205 205 continue
206 206 elif action == 'runcommand':
207 207 sentoutput = _httpv2runcommand(ui, repo, req, res, authedperm,
208 208 reqcommand, reactor, outstream,
209 209 meta, issubsequent=seencommand)
210 210
211 211 if sentoutput:
212 212 return
213 213
214 214 seencommand = True
215 215
216 216 elif action == 'error':
217 217 # TODO define proper error mechanism.
218 218 res.status = b'200 OK'
219 219 res.headers[b'Content-Type'] = b'text/plain'
220 220 res.setbodybytes(meta['message'] + b'\n')
221 221 return
222 222 else:
223 223 raise error.ProgrammingError(
224 224 'unhandled action from frame processor: %s' % action)
225 225
226 226 action, meta = reactor.oninputeof()
227 227 if action == 'sendframes':
228 228 # We assume we haven't started sending the response yet. If we're
229 229 # wrong, the response type will raise an exception.
230 230 res.status = b'200 OK'
231 231 res.headers[b'Content-Type'] = FRAMINGTYPE
232 232 res.setbodygen(meta['framegen'])
233 233 elif action == 'noop':
234 234 pass
235 235 else:
236 236 raise error.ProgrammingError('unhandled action from frame processor: %s'
237 237 % action)
238 238
239 239 def _httpv2runcommand(ui, repo, req, res, authedperm, reqcommand, reactor,
240 240 outstream, command, issubsequent):
241 241 """Dispatch a wire protocol command made from HTTPv2 requests.
242 242
243 243 The authenticated permission (``authedperm``) along with the original
244 244 command from the URL (``reqcommand``) are passed in.
245 245 """
246 246 # We already validated that the session has permissions to perform the
247 247 # actions in ``authedperm``. In the unified frame protocol, the canonical
248 248 # command to run is expressed in a frame. However, the URL also requested
249 249 # to run a specific command. We need to be careful that the command we
250 250 # run doesn't have permissions requirements greater than what was granted
251 251 # by ``authedperm``.
252 252 #
253 253 # Our rule for this is we only allow one command per HTTP request and
254 254 # that command must match the command in the URL. However, we make
255 255 # an exception for the ``multirequest`` URL. This URL is allowed to
256 256 # execute multiple commands. We double check permissions of each command
257 257 # as it is invoked to ensure there is no privilege escalation.
258 258 # TODO consider allowing multiple commands to regular command URLs
259 259 # iff each command is the same.
260 260
261 261 proto = httpv2protocolhandler(req, ui, args=command['args'])
262 262
263 263 if reqcommand == b'multirequest':
264 264 if not COMMANDS.commandavailable(command['command'], proto):
265 265 # TODO proper error mechanism
266 266 res.status = b'200 OK'
267 267 res.headers[b'Content-Type'] = b'text/plain'
268 268 res.setbodybytes(_('wire protocol command not available: %s') %
269 269 command['command'])
270 270 return True
271 271
272 272 # TODO don't use assert here, since it may be elided by -O.
273 273 assert authedperm in (b'ro', b'rw')
274 274 wirecommand = COMMANDS[command['command']]
275 275 assert wirecommand.permission in ('push', 'pull')
276 276
277 277 if authedperm == b'ro' and wirecommand.permission != 'pull':
278 278 # TODO proper error mechanism
279 279 res.status = b'403 Forbidden'
280 280 res.headers[b'Content-Type'] = b'text/plain'
281 281 res.setbodybytes(_('insufficient permissions to execute '
282 282 'command: %s') % command['command'])
283 283 return True
284 284
285 285 # TODO should we also call checkperm() here? Maybe not if we're going
286 286 # to overhaul that API. The granted scope from the URL check should
287 287 # be good enough.
288 288
289 289 else:
290 290 # Don't allow multiple commands outside of ``multirequest`` URL.
291 291 if issubsequent:
292 292 # TODO proper error mechanism
293 293 res.status = b'200 OK'
294 294 res.headers[b'Content-Type'] = b'text/plain'
295 295 res.setbodybytes(_('multiple commands cannot be issued to this '
296 296 'URL'))
297 297 return True
298 298
299 299 if reqcommand != command['command']:
300 300 # TODO define proper error mechanism
301 301 res.status = b'200 OK'
302 302 res.headers[b'Content-Type'] = b'text/plain'
303 303 res.setbodybytes(_('command in frame must match command in URL'))
304 304 return True
305 305
306 306 res.status = b'200 OK'
307 307 res.headers[b'Content-Type'] = FRAMINGTYPE
308 308
309 309 try:
310 310 objs = dispatch(repo, proto, command['command'])
311 311
312 312 action, meta = reactor.oncommandresponsereadyobjects(
313 313 outstream, command['requestid'], objs)
314 314
315 315 except error.WireprotoCommandError as e:
316 316 action, meta = reactor.oncommanderror(
317 317 outstream, command['requestid'], e.message, e.messageargs)
318 318
319 319 except Exception as e:
320 320 action, meta = reactor.onservererror(
321 321 outstream, command['requestid'],
322 322 _('exception when invoking command: %s') % e)
323 323
324 324 if action == 'sendframes':
325 325 res.setbodygen(meta['framegen'])
326 326 return True
327 327 elif action == 'noop':
328 328 return False
329 329 else:
330 330 raise error.ProgrammingError('unhandled event from reactor: %s' %
331 331 action)
332 332
333 333 def getdispatchrepo(repo, proto, command):
334 334 return repo.filtered('served')
335 335
336 336 def dispatch(repo, proto, command):
337 337 repo = getdispatchrepo(repo, proto, command)
338 338
339 339 func, spec = COMMANDS[command]
340 340 args = proto.getargs(spec)
341 341
342 342 return func(repo, proto, **args)
343 343
344 344 @interfaceutil.implementer(wireprototypes.baseprotocolhandler)
345 345 class httpv2protocolhandler(object):
346 346 def __init__(self, req, ui, args=None):
347 347 self._req = req
348 348 self._ui = ui
349 349 self._args = args
350 350
351 351 @property
352 352 def name(self):
353 353 return HTTP_WIREPROTO_V2
354 354
355 355 def getargs(self, args):
356 356 # First look for args that were passed but aren't registered on this
357 357 # command.
358 358 extra = set(self._args) - set(args)
359 359 if extra:
360 360 raise error.WireprotoCommandError(
361 361 'unsupported argument to command: %s' %
362 362 ', '.join(sorted(extra)))
363 363
364 364 # And look for required arguments that are missing.
365 365 missing = {a for a in args if args[a]['required']} - set(self._args)
366 366
367 367 if missing:
368 368 raise error.WireprotoCommandError(
369 369 'missing required arguments: %s' % ', '.join(sorted(missing)))
370 370
371 371 # Now derive the arguments to pass to the command, taking into
372 372 # account the arguments specified by the client.
373 373 data = {}
374 374 for k, meta in sorted(args.items()):
375 375 # This argument wasn't passed by the client.
376 376 if k not in self._args:
377 377 data[k] = meta['default']()
378 378 continue
379 379
380 380 v = self._args[k]
381 381
382 382 # Sets may be expressed as lists. Silently normalize.
383 383 if meta['type'] == 'set' and isinstance(v, list):
384 384 v = set(v)
385 385
386 386 # TODO consider more/stronger type validation.
387 387
388 388 data[k] = v
389 389
390 390 return data
391 391
392 392 def getprotocaps(self):
393 393 # Protocol capabilities are currently not implemented for HTTP V2.
394 394 return set()
395 395
396 396 def getpayload(self):
397 397 raise NotImplementedError
398 398
399 399 @contextlib.contextmanager
400 400 def mayberedirectstdio(self):
401 401 raise NotImplementedError
402 402
403 403 def client(self):
404 404 raise NotImplementedError
405 405
406 406 def addcapabilities(self, repo, caps):
407 407 return caps
408 408
409 409 def checkperm(self, perm):
410 410 raise NotImplementedError
411 411
412 412 def httpv2apidescriptor(req, repo):
413 413 proto = httpv2protocolhandler(req, repo.ui)
414 414
415 415 return _capabilitiesv2(repo, proto)
416 416
417 417 def _capabilitiesv2(repo, proto):
418 418 """Obtain the set of capabilities for version 2 transports.
419 419
420 420 These capabilities are distinct from the capabilities for version 1
421 421 transports.
422 422 """
423 423 compression = []
424 424 for engine in wireprototypes.supportedcompengines(repo.ui, util.SERVERROLE):
425 425 compression.append({
426 426 b'name': engine.wireprotosupport().name,
427 427 })
428 428
429 429 caps = {
430 430 'commands': {},
431 431 'compression': compression,
432 432 'framingmediatypes': [FRAMINGTYPE],
433 433 'pathfilterprefixes': set(narrowspec.VALID_PREFIXES),
434 434 }
435 435
436 436 for command, entry in COMMANDS.items():
437 437 args = {}
438 438
439 439 for arg, meta in entry.args.items():
440 440 args[arg] = {
441 441 # TODO should this be a normalized type using CBOR's
442 442 # terminology?
443 443 b'type': meta['type'],
444 444 b'required': meta['required'],
445 445 }
446 446
447 447 if not meta['required']:
448 448 args[arg][b'default'] = meta['default']()
449 449
450 450 if meta['validvalues']:
451 451 args[arg][b'validvalues'] = meta['validvalues']
452 452
453 453 caps['commands'][command] = {
454 454 'args': args,
455 455 'permissions': [entry.permission],
456 456 }
457 457
458 458 if streamclone.allowservergeneration(repo):
459 459 caps['rawrepoformats'] = sorted(repo.requirements &
460 460 repo.supportedformats)
461 461
462 462 return proto.addcapabilities(repo, caps)
463 463
464 464 def builddeltarequests(store, nodes, haveparents):
465 465 """Build a series of revision delta requests against a backend store.
466 466
467 467 Returns a list of revision numbers in the order they should be sent
468 468 and a list of ``irevisiondeltarequest`` instances to be made against
469 469 the backend store.
470 470 """
471 471 # We sort and send nodes in DAG order because this is optimal for
472 472 # storage emission.
473 473 # TODO we may want a better storage API here - one where we can throw
474 474 # a list of nodes and delta preconditions over a figurative wall and
475 475 # have the storage backend figure it out for us.
476 476 revs = dagop.linearize({store.rev(n) for n in nodes}, store.parentrevs)
477 477
478 478 requests = []
479 479 seenrevs = set()
480 480
481 481 for rev in revs:
482 482 node = store.node(rev)
483 483 parentnodes = store.parents(node)
484 484 parentrevs = [store.rev(n) for n in parentnodes]
485 485 deltabaserev = store.deltaparent(rev)
486 486 deltabasenode = store.node(deltabaserev)
487 487
488 488 # The choice of whether to send a fulltext revision or a delta and
489 489 # what delta to send is governed by a few factors.
490 490 #
491 491 # To send a delta, we need to ensure the receiver is capable of
492 492 # decoding it. And that requires the receiver to have the base
493 493 # revision the delta is against.
494 494 #
495 495 # We can only guarantee the receiver has the base revision if
496 496 # a) we've already sent the revision as part of this group
497 497 # b) the receiver has indicated they already have the revision.
498 498 # And the mechanism for "b" is the client indicating they have
499 499 # parent revisions. So this means we can only send the delta if
500 500 # it is sent before or it is against a delta and the receiver says
501 501 # they have a parent.
502 502
503 503 # We can send storage delta if it is against a revision we've sent
504 504 # in this group.
505 505 if deltabaserev != nullrev and deltabaserev in seenrevs:
506 506 basenode = deltabasenode
507 507
508 508 # We can send storage delta if it is against a parent revision and
509 509 # the receiver indicates they have the parents.
510 510 elif (deltabaserev != nullrev and deltabaserev in parentrevs
511 511 and haveparents):
512 512 basenode = deltabasenode
513 513
514 514 # Otherwise the storage delta isn't appropriate. Fall back to
515 515 # using another delta, if possible.
516 516
517 517 # Use p1 if we've emitted it or receiver says they have it.
518 518 elif parentrevs[0] != nullrev and (
519 519 parentrevs[0] in seenrevs or haveparents):
520 520 basenode = parentnodes[0]
521 521
522 522 # Use p2 if we've emitted it or receiver says they have it.
523 523 elif parentrevs[1] != nullrev and (
524 524 parentrevs[1] in seenrevs or haveparents):
525 525 basenode = parentnodes[1]
526 526
527 527 # Nothing appropriate to delta against. Send the full revision.
528 528 else:
529 529 basenode = nullid
530 530
531 531 requests.append(changegroup.revisiondeltarequest(
532 532 node=node,
533 533 p1node=parentnodes[0],
534 534 p2node=parentnodes[1],
535 535 # Receiver deals with linknode resolution.
536 536 linknode=nullid,
537 537 basenode=basenode,
538 538 ))
539 539
540 540 seenrevs.add(rev)
541 541
542 542 return revs, requests
543 543
544 544 def wireprotocommand(name, args=None, permission='push'):
545 545 """Decorator to declare a wire protocol command.
546 546
547 547 ``name`` is the name of the wire protocol command being provided.
548 548
549 549 ``args`` is a dict defining arguments accepted by the command. Keys are
550 550 the argument name. Values are dicts with the following keys:
551 551
552 552 ``type``
553 553 The argument data type. Must be one of the following string
554 554 literals: ``bytes``, ``int``, ``list``, ``dict``, ``set``,
555 555 or ``bool``.
556 556
557 557 ``default``
558 558 A callable returning the default value for this argument. If not
559 559 specified, ``None`` will be the default value.
560 560
561 561 ``required``
562 562 Bool indicating whether the argument is required.
563 563
564 564 ``example``
565 565 An example value for this argument.
566 566
567 567 ``validvalues``
568 568 Set of recognized values for this argument.
569 569
570 570 ``permission`` defines the permission type needed to run this command.
571 571 Can be ``push`` or ``pull``. These roughly map to read-write and read-only,
572 572 respectively. Default is to assume command requires ``push`` permissions
573 573 because otherwise commands not declaring their permissions could modify
574 574 a repository that is supposed to be read-only.
575 575
576 576 Wire protocol commands are generators of objects to be serialized and
577 577 sent to the client.
578 578
579 579 If a command raises an uncaught exception, this will be translated into
580 580 a command error.
581 581 """
582 582 transports = {k for k, v in wireprototypes.TRANSPORTS.items()
583 583 if v['version'] == 2}
584 584
585 585 if permission not in ('push', 'pull'):
586 586 raise error.ProgrammingError('invalid wire protocol permission; '
587 587 'got %s; expected "push" or "pull"' %
588 588 permission)
589 589
590 590 if args is None:
591 591 args = {}
592 592
593 593 if not isinstance(args, dict):
594 594 raise error.ProgrammingError('arguments for version 2 commands '
595 595 'must be declared as dicts')
596 596
597 597 for arg, meta in args.items():
598 598 if arg == '*':
599 599 raise error.ProgrammingError('* argument name not allowed on '
600 600 'version 2 commands')
601 601
602 602 if not isinstance(meta, dict):
603 603 raise error.ProgrammingError('arguments for version 2 commands '
604 604 'must declare metadata as a dict')
605 605
606 606 if 'type' not in meta:
607 607 raise error.ProgrammingError('%s argument for command %s does not '
608 608 'declare type field' % (arg, name))
609 609
610 610 if meta['type'] not in ('bytes', 'int', 'list', 'dict', 'set', 'bool'):
611 611 raise error.ProgrammingError('%s argument for command %s has '
612 612 'illegal type: %s' % (arg, name,
613 613 meta['type']))
614 614
615 615 if 'example' not in meta:
616 616 raise error.ProgrammingError('%s argument for command %s does not '
617 617 'declare example field' % (arg, name))
618 618
619 619 if 'default' in meta and meta.get('required'):
620 620 raise error.ProgrammingError('%s argument for command %s is marked '
621 621 'as required but has a default value' %
622 622 (arg, name))
623 623
624 624 meta.setdefault('default', lambda: None)
625 625 meta.setdefault('required', False)
626 626 meta.setdefault('validvalues', None)
627 627
628 628 def register(func):
629 629 if name in COMMANDS:
630 630 raise error.ProgrammingError('%s command already registered '
631 631 'for version 2' % name)
632 632
633 633 COMMANDS[name] = wireprototypes.commandentry(
634 634 func, args=args, transports=transports, permission=permission)
635 635
636 636 return func
637 637
638 638 return register
639 639
640 640 @wireprotocommand('branchmap', permission='pull')
641 641 def branchmapv2(repo, proto):
642 642 yield {encoding.fromlocal(k): v
643 643 for k, v in repo.branchmap().iteritems()}
644 644
645 645 @wireprotocommand('capabilities', permission='pull')
646 646 def capabilitiesv2(repo, proto):
647 647 yield _capabilitiesv2(repo, proto)
648 648
649 649 @wireprotocommand(
650 650 'changesetdata',
651 651 args={
652 652 'noderange': {
653 653 'type': 'list',
654 654 'example': [[b'0123456...'], [b'abcdef...']],
655 655 },
656 656 'nodes': {
657 657 'type': 'list',
658 658 'example': [b'0123456...'],
659 659 },
660 660 'fields': {
661 661 'type': 'set',
662 662 'default': set,
663 663 'example': {b'parents', b'revision'},
664 664 'validvalues': {b'bookmarks', b'parents', b'phase', b'revision'},
665 665 },
666 666 },
667 667 permission='pull')
668 668 def changesetdata(repo, proto, noderange, nodes, fields):
669 669 # TODO look for unknown fields and abort when they can't be serviced.
670 670 # This could probably be validated by dispatcher using validvalues.
671 671
672 672 if noderange is None and nodes is None:
673 673 raise error.WireprotoCommandError(
674 674 'noderange or nodes must be defined')
675 675
676 676 if noderange is not None:
677 677 if len(noderange) != 2:
678 678 raise error.WireprotoCommandError(
679 679 'noderange must consist of 2 elements')
680 680
681 681 if not noderange[1]:
682 682 raise error.WireprotoCommandError(
683 683 'heads in noderange request cannot be empty')
684 684
685 685 cl = repo.changelog
686 686 hasnode = cl.hasnode
687 687
688 688 seen = set()
689 689 outgoing = []
690 690
691 691 if nodes is not None:
692 692 outgoing.extend(n for n in nodes if hasnode(n))
693 693 seen |= set(outgoing)
694 694
695 695 if noderange is not None:
696 696 if noderange[0]:
697 697 common = [n for n in noderange[0] if hasnode(n)]
698 698 else:
699 699 common = [nullid]
700 700
701 701 for n in discovery.outgoing(repo, common, noderange[1]).missing:
702 702 if n not in seen:
703 703 outgoing.append(n)
704 704 # Don't need to add to seen here because this is the final
705 705 # source of nodes and there should be no duplicates in this
706 706 # list.
707 707
708 708 seen.clear()
709 709 publishing = repo.publishing()
710 710
711 711 if outgoing:
712 712 repo.hook('preoutgoing', throw=True, source='serve')
713 713
714 714 yield {
715 715 b'totalitems': len(outgoing),
716 716 }
717 717
718 718 # The phases of nodes already transferred to the client may have changed
719 719 # since the client last requested data. We send phase-only records
720 720 # for these revisions, if requested.
721 721 if b'phase' in fields and noderange is not None:
722 722 # TODO skip nodes whose phase will be reflected by a node in the
723 723 # outgoing set. This is purely an optimization to reduce data
724 724 # size.
725 725 for node in noderange[0]:
726 726 yield {
727 727 b'node': node,
728 728 b'phase': b'public' if publishing else repo[node].phasestr()
729 729 }
730 730
731 731 nodebookmarks = {}
732 732 for mark, node in repo._bookmarks.items():
733 733 nodebookmarks.setdefault(node, set()).add(mark)
734 734
735 735 # It is already topologically sorted by revision number.
736 736 for node in outgoing:
737 737 d = {
738 738 b'node': node,
739 739 }
740 740
741 741 if b'parents' in fields:
742 742 d[b'parents'] = cl.parents(node)
743 743
744 744 if b'phase' in fields:
745 745 if publishing:
746 746 d[b'phase'] = b'public'
747 747 else:
748 748 ctx = repo[node]
749 749 d[b'phase'] = ctx.phasestr()
750 750
751 751 if b'bookmarks' in fields and node in nodebookmarks:
752 752 d[b'bookmarks'] = sorted(nodebookmarks[node])
753 753 del nodebookmarks[node]
754 754
755 revisiondata = None
755 followingmeta = []
756 followingdata = []
756 757
757 758 if b'revision' in fields:
758 759 revisiondata = cl.revision(node, raw=True)
759 d[b'revisionsize'] = len(revisiondata)
760 followingmeta.append((b'revision', len(revisiondata)))
761 followingdata.append(revisiondata)
760 762
761 763 # TODO make it possible for extensions to wrap a function or register
762 764 # a handler to service custom fields.
763 765
766 if followingmeta:
767 d[b'fieldsfollowing'] = followingmeta
768
764 769 yield d
765 770
766 if revisiondata is not None:
767 yield revisiondata
771 for extra in followingdata:
772 yield extra
768 773
769 774 # If requested, send bookmarks from nodes that didn't have revision
770 775 # data sent so receiver is aware of any bookmark updates.
771 776 if b'bookmarks' in fields:
772 777 for node, marks in sorted(nodebookmarks.iteritems()):
773 778 yield {
774 779 b'node': node,
775 780 b'bookmarks': sorted(marks),
776 781 }
777 782
778 783 class FileAccessError(Exception):
779 784 """Represents an error accessing a specific file."""
780 785
781 786 def __init__(self, path, msg, args):
782 787 self.path = path
783 788 self.msg = msg
784 789 self.args = args
785 790
786 791 def getfilestore(repo, proto, path):
787 792 """Obtain a file storage object for use with wire protocol.
788 793
789 794 Exists as a standalone function so extensions can monkeypatch to add
790 795 access control.
791 796 """
792 797 # This seems to work even if the file doesn't exist. So catch
793 798 # "empty" files and return an error.
794 799 fl = repo.file(path)
795 800
796 801 if not len(fl):
797 802 raise FileAccessError(path, 'unknown file: %s', (path,))
798 803
799 804 return fl
800 805
801 806 @wireprotocommand(
802 807 'filedata',
803 808 args={
804 809 'haveparents': {
805 810 'type': 'bool',
806 811 'default': lambda: False,
807 812 'example': True,
808 813 },
809 814 'nodes': {
810 815 'type': 'list',
811 816 'required': True,
812 817 'example': [b'0123456...'],
813 818 },
814 819 'fields': {
815 820 'type': 'set',
816 821 'default': set,
817 822 'example': {b'parents', b'revision'},
818 823 'validvalues': {b'parents', b'revision'},
819 824 },
820 825 'path': {
821 826 'type': 'bytes',
822 827 'required': True,
823 828 'example': b'foo.txt',
824 829 }
825 830 },
826 831 permission='pull')
827 832 def filedata(repo, proto, haveparents, nodes, fields, path):
828 833 try:
829 834 # Extensions may wish to access the protocol handler.
830 835 store = getfilestore(repo, proto, path)
831 836 except FileAccessError as e:
832 837 raise error.WireprotoCommandError(e.msg, e.args)
833 838
834 839 # Validate requested nodes.
835 840 for node in nodes:
836 841 try:
837 842 store.rev(node)
838 843 except error.LookupError:
839 844 raise error.WireprotoCommandError('unknown file node: %s',
840 845 (hex(node),))
841 846
842 847 revs, requests = builddeltarequests(store, nodes, haveparents)
843 848
844 849 yield {
845 850 b'totalitems': len(revs),
846 851 }
847 852
848 853 if b'revision' in fields:
849 854 deltas = store.emitrevisiondeltas(requests)
850 855 else:
851 856 deltas = None
852 857
853 858 for rev in revs:
854 859 node = store.node(rev)
855 860
856 861 if deltas is not None:
857 862 delta = next(deltas)
858 863 else:
859 864 delta = None
860 865
861 866 d = {
862 867 b'node': node,
863 868 }
864 869
865 870 if b'parents' in fields:
866 871 d[b'parents'] = store.parents(node)
867 872
873 followingmeta = []
874 followingdata = []
875
868 876 if b'revision' in fields:
869 877 assert delta is not None
870 878 assert delta.flags == 0
871 879 assert d[b'node'] == delta.node
872 880
873 881 if delta.revision is not None:
874 revisiondata = delta.revision
875 d[b'revisionsize'] = len(revisiondata)
882 followingmeta.append((b'revision', len(delta.revision)))
883 followingdata.append(delta.revision)
876 884 else:
877 885 d[b'deltabasenode'] = delta.basenode
878 revisiondata = delta.delta
879 d[b'deltasize'] = len(revisiondata)
880 else:
881 revisiondata = None
886 followingmeta.append((b'delta', len(delta.delta)))
887 followingdata.append(delta.delta)
888
889 if followingmeta:
890 d[b'fieldsfollowing'] = followingmeta
882 891
883 892 yield d
884 893
885 if revisiondata is not None:
886 yield revisiondata
894 for extra in followingdata:
895 yield extra
887 896
888 897 if deltas is not None:
889 898 try:
890 899 next(deltas)
891 900 raise error.ProgrammingError('should not have more deltas')
892 901 except GeneratorExit:
893 902 pass
894 903
895 904 @wireprotocommand(
896 905 'heads',
897 906 args={
898 907 'publiconly': {
899 908 'type': 'bool',
900 909 'default': lambda: False,
901 910 'example': False,
902 911 },
903 912 },
904 913 permission='pull')
905 914 def headsv2(repo, proto, publiconly):
906 915 if publiconly:
907 916 repo = repo.filtered('immutable')
908 917
909 918 yield repo.heads()
910 919
911 920 @wireprotocommand(
912 921 'known',
913 922 args={
914 923 'nodes': {
915 924 'type': 'list',
916 925 'default': list,
917 926 'example': [b'deadbeef'],
918 927 },
919 928 },
920 929 permission='pull')
921 930 def knownv2(repo, proto, nodes):
922 931 result = b''.join(b'1' if n else b'0' for n in repo.known(nodes))
923 932 yield result
924 933
925 934 @wireprotocommand(
926 935 'listkeys',
927 936 args={
928 937 'namespace': {
929 938 'type': 'bytes',
930 939 'required': True,
931 940 'example': b'ns',
932 941 },
933 942 },
934 943 permission='pull')
935 944 def listkeysv2(repo, proto, namespace):
936 945 keys = repo.listkeys(encoding.tolocal(namespace))
937 946 keys = {encoding.fromlocal(k): encoding.fromlocal(v)
938 947 for k, v in keys.iteritems()}
939 948
940 949 yield keys
941 950
942 951 @wireprotocommand(
943 952 'lookup',
944 953 args={
945 954 'key': {
946 955 'type': 'bytes',
947 956 'required': True,
948 957 'example': b'foo',
949 958 },
950 959 },
951 960 permission='pull')
952 961 def lookupv2(repo, proto, key):
953 962 key = encoding.tolocal(key)
954 963
955 964 # TODO handle exception.
956 965 node = repo.lookup(key)
957 966
958 967 yield node
959 968
960 969 @wireprotocommand(
961 970 'manifestdata',
962 971 args={
963 972 'nodes': {
964 973 'type': 'list',
965 974 'required': True,
966 975 'example': [b'0123456...'],
967 976 },
968 977 'haveparents': {
969 978 'type': 'bool',
970 979 'default': lambda: False,
971 980 'example': True,
972 981 },
973 982 'fields': {
974 983 'type': 'set',
975 984 'default': set,
976 985 'example': {b'parents', b'revision'},
977 986 'validvalues': {b'parents', b'revision'},
978 987 },
979 988 'tree': {
980 989 'type': 'bytes',
981 990 'required': True,
982 991 'example': b'',
983 992 },
984 993 },
985 994 permission='pull')
986 995 def manifestdata(repo, proto, haveparents, nodes, fields, tree):
987 996 store = repo.manifestlog.getstorage(tree)
988 997
989 998 # Validate the node is known and abort on unknown revisions.
990 999 for node in nodes:
991 1000 try:
992 1001 store.rev(node)
993 1002 except error.LookupError:
994 1003 raise error.WireprotoCommandError(
995 1004 'unknown node: %s', (node,))
996 1005
997 1006 revs, requests = builddeltarequests(store, nodes, haveparents)
998 1007
999 1008 yield {
1000 1009 b'totalitems': len(revs),
1001 1010 }
1002 1011
1003 1012 if b'revision' in fields:
1004 1013 deltas = store.emitrevisiondeltas(requests)
1005 1014 else:
1006 1015 deltas = None
1007 1016
1008 1017 for rev in revs:
1009 1018 node = store.node(rev)
1010 1019
1011 1020 if deltas is not None:
1012 1021 delta = next(deltas)
1013 1022 else:
1014 1023 delta = None
1015 1024
1016 1025 d = {
1017 1026 b'node': node,
1018 1027 }
1019 1028
1020 1029 if b'parents' in fields:
1021 1030 d[b'parents'] = store.parents(node)
1022 1031
1032 followingmeta = []
1033 followingdata = []
1034
1023 1035 if b'revision' in fields:
1024 1036 assert delta is not None
1025 1037 assert delta.flags == 0
1026 1038 assert d[b'node'] == delta.node
1027 1039
1028 1040 if delta.revision is not None:
1029 revisiondata = delta.revision
1030 d[b'revisionsize'] = len(revisiondata)
1041 followingmeta.append((b'revision', len(delta.revision)))
1042 followingdata.append(delta.revision)
1031 1043 else:
1032 1044 d[b'deltabasenode'] = delta.basenode
1033 revisiondata = delta.delta
1034 d[b'deltasize'] = len(revisiondata)
1035 else:
1036 revisiondata = None
1045 followingmeta.append((b'delta', len(delta.delta)))
1046 followingdata.append(delta.delta)
1047
1048 if followingmeta:
1049 d[b'fieldsfollowing'] = followingmeta
1037 1050
1038 1051 yield d
1039 1052
1040 if revisiondata is not None:
1041 yield revisiondata
1053 for extra in followingdata:
1054 yield extra
1042 1055
1043 1056 if deltas is not None:
1044 1057 try:
1045 1058 next(deltas)
1046 1059 raise error.ProgrammingError('should not have more deltas')
1047 1060 except GeneratorExit:
1048 1061 pass
1049 1062
1050 1063 @wireprotocommand(
1051 1064 'pushkey',
1052 1065 args={
1053 1066 'namespace': {
1054 1067 'type': 'bytes',
1055 1068 'required': True,
1056 1069 'example': b'ns',
1057 1070 },
1058 1071 'key': {
1059 1072 'type': 'bytes',
1060 1073 'required': True,
1061 1074 'example': b'key',
1062 1075 },
1063 1076 'old': {
1064 1077 'type': 'bytes',
1065 1078 'required': True,
1066 1079 'example': b'old',
1067 1080 },
1068 1081 'new': {
1069 1082 'type': 'bytes',
1070 1083 'required': True,
1071 1084 'example': 'new',
1072 1085 },
1073 1086 },
1074 1087 permission='push')
1075 1088 def pushkeyv2(repo, proto, namespace, key, old, new):
1076 1089 # TODO handle ui output redirection
1077 1090 yield repo.pushkey(encoding.tolocal(namespace),
1078 1091 encoding.tolocal(key),
1079 1092 encoding.tolocal(old),
1080 1093 encoding.tolocal(new))
@@ -1,1296 +1,1296 b''
1 1 #testcases sshv1 sshv2
2 2
3 3 #if sshv2
4 4 $ cat >> $HGRCPATH << EOF
5 5 > [experimental]
6 6 > sshpeer.advertise-v2 = true
7 7 > sshserver.support-v2 = true
8 8 > EOF
9 9 #endif
10 10
11 11 Prepare repo a:
12 12
13 13 $ hg init a
14 14 $ cd a
15 15 $ echo a > a
16 16 $ hg add a
17 17 $ hg commit -m test
18 18 $ echo first line > b
19 19 $ hg add b
20 20
21 21 Create a non-inlined filelog:
22 22
23 23 $ "$PYTHON" -c 'open("data1", "wb").write(b"".join(b"%d\n" % x for x in range(10000)))'
24 24 $ for j in 0 1 2 3 4 5 6 7 8 9; do
25 25 > cat data1 >> b
26 26 > hg commit -m test
27 27 > done
28 28
29 29 List files in store/data (should show a 'b.d'):
30 30
31 31 #if reporevlogstore
32 32 $ for i in .hg/store/data/*; do
33 33 > echo $i
34 34 > done
35 35 .hg/store/data/a.i
36 36 .hg/store/data/b.d
37 37 .hg/store/data/b.i
38 38 #endif
39 39
40 40 Trigger branchcache creation:
41 41
42 42 $ hg branches
43 43 default 10:a7949464abda
44 44 $ ls .hg/cache
45 45 branch2-served
46 46 checkisexec (execbit !)
47 47 checklink (symlink !)
48 48 checklink-target (symlink !)
49 49 checknoexec (execbit !)
50 50 manifestfulltextcache (reporevlogstore !)
51 51 rbc-names-v1
52 52 rbc-revs-v1
53 53
54 54 Default operation:
55 55
56 56 $ hg clone . ../b
57 57 updating to branch default
58 58 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
59 59 $ cd ../b
60 60
61 61 Ensure branchcache got copied over:
62 62
63 63 $ ls .hg/cache
64 64 branch2-served
65 65 checkisexec (execbit !)
66 66 checklink (symlink !)
67 67 checklink-target (symlink !)
68 68 rbc-names-v1
69 69 rbc-revs-v1
70 70
71 71 $ cat a
72 72 a
73 73 $ hg verify
74 74 checking changesets
75 75 checking manifests
76 76 crosschecking files in changesets and manifests
77 77 checking files
78 78 checked 11 changesets with 11 changes to 2 files
79 79
80 80 Invalid dest '' must abort:
81 81
82 82 $ hg clone . ''
83 83 abort: empty destination path is not valid
84 84 [255]
85 85
86 86 No update, with debug option:
87 87
88 88 #if hardlink
89 89 $ hg --debug clone -U . ../c --config progress.debug=true
90 90 linking: 1
91 91 linking: 2
92 92 linking: 3
93 93 linking: 4
94 94 linking: 5
95 95 linking: 6
96 96 linking: 7
97 97 linking: 8
98 98 linked 8 files (reporevlogstore !)
99 99 linking: 9 (reposimplestore !)
100 100 linking: 10 (reposimplestore !)
101 101 linking: 11 (reposimplestore !)
102 102 linking: 12 (reposimplestore !)
103 103 linking: 13 (reposimplestore !)
104 104 linking: 14 (reposimplestore !)
105 105 linking: 15 (reposimplestore !)
106 106 linking: 16 (reposimplestore !)
107 107 linking: 17 (reposimplestore !)
108 108 linking: 18 (reposimplestore !)
109 109 linked 18 files (reposimplestore !)
110 110 #else
111 111 $ hg --debug clone -U . ../c --config progress.debug=true
112 112 linking: 1
113 113 copying: 2
114 114 copying: 3
115 115 copying: 4
116 116 copying: 5
117 117 copying: 6
118 118 copying: 7
119 119 copying: 8
120 120 copied 8 files (reporevlogstore !)
121 121 copying: 9 (reposimplestore !)
122 122 copying: 10 (reposimplestore !)
123 123 copying: 11 (reposimplestore !)
124 124 copying: 12 (reposimplestore !)
125 125 copying: 13 (reposimplestore !)
126 126 copying: 14 (reposimplestore !)
127 127 copying: 15 (reposimplestore !)
128 128 copying: 16 (reposimplestore !)
129 129 copying: 17 (reposimplestore !)
130 130 copying: 18 (reposimplestore !)
131 131 copied 18 files (reposimplestore !)
132 132 #endif
133 133 $ cd ../c
134 134
135 135 Ensure branchcache got copied over:
136 136
137 137 $ ls .hg/cache
138 138 branch2-served
139 139 rbc-names-v1
140 140 rbc-revs-v1
141 141
142 142 $ cat a 2>/dev/null || echo "a not present"
143 143 a not present
144 144 $ hg verify
145 145 checking changesets
146 146 checking manifests
147 147 crosschecking files in changesets and manifests
148 148 checking files
149 149 checked 11 changesets with 11 changes to 2 files
150 150
151 151 Default destination:
152 152
153 153 $ mkdir ../d
154 154 $ cd ../d
155 155 $ hg clone ../a
156 156 destination directory: a
157 157 updating to branch default
158 158 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
159 159 $ cd a
160 160 $ hg cat a
161 161 a
162 162 $ cd ../..
163 163
164 164 Check that we drop the 'file:' from the path before writing the .hgrc:
165 165
166 166 $ hg clone file:a e
167 167 updating to branch default
168 168 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
169 169 $ grep 'file:' e/.hg/hgrc
170 170 [1]
171 171
172 172 Check that path aliases are expanded:
173 173
174 174 $ hg clone -q -U --config 'paths.foobar=a#0' foobar f
175 175 $ hg -R f showconfig paths.default
176 176 $TESTTMP/a#0
177 177
178 178 Use --pull:
179 179
180 180 $ hg clone --pull a g
181 181 requesting all changes
182 182 adding changesets
183 183 adding manifests
184 184 adding file changes
185 185 added 11 changesets with 11 changes to 2 files
186 186 new changesets acb14030fe0a:a7949464abda
187 187 updating to branch default
188 188 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
189 189 $ hg -R g verify
190 190 checking changesets
191 191 checking manifests
192 192 crosschecking files in changesets and manifests
193 193 checking files
194 194 checked 11 changesets with 11 changes to 2 files
195 195
196 196 Invalid dest '' with --pull must abort (issue2528):
197 197
198 198 $ hg clone --pull a ''
199 199 abort: empty destination path is not valid
200 200 [255]
201 201
202 202 Clone to '.':
203 203
204 204 $ mkdir h
205 205 $ cd h
206 206 $ hg clone ../a .
207 207 updating to branch default
208 208 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
209 209 $ cd ..
210 210
211 211
212 212 *** Tests for option -u ***
213 213
214 214 Adding some more history to repo a:
215 215
216 216 $ cd a
217 217 $ hg tag ref1
218 218 $ echo the quick brown fox >a
219 219 $ hg ci -m "hacked default"
220 220 $ hg up ref1
221 221 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
222 222 $ hg branch stable
223 223 marked working directory as branch stable
224 224 (branches are permanent and global, did you want a bookmark?)
225 225 $ echo some text >a
226 226 $ hg ci -m "starting branch stable"
227 227 $ hg tag ref2
228 228 $ echo some more text >a
229 229 $ hg ci -m "another change for branch stable"
230 230 $ hg up ref2
231 231 1 files updated, 0 files merged, 1 files removed, 0 files unresolved
232 232 $ hg parents
233 233 changeset: 13:e8ece76546a6
234 234 branch: stable
235 235 tag: ref2
236 236 parent: 10:a7949464abda
237 237 user: test
238 238 date: Thu Jan 01 00:00:00 1970 +0000
239 239 summary: starting branch stable
240 240
241 241
242 242 Repo a has two heads:
243 243
244 244 $ hg heads
245 245 changeset: 15:0aae7cf88f0d
246 246 branch: stable
247 247 tag: tip
248 248 user: test
249 249 date: Thu Jan 01 00:00:00 1970 +0000
250 250 summary: another change for branch stable
251 251
252 252 changeset: 12:f21241060d6a
253 253 user: test
254 254 date: Thu Jan 01 00:00:00 1970 +0000
255 255 summary: hacked default
256 256
257 257
258 258 $ cd ..
259 259
260 260
261 261 Testing --noupdate with --updaterev (must abort):
262 262
263 263 $ hg clone --noupdate --updaterev 1 a ua
264 264 abort: cannot specify both --noupdate and --updaterev
265 265 [255]
266 266
267 267
268 268 Testing clone -u:
269 269
270 270 $ hg clone -u . a ua
271 271 updating to branch stable
272 272 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
273 273
274 274 Repo ua has both heads:
275 275
276 276 $ hg -R ua heads
277 277 changeset: 15:0aae7cf88f0d
278 278 branch: stable
279 279 tag: tip
280 280 user: test
281 281 date: Thu Jan 01 00:00:00 1970 +0000
282 282 summary: another change for branch stable
283 283
284 284 changeset: 12:f21241060d6a
285 285 user: test
286 286 date: Thu Jan 01 00:00:00 1970 +0000
287 287 summary: hacked default
288 288
289 289
290 290 Same revision checked out in repo a and ua:
291 291
292 292 $ hg -R a parents --template "{node|short}\n"
293 293 e8ece76546a6
294 294 $ hg -R ua parents --template "{node|short}\n"
295 295 e8ece76546a6
296 296
297 297 $ rm -r ua
298 298
299 299
300 300 Testing clone --pull -u:
301 301
302 302 $ hg clone --pull -u . a ua
303 303 requesting all changes
304 304 adding changesets
305 305 adding manifests
306 306 adding file changes
307 307 added 16 changesets with 16 changes to 3 files (+1 heads)
308 308 new changesets acb14030fe0a:0aae7cf88f0d
309 309 updating to branch stable
310 310 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
311 311
312 312 Repo ua has both heads:
313 313
314 314 $ hg -R ua heads
315 315 changeset: 15:0aae7cf88f0d
316 316 branch: stable
317 317 tag: tip
318 318 user: test
319 319 date: Thu Jan 01 00:00:00 1970 +0000
320 320 summary: another change for branch stable
321 321
322 322 changeset: 12:f21241060d6a
323 323 user: test
324 324 date: Thu Jan 01 00:00:00 1970 +0000
325 325 summary: hacked default
326 326
327 327
328 328 Same revision checked out in repo a and ua:
329 329
330 330 $ hg -R a parents --template "{node|short}\n"
331 331 e8ece76546a6
332 332 $ hg -R ua parents --template "{node|short}\n"
333 333 e8ece76546a6
334 334
335 335 $ rm -r ua
336 336
337 337
338 338 Testing clone -u <branch>:
339 339
340 340 $ hg clone -u stable a ua
341 341 updating to branch stable
342 342 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
343 343
344 344 Repo ua has both heads:
345 345
346 346 $ hg -R ua heads
347 347 changeset: 15:0aae7cf88f0d
348 348 branch: stable
349 349 tag: tip
350 350 user: test
351 351 date: Thu Jan 01 00:00:00 1970 +0000
352 352 summary: another change for branch stable
353 353
354 354 changeset: 12:f21241060d6a
355 355 user: test
356 356 date: Thu Jan 01 00:00:00 1970 +0000
357 357 summary: hacked default
358 358
359 359
360 360 Branch 'stable' is checked out:
361 361
362 362 $ hg -R ua parents
363 363 changeset: 15:0aae7cf88f0d
364 364 branch: stable
365 365 tag: tip
366 366 user: test
367 367 date: Thu Jan 01 00:00:00 1970 +0000
368 368 summary: another change for branch stable
369 369
370 370
371 371 $ rm -r ua
372 372
373 373
374 374 Testing default checkout:
375 375
376 376 $ hg clone a ua
377 377 updating to branch default
378 378 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
379 379
380 380 Repo ua has both heads:
381 381
382 382 $ hg -R ua heads
383 383 changeset: 15:0aae7cf88f0d
384 384 branch: stable
385 385 tag: tip
386 386 user: test
387 387 date: Thu Jan 01 00:00:00 1970 +0000
388 388 summary: another change for branch stable
389 389
390 390 changeset: 12:f21241060d6a
391 391 user: test
392 392 date: Thu Jan 01 00:00:00 1970 +0000
393 393 summary: hacked default
394 394
395 395
396 396 Branch 'default' is checked out:
397 397
398 398 $ hg -R ua parents
399 399 changeset: 12:f21241060d6a
400 400 user: test
401 401 date: Thu Jan 01 00:00:00 1970 +0000
402 402 summary: hacked default
403 403
404 404 Test clone with a branch named "@" (issue3677)
405 405
406 406 $ hg -R ua branch @
407 407 marked working directory as branch @
408 408 $ hg -R ua commit -m 'created branch @'
409 409 $ hg clone ua atbranch
410 410 updating to branch default
411 411 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
412 412 $ hg -R atbranch heads
413 413 changeset: 16:798b6d97153e
414 414 branch: @
415 415 tag: tip
416 416 parent: 12:f21241060d6a
417 417 user: test
418 418 date: Thu Jan 01 00:00:00 1970 +0000
419 419 summary: created branch @
420 420
421 421 changeset: 15:0aae7cf88f0d
422 422 branch: stable
423 423 user: test
424 424 date: Thu Jan 01 00:00:00 1970 +0000
425 425 summary: another change for branch stable
426 426
427 427 changeset: 12:f21241060d6a
428 428 user: test
429 429 date: Thu Jan 01 00:00:00 1970 +0000
430 430 summary: hacked default
431 431
432 432 $ hg -R atbranch parents
433 433 changeset: 12:f21241060d6a
434 434 user: test
435 435 date: Thu Jan 01 00:00:00 1970 +0000
436 436 summary: hacked default
437 437
438 438
439 439 $ rm -r ua atbranch
440 440
441 441
442 442 Testing #<branch>:
443 443
444 444 $ hg clone -u . a#stable ua
445 445 adding changesets
446 446 adding manifests
447 447 adding file changes
448 448 added 14 changesets with 14 changes to 3 files
449 449 new changesets acb14030fe0a:0aae7cf88f0d
450 450 updating to branch stable
451 451 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
452 452
453 453 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
454 454
455 455 $ hg -R ua heads
456 456 changeset: 13:0aae7cf88f0d
457 457 branch: stable
458 458 tag: tip
459 459 user: test
460 460 date: Thu Jan 01 00:00:00 1970 +0000
461 461 summary: another change for branch stable
462 462
463 463 changeset: 10:a7949464abda
464 464 user: test
465 465 date: Thu Jan 01 00:00:00 1970 +0000
466 466 summary: test
467 467
468 468
469 469 Same revision checked out in repo a and ua:
470 470
471 471 $ hg -R a parents --template "{node|short}\n"
472 472 e8ece76546a6
473 473 $ hg -R ua parents --template "{node|short}\n"
474 474 e8ece76546a6
475 475
476 476 $ rm -r ua
477 477
478 478
479 479 Testing -u -r <branch>:
480 480
481 481 $ hg clone -u . -r stable a ua
482 482 adding changesets
483 483 adding manifests
484 484 adding file changes
485 485 added 14 changesets with 14 changes to 3 files
486 486 new changesets acb14030fe0a:0aae7cf88f0d
487 487 updating to branch stable
488 488 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
489 489
490 490 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
491 491
492 492 $ hg -R ua heads
493 493 changeset: 13:0aae7cf88f0d
494 494 branch: stable
495 495 tag: tip
496 496 user: test
497 497 date: Thu Jan 01 00:00:00 1970 +0000
498 498 summary: another change for branch stable
499 499
500 500 changeset: 10:a7949464abda
501 501 user: test
502 502 date: Thu Jan 01 00:00:00 1970 +0000
503 503 summary: test
504 504
505 505
506 506 Same revision checked out in repo a and ua:
507 507
508 508 $ hg -R a parents --template "{node|short}\n"
509 509 e8ece76546a6
510 510 $ hg -R ua parents --template "{node|short}\n"
511 511 e8ece76546a6
512 512
513 513 $ rm -r ua
514 514
515 515
516 516 Testing -r <branch>:
517 517
518 518 $ hg clone -r stable a ua
519 519 adding changesets
520 520 adding manifests
521 521 adding file changes
522 522 added 14 changesets with 14 changes to 3 files
523 523 new changesets acb14030fe0a:0aae7cf88f0d
524 524 updating to branch stable
525 525 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
526 526
527 527 Repo ua has branch 'stable' and 'default' (was changed in fd511e9eeea6):
528 528
529 529 $ hg -R ua heads
530 530 changeset: 13:0aae7cf88f0d
531 531 branch: stable
532 532 tag: tip
533 533 user: test
534 534 date: Thu Jan 01 00:00:00 1970 +0000
535 535 summary: another change for branch stable
536 536
537 537 changeset: 10:a7949464abda
538 538 user: test
539 539 date: Thu Jan 01 00:00:00 1970 +0000
540 540 summary: test
541 541
542 542
543 543 Branch 'stable' is checked out:
544 544
545 545 $ hg -R ua parents
546 546 changeset: 13:0aae7cf88f0d
547 547 branch: stable
548 548 tag: tip
549 549 user: test
550 550 date: Thu Jan 01 00:00:00 1970 +0000
551 551 summary: another change for branch stable
552 552
553 553
554 554 $ rm -r ua
555 555
556 556
557 557 Issue2267: Error in 1.6 hg.py: TypeError: 'NoneType' object is not
558 558 iterable in addbranchrevs()
559 559
560 560 $ cat <<EOF > simpleclone.py
561 561 > from mercurial import ui, hg
562 562 > myui = ui.ui.load()
563 563 > repo = hg.repository(myui, b'a')
564 564 > hg.clone(myui, {}, repo, dest=b"ua")
565 565 > EOF
566 566
567 567 $ "$PYTHON" simpleclone.py
568 568 updating to branch default
569 569 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
570 570
571 571 $ rm -r ua
572 572
573 573 $ cat <<EOF > branchclone.py
574 574 > from mercurial import ui, hg, extensions
575 575 > myui = ui.ui.load()
576 576 > extensions.loadall(myui)
577 577 > repo = hg.repository(myui, b'a')
578 578 > hg.clone(myui, {}, repo, dest=b"ua", branch=[b"stable",])
579 579 > EOF
580 580
581 581 $ "$PYTHON" branchclone.py
582 582 adding changesets
583 583 adding manifests
584 584 adding file changes
585 585 added 14 changesets with 14 changes to 3 files
586 586 new changesets acb14030fe0a:0aae7cf88f0d
587 587 updating to branch stable
588 588 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
589 589 $ rm -r ua
590 590
591 591
592 592 Test clone with special '@' bookmark:
593 593 $ cd a
594 594 $ hg bookmark -r a7949464abda @ # branch point of stable from default
595 595 $ hg clone . ../i
596 596 updating to bookmark @
597 597 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
598 598 $ hg id -i ../i
599 599 a7949464abda
600 600 $ rm -r ../i
601 601
602 602 $ hg bookmark -f -r stable @
603 603 $ hg bookmarks
604 604 @ 15:0aae7cf88f0d
605 605 $ hg clone . ../i
606 606 updating to bookmark @ on branch stable
607 607 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
608 608 $ hg id -i ../i
609 609 0aae7cf88f0d
610 610 $ cd "$TESTTMP"
611 611
612 612
613 613 Testing failures:
614 614
615 615 $ mkdir fail
616 616 $ cd fail
617 617
618 618 No local source
619 619
620 620 $ hg clone a b
621 621 abort: repository a not found!
622 622 [255]
623 623
624 624 No remote source
625 625
626 626 #if windows
627 627 $ hg clone http://$LOCALIP:3121/a b
628 628 abort: error: * (glob)
629 629 [255]
630 630 #else
631 631 $ hg clone http://$LOCALIP:3121/a b
632 632 abort: error: *refused* (glob)
633 633 [255]
634 634 #endif
635 635 $ rm -rf b # work around bug with http clone
636 636
637 637
638 638 #if unix-permissions no-root
639 639
640 640 Inaccessible source
641 641
642 642 $ mkdir a
643 643 $ chmod 000 a
644 644 $ hg clone a b
645 645 abort: Permission denied: '$TESTTMP/fail/a/.hg'
646 646 [255]
647 647
648 648 Inaccessible destination
649 649
650 650 $ hg init b
651 651 $ cd b
652 652 $ hg clone . ../a
653 653 abort: Permission denied: '../a'
654 654 [255]
655 655 $ cd ..
656 656 $ chmod 700 a
657 657 $ rm -r a b
658 658
659 659 #endif
660 660
661 661
662 662 #if fifo
663 663
664 664 Source of wrong type
665 665
666 666 $ mkfifo a
667 667 $ hg clone a b
668 668 abort: $ENOTDIR$: '$TESTTMP/fail/a/.hg'
669 669 [255]
670 670 $ rm a
671 671
672 672 #endif
673 673
674 674 Default destination, same directory
675 675
676 676 $ hg init q
677 677 $ hg clone q
678 678 destination directory: q
679 679 abort: destination 'q' is not empty
680 680 [255]
681 681
682 682 destination directory not empty
683 683
684 684 $ mkdir a
685 685 $ echo stuff > a/a
686 686 $ hg clone q a
687 687 abort: destination 'a' is not empty
688 688 [255]
689 689
690 690
691 691 #if unix-permissions no-root
692 692
693 693 leave existing directory in place after clone failure
694 694
695 695 $ hg init c
696 696 $ cd c
697 697 $ echo c > c
698 698 $ hg commit -A -m test
699 699 adding c
700 700 $ chmod -rx .hg/store/data
701 701 $ cd ..
702 702 $ mkdir d
703 703 $ hg clone c d 2> err
704 704 [255]
705 705 $ test -d d
706 706 $ test -d d/.hg
707 707 [1]
708 708
709 709 re-enable perm to allow deletion
710 710
711 711 $ chmod +rx c/.hg/store/data
712 712
713 713 #endif
714 714
715 715 $ cd ..
716 716
717 717 Test clone from the repository in (emulated) revlog format 0 (issue4203):
718 718
719 719 $ mkdir issue4203
720 720 $ mkdir -p src/.hg
721 721 $ echo foo > src/foo
722 722 $ hg -R src add src/foo
723 723 $ hg -R src commit -m '#0'
724 724 $ hg -R src log -q
725 725 0:e1bab28bca43
726 726 $ hg clone -U -q src dst
727 727 $ hg -R dst log -q
728 728 0:e1bab28bca43
729 729
730 730 Create repositories to test auto sharing functionality
731 731
732 732 $ cat >> $HGRCPATH << EOF
733 733 > [extensions]
734 734 > share=
735 735 > EOF
736 736
737 737 $ hg init empty
738 738 $ hg init source1a
739 739 $ cd source1a
740 740 $ echo initial1 > foo
741 741 $ hg -q commit -A -m initial
742 742 $ echo second > foo
743 743 $ hg commit -m second
744 744 $ cd ..
745 745
746 746 $ hg init filteredrev0
747 747 $ cd filteredrev0
748 748 $ cat >> .hg/hgrc << EOF
749 749 > [experimental]
750 750 > evolution.createmarkers=True
751 751 > EOF
752 752 $ echo initial1 > foo
753 753 $ hg -q commit -A -m initial0
754 754 $ hg -q up -r null
755 755 $ echo initial2 > foo
756 756 $ hg -q commit -A -m initial1
757 757 $ hg debugobsolete c05d5c47a5cf81401869999f3d05f7d699d2b29a e082c1832e09a7d1e78b7fd49a592d372de854c8
758 758 obsoleted 1 changesets
759 759 $ cd ..
760 760
761 761 $ hg -q clone --pull source1a source1b
762 762 $ cd source1a
763 763 $ hg bookmark bookA
764 764 $ echo 1a > foo
765 765 $ hg commit -m 1a
766 766 $ cd ../source1b
767 767 $ hg -q up -r 0
768 768 $ echo head1 > foo
769 769 $ hg commit -m head1
770 770 created new head
771 771 $ hg bookmark head1
772 772 $ hg -q up -r 0
773 773 $ echo head2 > foo
774 774 $ hg commit -m head2
775 775 created new head
776 776 $ hg bookmark head2
777 777 $ hg -q up -r 0
778 778 $ hg branch branch1
779 779 marked working directory as branch branch1
780 780 (branches are permanent and global, did you want a bookmark?)
781 781 $ echo branch1 > foo
782 782 $ hg commit -m branch1
783 783 $ hg -q up -r 0
784 784 $ hg branch branch2
785 785 marked working directory as branch branch2
786 786 $ echo branch2 > foo
787 787 $ hg commit -m branch2
788 788 $ cd ..
789 789 $ hg init source2
790 790 $ cd source2
791 791 $ echo initial2 > foo
792 792 $ hg -q commit -A -m initial2
793 793 $ echo second > foo
794 794 $ hg commit -m second
795 795 $ cd ..
796 796
797 797 Clone with auto share from an empty repo should not result in share
798 798
799 799 $ mkdir share
800 800 $ hg --config share.pool=share clone empty share-empty
801 801 (not using pooled storage: remote appears to be empty)
802 802 updating to branch default
803 803 0 files updated, 0 files merged, 0 files removed, 0 files unresolved
804 804 $ ls share
805 805 $ test -d share-empty/.hg/store
806 806 $ test -f share-empty/.hg/sharedpath
807 807 [1]
808 808
809 809 Clone with auto share from a repo with filtered revision 0 should not result in share
810 810
811 811 $ hg --config share.pool=share clone filteredrev0 share-filtered
812 812 (not using pooled storage: unable to resolve identity of remote)
813 813 requesting all changes
814 814 adding changesets
815 815 adding manifests
816 816 adding file changes
817 817 added 1 changesets with 1 changes to 1 files
818 818 new changesets e082c1832e09
819 819 updating to branch default
820 820 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
821 821
822 822 Clone from repo with content should result in shared store being created
823 823
824 824 $ hg --config share.pool=share clone source1a share-dest1a
825 825 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
826 826 requesting all changes
827 827 adding changesets
828 828 adding manifests
829 829 adding file changes
830 830 added 3 changesets with 3 changes to 1 files
831 831 new changesets b5f04eac9d8f:e5bfe23c0b47
832 832 searching for changes
833 833 no changes found
834 834 adding remote bookmark bookA
835 835 updating working directory
836 836 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
837 837
838 838 The shared repo should have been created
839 839
840 840 $ ls share
841 841 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
842 842
843 843 The destination should point to it
844 844
845 845 $ cat share-dest1a/.hg/sharedpath; echo
846 846 $TESTTMP/share/b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1/.hg
847 847
848 848 The destination should have bookmarks
849 849
850 850 $ hg -R share-dest1a bookmarks
851 851 bookA 2:e5bfe23c0b47
852 852
853 853 The default path should be the remote, not the share
854 854
855 855 $ hg -R share-dest1a config paths.default
856 856 $TESTTMP/source1a
857 857
858 858 Clone with existing share dir should result in pull + share
859 859
860 860 $ hg --config share.pool=share clone source1b share-dest1b
861 861 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
862 862 searching for changes
863 863 adding changesets
864 864 adding manifests
865 865 adding file changes
866 866 added 4 changesets with 4 changes to 1 files (+4 heads)
867 867 adding remote bookmark head1
868 868 adding remote bookmark head2
869 869 new changesets 4a8dc1ab4c13:6bacf4683960
870 870 updating working directory
871 871 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
872 872
873 873 $ ls share
874 874 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
875 875
876 876 $ cat share-dest1b/.hg/sharedpath; echo
877 877 $TESTTMP/share/b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1/.hg
878 878
879 879 We only get bookmarks from the remote, not everything in the share
880 880
881 881 $ hg -R share-dest1b bookmarks
882 882 head1 3:4a8dc1ab4c13
883 883 head2 4:99f71071f117
884 884
885 885 Default path should be source, not share.
886 886
887 887 $ hg -R share-dest1b config paths.default
888 888 $TESTTMP/source1b
889 889
890 890 Checked out revision should be head of default branch
891 891
892 892 $ hg -R share-dest1b log -r .
893 893 changeset: 4:99f71071f117
894 894 bookmark: head2
895 895 parent: 0:b5f04eac9d8f
896 896 user: test
897 897 date: Thu Jan 01 00:00:00 1970 +0000
898 898 summary: head2
899 899
900 900
901 901 Clone from unrelated repo should result in new share
902 902
903 903 $ hg --config share.pool=share clone source2 share-dest2
904 904 (sharing from new pooled repository 22aeff664783fd44c6d9b435618173c118c3448e)
905 905 requesting all changes
906 906 adding changesets
907 907 adding manifests
908 908 adding file changes
909 909 added 2 changesets with 2 changes to 1 files
910 910 new changesets 22aeff664783:63cf6c3dba4a
911 911 searching for changes
912 912 no changes found
913 913 updating working directory
914 914 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
915 915
916 916 $ ls share
917 917 22aeff664783fd44c6d9b435618173c118c3448e
918 918 b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1
919 919
920 920 remote naming mode works as advertised
921 921
922 922 $ hg --config share.pool=shareremote --config share.poolnaming=remote clone source1a share-remote1a
923 923 (sharing from new pooled repository 195bb1fcdb595c14a6c13e0269129ed78f6debde)
924 924 requesting all changes
925 925 adding changesets
926 926 adding manifests
927 927 adding file changes
928 928 added 3 changesets with 3 changes to 1 files
929 929 new changesets b5f04eac9d8f:e5bfe23c0b47
930 930 searching for changes
931 931 no changes found
932 932 adding remote bookmark bookA
933 933 updating working directory
934 934 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
935 935
936 936 $ ls shareremote
937 937 195bb1fcdb595c14a6c13e0269129ed78f6debde
938 938
939 939 $ hg --config share.pool=shareremote --config share.poolnaming=remote clone source1b share-remote1b
940 940 (sharing from new pooled repository c0d4f83847ca2a873741feb7048a45085fd47c46)
941 941 requesting all changes
942 942 adding changesets
943 943 adding manifests
944 944 adding file changes
945 945 added 6 changesets with 6 changes to 1 files (+4 heads)
946 946 new changesets b5f04eac9d8f:6bacf4683960
947 947 searching for changes
948 948 no changes found
949 949 adding remote bookmark head1
950 950 adding remote bookmark head2
951 951 updating working directory
952 952 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
953 953
954 954 $ ls shareremote
955 955 195bb1fcdb595c14a6c13e0269129ed78f6debde
956 956 c0d4f83847ca2a873741feb7048a45085fd47c46
957 957
958 958 request to clone a single revision is respected in sharing mode
959 959
960 960 $ hg --config share.pool=sharerevs clone -r 4a8dc1ab4c13 source1b share-1arev
961 961 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
962 962 adding changesets
963 963 adding manifests
964 964 adding file changes
965 965 added 2 changesets with 2 changes to 1 files
966 966 new changesets b5f04eac9d8f:4a8dc1ab4c13
967 967 no changes found
968 968 adding remote bookmark head1
969 969 updating working directory
970 970 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
971 971
972 972 $ hg -R share-1arev log -G
973 973 @ changeset: 1:4a8dc1ab4c13
974 974 | bookmark: head1
975 975 | tag: tip
976 976 | user: test
977 977 | date: Thu Jan 01 00:00:00 1970 +0000
978 978 | summary: head1
979 979 |
980 980 o changeset: 0:b5f04eac9d8f
981 981 user: test
982 982 date: Thu Jan 01 00:00:00 1970 +0000
983 983 summary: initial
984 984
985 985
986 986 making another clone should only pull down requested rev
987 987
988 988 $ hg --config share.pool=sharerevs clone -r 99f71071f117 source1b share-1brev
989 989 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
990 990 searching for changes
991 991 adding changesets
992 992 adding manifests
993 993 adding file changes
994 994 added 1 changesets with 1 changes to 1 files (+1 heads)
995 995 adding remote bookmark head1
996 996 adding remote bookmark head2
997 997 new changesets 99f71071f117
998 998 updating working directory
999 999 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1000 1000
1001 1001 $ hg -R share-1brev log -G
1002 1002 @ changeset: 2:99f71071f117
1003 1003 | bookmark: head2
1004 1004 | tag: tip
1005 1005 | parent: 0:b5f04eac9d8f
1006 1006 | user: test
1007 1007 | date: Thu Jan 01 00:00:00 1970 +0000
1008 1008 | summary: head2
1009 1009 |
1010 1010 | o changeset: 1:4a8dc1ab4c13
1011 1011 |/ bookmark: head1
1012 1012 | user: test
1013 1013 | date: Thu Jan 01 00:00:00 1970 +0000
1014 1014 | summary: head1
1015 1015 |
1016 1016 o changeset: 0:b5f04eac9d8f
1017 1017 user: test
1018 1018 date: Thu Jan 01 00:00:00 1970 +0000
1019 1019 summary: initial
1020 1020
1021 1021
1022 1022 Request to clone a single branch is respected in sharing mode
1023 1023
1024 1024 $ hg --config share.pool=sharebranch clone -b branch1 source1b share-1bbranch1
1025 1025 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1026 1026 adding changesets
1027 1027 adding manifests
1028 1028 adding file changes
1029 1029 added 2 changesets with 2 changes to 1 files
1030 1030 new changesets b5f04eac9d8f:5f92a6c1a1b1
1031 1031 no changes found
1032 1032 updating working directory
1033 1033 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1034 1034
1035 1035 $ hg -R share-1bbranch1 log -G
1036 1036 o changeset: 1:5f92a6c1a1b1
1037 1037 | branch: branch1
1038 1038 | tag: tip
1039 1039 | user: test
1040 1040 | date: Thu Jan 01 00:00:00 1970 +0000
1041 1041 | summary: branch1
1042 1042 |
1043 1043 @ changeset: 0:b5f04eac9d8f
1044 1044 user: test
1045 1045 date: Thu Jan 01 00:00:00 1970 +0000
1046 1046 summary: initial
1047 1047
1048 1048
1049 1049 $ hg --config share.pool=sharebranch clone -b branch2 source1b share-1bbranch2
1050 1050 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1051 1051 searching for changes
1052 1052 adding changesets
1053 1053 adding manifests
1054 1054 adding file changes
1055 1055 added 1 changesets with 1 changes to 1 files (+1 heads)
1056 1056 new changesets 6bacf4683960
1057 1057 updating working directory
1058 1058 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1059 1059
1060 1060 $ hg -R share-1bbranch2 log -G
1061 1061 o changeset: 2:6bacf4683960
1062 1062 | branch: branch2
1063 1063 | tag: tip
1064 1064 | parent: 0:b5f04eac9d8f
1065 1065 | user: test
1066 1066 | date: Thu Jan 01 00:00:00 1970 +0000
1067 1067 | summary: branch2
1068 1068 |
1069 1069 | o changeset: 1:5f92a6c1a1b1
1070 1070 |/ branch: branch1
1071 1071 | user: test
1072 1072 | date: Thu Jan 01 00:00:00 1970 +0000
1073 1073 | summary: branch1
1074 1074 |
1075 1075 @ changeset: 0:b5f04eac9d8f
1076 1076 user: test
1077 1077 date: Thu Jan 01 00:00:00 1970 +0000
1078 1078 summary: initial
1079 1079
1080 1080
1081 1081 -U is respected in share clone mode
1082 1082
1083 1083 $ hg --config share.pool=share clone -U source1a share-1anowc
1084 1084 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1085 1085 searching for changes
1086 1086 no changes found
1087 1087 adding remote bookmark bookA
1088 1088
1089 1089 $ ls share-1anowc
1090 1090
1091 1091 Test that auto sharing doesn't cause failure of "hg clone local remote"
1092 1092
1093 1093 $ cd $TESTTMP
1094 1094 $ hg -R a id -r 0
1095 1095 acb14030fe0a
1096 1096 $ hg id -R remote -r 0
1097 1097 abort: repository remote not found!
1098 1098 [255]
1099 1099 $ hg --config share.pool=share -q clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" a ssh://user@dummy/remote
1100 1100 $ hg -R remote id -r 0
1101 1101 acb14030fe0a
1102 1102
1103 1103 Cloning into pooled storage doesn't race (issue5104)
1104 1104
1105 1105 $ HGPOSTLOCKDELAY=2.0 hg --config share.pool=racepool --config extensions.lockdelay=$TESTDIR/lockdelay.py clone source1a share-destrace1 > race1.log 2>&1 &
1106 1106 $ HGPRELOCKDELAY=1.0 hg --config share.pool=racepool --config extensions.lockdelay=$TESTDIR/lockdelay.py clone source1a share-destrace2 > race2.log 2>&1
1107 1107 $ wait
1108 1108
1109 1109 $ hg -R share-destrace1 log -r tip
1110 1110 changeset: 2:e5bfe23c0b47
1111 1111 bookmark: bookA
1112 1112 tag: tip
1113 1113 user: test
1114 1114 date: Thu Jan 01 00:00:00 1970 +0000
1115 1115 summary: 1a
1116 1116
1117 1117
1118 1118 $ hg -R share-destrace2 log -r tip
1119 1119 changeset: 2:e5bfe23c0b47
1120 1120 bookmark: bookA
1121 1121 tag: tip
1122 1122 user: test
1123 1123 date: Thu Jan 01 00:00:00 1970 +0000
1124 1124 summary: 1a
1125 1125
1126 1126 One repo should be new, the other should be shared from the pool. We
1127 1127 don't care which is which, so we just make sure we always print the
1128 1128 one containing "new pooled" first, then one one containing "existing
1129 1129 pooled".
1130 1130
1131 1131 $ (grep 'new pooled' race1.log > /dev/null && cat race1.log || cat race2.log) | grep -v lock
1132 1132 (sharing from new pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1133 1133 requesting all changes
1134 1134 adding changesets
1135 1135 adding manifests
1136 1136 adding file changes
1137 1137 added 3 changesets with 3 changes to 1 files
1138 1138 new changesets b5f04eac9d8f:e5bfe23c0b47
1139 1139 searching for changes
1140 1140 no changes found
1141 1141 adding remote bookmark bookA
1142 1142 updating working directory
1143 1143 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1144 1144
1145 1145 $ (grep 'existing pooled' race1.log > /dev/null && cat race1.log || cat race2.log) | grep -v lock
1146 1146 (sharing from existing pooled repository b5f04eac9d8f7a6a9fcb070243cccea7dc5ea0c1)
1147 1147 searching for changes
1148 1148 no changes found
1149 1149 adding remote bookmark bookA
1150 1150 updating working directory
1151 1151 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1152 1152
1153 1153 SEC: check for unsafe ssh url
1154 1154
1155 1155 $ cat >> $HGRCPATH << EOF
1156 1156 > [ui]
1157 1157 > ssh = sh -c "read l; read l; read l"
1158 1158 > EOF
1159 1159
1160 1160 $ hg clone 'ssh://-oProxyCommand=touch${IFS}owned/path'
1161 1161 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path'
1162 1162 [255]
1163 1163 $ hg clone 'ssh://%2DoProxyCommand=touch${IFS}owned/path'
1164 1164 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch${IFS}owned/path'
1165 1165 [255]
1166 1166 $ hg clone 'ssh://fakehost|touch%20owned/path'
1167 1167 abort: no suitable response from remote hg!
1168 1168 [255]
1169 1169 $ hg clone 'ssh://fakehost%7Ctouch%20owned/path'
1170 1170 abort: no suitable response from remote hg!
1171 1171 [255]
1172 1172
1173 1173 $ hg clone 'ssh://-oProxyCommand=touch owned%20foo@example.com/nonexistent/path'
1174 1174 abort: potentially unsafe url: 'ssh://-oProxyCommand=touch owned foo@example.com/nonexistent/path'
1175 1175 [255]
1176 1176
1177 1177 #if windows
1178 1178 $ hg clone "ssh://%26touch%20owned%20/" --debug
1179 1179 running sh -c "read l; read l; read l" "&touch owned " "hg -R . serve --stdio"
1180 sending upgrade request: * proto=exp-ssh-v2-0001 (glob) (sshv2 !)
1180 sending upgrade request: * proto=exp-ssh-v2-0002 (glob) (sshv2 !)
1181 1181 sending hello command
1182 1182 sending between command
1183 1183 abort: no suitable response from remote hg!
1184 1184 [255]
1185 1185 $ hg clone "ssh://example.com:%26touch%20owned%20/" --debug
1186 1186 running sh -c "read l; read l; read l" -p "&touch owned " example.com "hg -R . serve --stdio"
1187 sending upgrade request: * proto=exp-ssh-v2-0001 (glob) (sshv2 !)
1187 sending upgrade request: * proto=exp-ssh-v2-0002 (glob) (sshv2 !)
1188 1188 sending hello command
1189 1189 sending between command
1190 1190 abort: no suitable response from remote hg!
1191 1191 [255]
1192 1192 #else
1193 1193 $ hg clone "ssh://%3btouch%20owned%20/" --debug
1194 1194 running sh -c "read l; read l; read l" ';touch owned ' 'hg -R . serve --stdio'
1195 sending upgrade request: * proto=exp-ssh-v2-0001 (glob) (sshv2 !)
1195 sending upgrade request: * proto=exp-ssh-v2-0002 (glob) (sshv2 !)
1196 1196 sending hello command
1197 1197 sending between command
1198 1198 abort: no suitable response from remote hg!
1199 1199 [255]
1200 1200 $ hg clone "ssh://example.com:%3btouch%20owned%20/" --debug
1201 1201 running sh -c "read l; read l; read l" -p ';touch owned ' example.com 'hg -R . serve --stdio'
1202 sending upgrade request: * proto=exp-ssh-v2-0001 (glob) (sshv2 !)
1202 sending upgrade request: * proto=exp-ssh-v2-0002 (glob) (sshv2 !)
1203 1203 sending hello command
1204 1204 sending between command
1205 1205 abort: no suitable response from remote hg!
1206 1206 [255]
1207 1207 #endif
1208 1208
1209 1209 $ hg clone "ssh://v-alid.example.com/" --debug
1210 1210 running sh -c "read l; read l; read l" v-alid\.example\.com ['"]hg -R \. serve --stdio['"] (re)
1211 sending upgrade request: * proto=exp-ssh-v2-0001 (glob) (sshv2 !)
1211 sending upgrade request: * proto=exp-ssh-v2-0002 (glob) (sshv2 !)
1212 1212 sending hello command
1213 1213 sending between command
1214 1214 abort: no suitable response from remote hg!
1215 1215 [255]
1216 1216
1217 1217 We should not have created a file named owned - if it exists, the
1218 1218 attack succeeded.
1219 1219 $ if test -f owned; then echo 'you got owned'; fi
1220 1220
1221 1221 Cloning without fsmonitor enabled does not print a warning for small repos
1222 1222
1223 1223 $ hg clone a fsmonitor-default
1224 1224 updating to bookmark @ on branch stable
1225 1225 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1226 1226
1227 1227 Lower the warning threshold to simulate a large repo
1228 1228
1229 1229 $ cat >> $HGRCPATH << EOF
1230 1230 > [fsmonitor]
1231 1231 > warn_update_file_count = 2
1232 1232 > EOF
1233 1233
1234 1234 We should see a warning about no fsmonitor on supported platforms
1235 1235
1236 1236 #if linuxormacos no-fsmonitor
1237 1237 $ hg clone a nofsmonitor
1238 1238 updating to bookmark @ on branch stable
1239 1239 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor")
1240 1240 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1241 1241 #else
1242 1242 $ hg clone a nofsmonitor
1243 1243 updating to bookmark @ on branch stable
1244 1244 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1245 1245 #endif
1246 1246
1247 1247 We should not see warning about fsmonitor when it is enabled
1248 1248
1249 1249 #if fsmonitor
1250 1250 $ hg clone a fsmonitor-enabled
1251 1251 updating to bookmark @ on branch stable
1252 1252 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1253 1253 #endif
1254 1254
1255 1255 We can disable the fsmonitor warning
1256 1256
1257 1257 $ hg --config fsmonitor.warn_when_unused=false clone a fsmonitor-disable-warning
1258 1258 updating to bookmark @ on branch stable
1259 1259 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1260 1260
1261 1261 Loaded fsmonitor but disabled in config should still print warning
1262 1262
1263 1263 #if linuxormacos fsmonitor
1264 1264 $ hg --config fsmonitor.mode=off clone a fsmonitor-mode-off
1265 1265 updating to bookmark @ on branch stable
1266 1266 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor") (fsmonitor !)
1267 1267 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
1268 1268 #endif
1269 1269
1270 1270 Warning not printed if working directory isn't empty
1271 1271
1272 1272 $ hg -q clone a fsmonitor-update
1273 1273 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor") (?)
1274 1274 $ cd fsmonitor-update
1275 1275 $ hg up acb14030fe0a
1276 1276 1 files updated, 0 files merged, 2 files removed, 0 files unresolved
1277 1277 (leaving bookmark @)
1278 1278 $ hg up cf0fe1914066
1279 1279 1 files updated, 0 files merged, 0 files removed, 0 files unresolved
1280 1280
1281 1281 `hg update` from null revision also prints
1282 1282
1283 1283 $ hg up null
1284 1284 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
1285 1285
1286 1286 #if linuxormacos no-fsmonitor
1287 1287 $ hg up cf0fe1914066
1288 1288 (warning: large working directory being used without fsmonitor enabled; enable fsmonitor to improve performance; see "hg help -e fsmonitor")
1289 1289 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1290 1290 #else
1291 1291 $ hg up cf0fe1914066
1292 1292 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
1293 1293 #endif
1294 1294
1295 1295 $ cd ..
1296 1296
@@ -1,619 +1,619 b''
1 1 #require no-chg
2 2
3 3 $ . $TESTDIR/wireprotohelpers.sh
4 4 $ enabledummycommands
5 5
6 6 $ hg init server
7 7 $ cat > server/.hg/hgrc << EOF
8 8 > [experimental]
9 9 > web.apiserver = true
10 10 > EOF
11 11 $ hg -R server serve -p $HGPORT -d --pid-file hg.pid
12 12 $ cat hg.pid > $DAEMON_PIDS
13 13
14 14 HTTP v2 protocol not enabled by default
15 15
16 16 $ sendhttpraw << EOF
17 17 > httprequest GET api/$HTTPV2
18 18 > user-agent: test
19 19 > EOF
20 20 using raw connection to peer
21 s> GET /api/exp-http-v2-0001 HTTP/1.1\r\n
21 s> GET /api/exp-http-v2-0002 HTTP/1.1\r\n
22 22 s> Accept-Encoding: identity\r\n
23 23 s> user-agent: test\r\n
24 24 s> host: $LOCALIP:$HGPORT\r\n (glob)
25 25 s> \r\n
26 26 s> makefile('rb', None)
27 27 s> HTTP/1.1 404 Not Found\r\n
28 28 s> Server: testing stub value\r\n
29 29 s> Date: $HTTP_DATE$\r\n
30 30 s> Content-Type: text/plain\r\n
31 31 s> Content-Length: 33\r\n
32 32 s> \r\n
33 s> API exp-http-v2-0001 not enabled\n
33 s> API exp-http-v2-0002 not enabled\n
34 34
35 35 Restart server with support for HTTP v2 API
36 36
37 37 $ killdaemons.py
38 38 $ enablehttpv2 server
39 39 $ hg -R server serve -p $HGPORT -d --pid-file hg.pid
40 40 $ cat hg.pid > $DAEMON_PIDS
41 41
42 42 Request to unknown command yields 404
43 43
44 44 $ sendhttpraw << EOF
45 45 > httprequest POST api/$HTTPV2/ro/badcommand
46 46 > user-agent: test
47 47 > EOF
48 48 using raw connection to peer
49 s> POST /api/exp-http-v2-0001/ro/badcommand HTTP/1.1\r\n
49 s> POST /api/exp-http-v2-0002/ro/badcommand HTTP/1.1\r\n
50 50 s> Accept-Encoding: identity\r\n
51 51 s> user-agent: test\r\n
52 52 s> host: $LOCALIP:$HGPORT\r\n (glob)
53 53 s> \r\n
54 54 s> makefile('rb', None)
55 55 s> HTTP/1.1 404 Not Found\r\n
56 56 s> Server: testing stub value\r\n
57 57 s> Date: $HTTP_DATE$\r\n
58 58 s> Content-Type: text/plain\r\n
59 59 s> Content-Length: 42\r\n
60 60 s> \r\n
61 61 s> unknown wire protocol command: badcommand\n
62 62
63 63 GET to read-only command yields a 405
64 64
65 65 $ sendhttpraw << EOF
66 66 > httprequest GET api/$HTTPV2/ro/customreadonly
67 67 > user-agent: test
68 68 > EOF
69 69 using raw connection to peer
70 s> GET /api/exp-http-v2-0001/ro/customreadonly HTTP/1.1\r\n
70 s> GET /api/exp-http-v2-0002/ro/customreadonly HTTP/1.1\r\n
71 71 s> Accept-Encoding: identity\r\n
72 72 s> user-agent: test\r\n
73 73 s> host: $LOCALIP:$HGPORT\r\n (glob)
74 74 s> \r\n
75 75 s> makefile('rb', None)
76 76 s> HTTP/1.1 405 Method Not Allowed\r\n
77 77 s> Server: testing stub value\r\n
78 78 s> Date: $HTTP_DATE$\r\n
79 79 s> Allow: POST\r\n
80 80 s> Content-Length: 30\r\n
81 81 s> \r\n
82 82 s> commands require POST requests
83 83
84 84 Missing Accept header results in 406
85 85
86 86 $ sendhttpraw << EOF
87 87 > httprequest POST api/$HTTPV2/ro/customreadonly
88 88 > user-agent: test
89 89 > EOF
90 90 using raw connection to peer
91 s> POST /api/exp-http-v2-0001/ro/customreadonly HTTP/1.1\r\n
91 s> POST /api/exp-http-v2-0002/ro/customreadonly HTTP/1.1\r\n
92 92 s> Accept-Encoding: identity\r\n
93 93 s> user-agent: test\r\n
94 94 s> host: $LOCALIP:$HGPORT\r\n (glob)
95 95 s> \r\n
96 96 s> makefile('rb', None)
97 97 s> HTTP/1.1 406 Not Acceptable\r\n
98 98 s> Server: testing stub value\r\n
99 99 s> Date: $HTTP_DATE$\r\n
100 100 s> Content-Type: text/plain\r\n
101 101 s> Content-Length: 85\r\n
102 102 s> \r\n
103 103 s> client MUST specify Accept header with value: application/mercurial-exp-framing-0005\n
104 104
105 105 Bad Accept header results in 406
106 106
107 107 $ sendhttpraw << EOF
108 108 > httprequest POST api/$HTTPV2/ro/customreadonly
109 109 > accept: invalid
110 110 > user-agent: test
111 111 > EOF
112 112 using raw connection to peer
113 s> POST /api/exp-http-v2-0001/ro/customreadonly HTTP/1.1\r\n
113 s> POST /api/exp-http-v2-0002/ro/customreadonly HTTP/1.1\r\n
114 114 s> Accept-Encoding: identity\r\n
115 115 s> accept: invalid\r\n
116 116 s> user-agent: test\r\n
117 117 s> host: $LOCALIP:$HGPORT\r\n (glob)
118 118 s> \r\n
119 119 s> makefile('rb', None)
120 120 s> HTTP/1.1 406 Not Acceptable\r\n
121 121 s> Server: testing stub value\r\n
122 122 s> Date: $HTTP_DATE$\r\n
123 123 s> Content-Type: text/plain\r\n
124 124 s> Content-Length: 85\r\n
125 125 s> \r\n
126 126 s> client MUST specify Accept header with value: application/mercurial-exp-framing-0005\n
127 127
128 128 Bad Content-Type header results in 415
129 129
130 130 $ sendhttpraw << EOF
131 131 > httprequest POST api/$HTTPV2/ro/customreadonly
132 132 > accept: $MEDIATYPE
133 133 > user-agent: test
134 134 > content-type: badmedia
135 135 > EOF
136 136 using raw connection to peer
137 s> POST /api/exp-http-v2-0001/ro/customreadonly HTTP/1.1\r\n
137 s> POST /api/exp-http-v2-0002/ro/customreadonly HTTP/1.1\r\n
138 138 s> Accept-Encoding: identity\r\n
139 139 s> accept: application/mercurial-exp-framing-0005\r\n
140 140 s> content-type: badmedia\r\n
141 141 s> user-agent: test\r\n
142 142 s> host: $LOCALIP:$HGPORT\r\n (glob)
143 143 s> \r\n
144 144 s> makefile('rb', None)
145 145 s> HTTP/1.1 415 Unsupported Media Type\r\n
146 146 s> Server: testing stub value\r\n
147 147 s> Date: $HTTP_DATE$\r\n
148 148 s> Content-Type: text/plain\r\n
149 149 s> Content-Length: 88\r\n
150 150 s> \r\n
151 151 s> client MUST send Content-Type header with value: application/mercurial-exp-framing-0005\n
152 152
153 153 Request to read-only command works out of the box
154 154
155 155 $ sendhttpraw << EOF
156 156 > httprequest POST api/$HTTPV2/ro/customreadonly
157 157 > accept: $MEDIATYPE
158 158 > content-type: $MEDIATYPE
159 159 > user-agent: test
160 160 > frame 1 1 stream-begin command-request new cbor:{b'name': b'customreadonly'}
161 161 > EOF
162 162 using raw connection to peer
163 s> POST /api/exp-http-v2-0001/ro/customreadonly HTTP/1.1\r\n
163 s> POST /api/exp-http-v2-0002/ro/customreadonly HTTP/1.1\r\n
164 164 s> Accept-Encoding: identity\r\n
165 165 s> *\r\n (glob)
166 166 s> content-type: application/mercurial-exp-framing-0005\r\n
167 167 s> user-agent: test\r\n
168 168 s> content-length: 29\r\n
169 169 s> host: $LOCALIP:$HGPORT\r\n (glob)
170 170 s> \r\n
171 171 s> \x15\x00\x00\x01\x00\x01\x01\x11\xa1DnameNcustomreadonly
172 172 s> makefile('rb', None)
173 173 s> HTTP/1.1 200 OK\r\n
174 174 s> Server: testing stub value\r\n
175 175 s> Date: $HTTP_DATE$\r\n
176 176 s> Content-Type: application/mercurial-exp-framing-0005\r\n
177 177 s> Transfer-Encoding: chunked\r\n
178 178 s> \r\n
179 179 s> 13\r\n
180 180 s> \x0b\x00\x00\x01\x00\x02\x011\xa1FstatusBok
181 181 s> \r\n
182 182 s> 27\r\n
183 183 s> \x1f\x00\x00\x01\x00\x02\x001X\x1dcustomreadonly bytes response
184 184 s> \r\n
185 185 s> 8\r\n
186 186 s> \x00\x00\x00\x01\x00\x02\x002
187 187 s> \r\n
188 188 s> 0\r\n
189 189 s> \r\n
190 190
191 191 $ sendhttpv2peer << EOF
192 192 > command customreadonly
193 193 > EOF
194 194 creating http peer for wire protocol version 2
195 195 sending customreadonly command
196 s> POST /api/exp-http-v2-0001/ro/customreadonly HTTP/1.1\r\n
196 s> POST /api/exp-http-v2-0002/ro/customreadonly HTTP/1.1\r\n
197 197 s> Accept-Encoding: identity\r\n
198 198 s> accept: application/mercurial-exp-framing-0005\r\n
199 199 s> content-type: application/mercurial-exp-framing-0005\r\n
200 200 s> content-length: 29\r\n
201 201 s> host: $LOCALIP:$HGPORT\r\n (glob)
202 202 s> user-agent: Mercurial debugwireproto\r\n
203 203 s> \r\n
204 204 s> \x15\x00\x00\x01\x00\x01\x01\x11\xa1DnameNcustomreadonly
205 205 s> makefile('rb', None)
206 206 s> HTTP/1.1 200 OK\r\n
207 207 s> Server: testing stub value\r\n
208 208 s> Date: $HTTP_DATE$\r\n
209 209 s> Content-Type: application/mercurial-exp-framing-0005\r\n
210 210 s> Transfer-Encoding: chunked\r\n
211 211 s> \r\n
212 212 s> 13\r\n
213 213 s> \x0b\x00\x00\x01\x00\x02\x011
214 214 s> \xa1FstatusBok
215 215 s> \r\n
216 216 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
217 217 s> 27\r\n
218 218 s> \x1f\x00\x00\x01\x00\x02\x001
219 219 s> X\x1dcustomreadonly bytes response
220 220 s> \r\n
221 221 received frame(size=31; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
222 222 s> 8\r\n
223 223 s> \x00\x00\x00\x01\x00\x02\x002
224 224 s> \r\n
225 225 s> 0\r\n
226 226 s> \r\n
227 227 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
228 228 response: gen[
229 229 b'customreadonly bytes response'
230 230 ]
231 231
232 232 Request to read-write command fails because server is read-only by default
233 233
234 234 GET to read-write request yields 405
235 235
236 236 $ sendhttpraw << EOF
237 237 > httprequest GET api/$HTTPV2/rw/customreadonly
238 238 > user-agent: test
239 239 > EOF
240 240 using raw connection to peer
241 s> GET /api/exp-http-v2-0001/rw/customreadonly HTTP/1.1\r\n
241 s> GET /api/exp-http-v2-0002/rw/customreadonly HTTP/1.1\r\n
242 242 s> Accept-Encoding: identity\r\n
243 243 s> user-agent: test\r\n
244 244 s> host: $LOCALIP:$HGPORT\r\n (glob)
245 245 s> \r\n
246 246 s> makefile('rb', None)
247 247 s> HTTP/1.1 405 Method Not Allowed\r\n
248 248 s> Server: testing stub value\r\n
249 249 s> Date: $HTTP_DATE$\r\n
250 250 s> Allow: POST\r\n
251 251 s> Content-Length: 30\r\n
252 252 s> \r\n
253 253 s> commands require POST requests
254 254
255 255 Even for unknown commands
256 256
257 257 $ sendhttpraw << EOF
258 258 > httprequest GET api/$HTTPV2/rw/badcommand
259 259 > user-agent: test
260 260 > EOF
261 261 using raw connection to peer
262 s> GET /api/exp-http-v2-0001/rw/badcommand HTTP/1.1\r\n
262 s> GET /api/exp-http-v2-0002/rw/badcommand HTTP/1.1\r\n
263 263 s> Accept-Encoding: identity\r\n
264 264 s> user-agent: test\r\n
265 265 s> host: $LOCALIP:$HGPORT\r\n (glob)
266 266 s> \r\n
267 267 s> makefile('rb', None)
268 268 s> HTTP/1.1 405 Method Not Allowed\r\n
269 269 s> Server: testing stub value\r\n
270 270 s> Date: $HTTP_DATE$\r\n
271 271 s> Allow: POST\r\n
272 272 s> Content-Length: 30\r\n
273 273 s> \r\n
274 274 s> commands require POST requests
275 275
276 276 SSL required by default
277 277
278 278 $ sendhttpraw << EOF
279 279 > httprequest POST api/$HTTPV2/rw/customreadonly
280 280 > user-agent: test
281 281 > EOF
282 282 using raw connection to peer
283 s> POST /api/exp-http-v2-0001/rw/customreadonly HTTP/1.1\r\n
283 s> POST /api/exp-http-v2-0002/rw/customreadonly HTTP/1.1\r\n
284 284 s> Accept-Encoding: identity\r\n
285 285 s> user-agent: test\r\n
286 286 s> host: $LOCALIP:$HGPORT\r\n (glob)
287 287 s> \r\n
288 288 s> makefile('rb', None)
289 289 s> HTTP/1.1 403 ssl required\r\n
290 290 s> Server: testing stub value\r\n
291 291 s> Date: $HTTP_DATE$\r\n
292 292 s> Content-Length: 17\r\n
293 293 s> \r\n
294 294 s> permission denied
295 295
296 296 Restart server to allow non-ssl read-write operations
297 297
298 298 $ killdaemons.py
299 299 $ cat > server/.hg/hgrc << EOF
300 300 > [experimental]
301 301 > web.apiserver = true
302 302 > web.api.http-v2 = true
303 303 > [web]
304 304 > push_ssl = false
305 305 > allow-push = *
306 306 > EOF
307 307
308 308 $ hg -R server serve -p $HGPORT -d --pid-file hg.pid -E error.log
309 309 $ cat hg.pid > $DAEMON_PIDS
310 310
311 311 Authorized request for valid read-write command works
312 312
313 313 $ sendhttpraw << EOF
314 314 > httprequest POST api/$HTTPV2/rw/customreadonly
315 315 > user-agent: test
316 316 > accept: $MEDIATYPE
317 317 > content-type: $MEDIATYPE
318 318 > frame 1 1 stream-begin command-request new cbor:{b'name': b'customreadonly'}
319 319 > EOF
320 320 using raw connection to peer
321 s> POST /api/exp-http-v2-0001/rw/customreadonly HTTP/1.1\r\n
321 s> POST /api/exp-http-v2-0002/rw/customreadonly HTTP/1.1\r\n
322 322 s> Accept-Encoding: identity\r\n
323 323 s> accept: application/mercurial-exp-framing-0005\r\n
324 324 s> content-type: application/mercurial-exp-framing-0005\r\n
325 325 s> user-agent: test\r\n
326 326 s> content-length: 29\r\n
327 327 s> host: $LOCALIP:$HGPORT\r\n (glob)
328 328 s> \r\n
329 329 s> \x15\x00\x00\x01\x00\x01\x01\x11\xa1DnameNcustomreadonly
330 330 s> makefile('rb', None)
331 331 s> HTTP/1.1 200 OK\r\n
332 332 s> Server: testing stub value\r\n
333 333 s> Date: $HTTP_DATE$\r\n
334 334 s> Content-Type: application/mercurial-exp-framing-0005\r\n
335 335 s> Transfer-Encoding: chunked\r\n
336 336 s> \r\n
337 337 s> 13\r\n
338 338 s> \x0b\x00\x00\x01\x00\x02\x011\xa1FstatusBok
339 339 s> \r\n
340 340 s> 27\r\n
341 341 s> \x1f\x00\x00\x01\x00\x02\x001X\x1dcustomreadonly bytes response
342 342 s> \r\n
343 343 s> 8\r\n
344 344 s> \x00\x00\x00\x01\x00\x02\x002
345 345 s> \r\n
346 346 s> 0\r\n
347 347 s> \r\n
348 348
349 349 Authorized request for unknown command is rejected
350 350
351 351 $ sendhttpraw << EOF
352 352 > httprequest POST api/$HTTPV2/rw/badcommand
353 353 > user-agent: test
354 354 > accept: $MEDIATYPE
355 355 > EOF
356 356 using raw connection to peer
357 s> POST /api/exp-http-v2-0001/rw/badcommand HTTP/1.1\r\n
357 s> POST /api/exp-http-v2-0002/rw/badcommand HTTP/1.1\r\n
358 358 s> Accept-Encoding: identity\r\n
359 359 s> accept: application/mercurial-exp-framing-0005\r\n
360 360 s> user-agent: test\r\n
361 361 s> host: $LOCALIP:$HGPORT\r\n (glob)
362 362 s> \r\n
363 363 s> makefile('rb', None)
364 364 s> HTTP/1.1 404 Not Found\r\n
365 365 s> Server: testing stub value\r\n
366 366 s> Date: $HTTP_DATE$\r\n
367 367 s> Content-Type: text/plain\r\n
368 368 s> Content-Length: 42\r\n
369 369 s> \r\n
370 370 s> unknown wire protocol command: badcommand\n
371 371
372 372 debugreflect isn't enabled by default
373 373
374 374 $ sendhttpraw << EOF
375 375 > httprequest POST api/$HTTPV2/ro/debugreflect
376 376 > user-agent: test
377 377 > EOF
378 378 using raw connection to peer
379 s> POST /api/exp-http-v2-0001/ro/debugreflect HTTP/1.1\r\n
379 s> POST /api/exp-http-v2-0002/ro/debugreflect HTTP/1.1\r\n
380 380 s> Accept-Encoding: identity\r\n
381 381 s> user-agent: test\r\n
382 382 s> host: $LOCALIP:$HGPORT\r\n (glob)
383 383 s> \r\n
384 384 s> makefile('rb', None)
385 385 s> HTTP/1.1 404 Not Found\r\n
386 386 s> Server: testing stub value\r\n
387 387 s> Date: $HTTP_DATE$\r\n
388 388 s> Content-Type: text/plain\r\n
389 389 s> Content-Length: 34\r\n
390 390 s> \r\n
391 391 s> debugreflect service not available
392 392
393 393 Restart server to get debugreflect endpoint
394 394
395 395 $ killdaemons.py
396 396 $ cat > server/.hg/hgrc << EOF
397 397 > [experimental]
398 398 > web.apiserver = true
399 399 > web.api.debugreflect = true
400 400 > web.api.http-v2 = true
401 401 > [web]
402 402 > push_ssl = false
403 403 > allow-push = *
404 404 > EOF
405 405
406 406 $ hg -R server serve -p $HGPORT -d --pid-file hg.pid -E error.log
407 407 $ cat hg.pid > $DAEMON_PIDS
408 408
409 409 Command frames can be reflected via debugreflect
410 410
411 411 $ sendhttpraw << EOF
412 412 > httprequest POST api/$HTTPV2/ro/debugreflect
413 413 > accept: $MEDIATYPE
414 414 > content-type: $MEDIATYPE
415 415 > user-agent: test
416 416 > frame 1 1 stream-begin command-request new cbor:{b'name': b'command1', b'args': {b'foo': b'val1', b'bar1': b'val'}}
417 417 > EOF
418 418 using raw connection to peer
419 s> POST /api/exp-http-v2-0001/ro/debugreflect HTTP/1.1\r\n
419 s> POST /api/exp-http-v2-0002/ro/debugreflect HTTP/1.1\r\n
420 420 s> Accept-Encoding: identity\r\n
421 421 s> accept: application/mercurial-exp-framing-0005\r\n
422 422 s> content-type: application/mercurial-exp-framing-0005\r\n
423 423 s> user-agent: test\r\n
424 424 s> content-length: 47\r\n
425 425 s> host: $LOCALIP:$HGPORT\r\n (glob)
426 426 s> \r\n
427 427 s> \'\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa2Dbar1CvalCfooDval1DnameHcommand1
428 428 s> makefile('rb', None)
429 429 s> HTTP/1.1 200 OK\r\n
430 430 s> Server: testing stub value\r\n
431 431 s> Date: $HTTP_DATE$\r\n
432 432 s> Content-Type: text/plain\r\n
433 433 s> Content-Length: 205\r\n
434 434 s> \r\n
435 435 s> received: 1 1 1 \xa2Dargs\xa2Dbar1CvalCfooDval1DnameHcommand1\n
436 436 s> ["runcommand", {"args": {"bar1": "val", "foo": "val1"}, "command": "command1", "data": null, "requestid": 1}]\n
437 437 s> received: <no frame>\n
438 438 s> {"action": "noop"}
439 439
440 440 Multiple requests to regular command URL are not allowed
441 441
442 442 $ sendhttpraw << EOF
443 443 > httprequest POST api/$HTTPV2/ro/customreadonly
444 444 > accept: $MEDIATYPE
445 445 > content-type: $MEDIATYPE
446 446 > user-agent: test
447 447 > frame 1 1 stream-begin command-request new cbor:{b'name': b'customreadonly'}
448 448 > EOF
449 449 using raw connection to peer
450 s> POST /api/exp-http-v2-0001/ro/customreadonly HTTP/1.1\r\n
450 s> POST /api/exp-http-v2-0002/ro/customreadonly HTTP/1.1\r\n
451 451 s> Accept-Encoding: identity\r\n
452 452 s> accept: application/mercurial-exp-framing-0005\r\n
453 453 s> content-type: application/mercurial-exp-framing-0005\r\n
454 454 s> user-agent: test\r\n
455 455 s> content-length: 29\r\n
456 456 s> host: $LOCALIP:$HGPORT\r\n (glob)
457 457 s> \r\n
458 458 s> \x15\x00\x00\x01\x00\x01\x01\x11\xa1DnameNcustomreadonly
459 459 s> makefile('rb', None)
460 460 s> HTTP/1.1 200 OK\r\n
461 461 s> Server: testing stub value\r\n
462 462 s> Date: $HTTP_DATE$\r\n
463 463 s> Content-Type: application/mercurial-exp-framing-0005\r\n
464 464 s> Transfer-Encoding: chunked\r\n
465 465 s> \r\n
466 466 s> 13\r\n
467 467 s> \x0b\x00\x00\x01\x00\x02\x011\xa1FstatusBok
468 468 s> \r\n
469 469 s> 27\r\n
470 470 s> \x1f\x00\x00\x01\x00\x02\x001X\x1dcustomreadonly bytes response
471 471 s> \r\n
472 472 s> 8\r\n
473 473 s> \x00\x00\x00\x01\x00\x02\x002
474 474 s> \r\n
475 475 s> 0\r\n
476 476 s> \r\n
477 477
478 478 Multiple requests to "multirequest" URL are allowed
479 479
480 480 $ sendhttpraw << EOF
481 481 > httprequest POST api/$HTTPV2/ro/multirequest
482 482 > accept: $MEDIATYPE
483 483 > content-type: $MEDIATYPE
484 484 > user-agent: test
485 485 > frame 1 1 stream-begin command-request new cbor:{b'name': b'customreadonly'}
486 486 > frame 3 1 0 command-request new cbor:{b'name': b'customreadonly'}
487 487 > EOF
488 488 using raw connection to peer
489 s> POST /api/exp-http-v2-0001/ro/multirequest HTTP/1.1\r\n
489 s> POST /api/exp-http-v2-0002/ro/multirequest HTTP/1.1\r\n
490 490 s> Accept-Encoding: identity\r\n
491 491 s> *\r\n (glob)
492 492 s> *\r\n (glob)
493 493 s> user-agent: test\r\n
494 494 s> content-length: 58\r\n
495 495 s> host: $LOCALIP:$HGPORT\r\n (glob)
496 496 s> \r\n
497 497 s> \x15\x00\x00\x01\x00\x01\x01\x11\xa1DnameNcustomreadonly\x15\x00\x00\x03\x00\x01\x00\x11\xa1DnameNcustomreadonly
498 498 s> makefile('rb', None)
499 499 s> HTTP/1.1 200 OK\r\n
500 500 s> Server: testing stub value\r\n
501 501 s> Date: $HTTP_DATE$\r\n
502 502 s> Content-Type: application/mercurial-exp-framing-0005\r\n
503 503 s> Transfer-Encoding: chunked\r\n
504 504 s> \r\n
505 505 s> 13\r\n
506 506 s> \x0b\x00\x00\x01\x00\x02\x011\xa1FstatusBok
507 507 s> \r\n
508 508 s> 27\r\n
509 509 s> \x1f\x00\x00\x01\x00\x02\x001X\x1dcustomreadonly bytes response
510 510 s> \r\n
511 511 s> 8\r\n
512 512 s> \x00\x00\x00\x01\x00\x02\x002
513 513 s> \r\n
514 514 s> 13\r\n
515 515 s> \x0b\x00\x00\x03\x00\x02\x001\xa1FstatusBok
516 516 s> \r\n
517 517 s> 27\r\n
518 518 s> \x1f\x00\x00\x03\x00\x02\x001X\x1dcustomreadonly bytes response
519 519 s> \r\n
520 520 s> 8\r\n
521 521 s> \x00\x00\x00\x03\x00\x02\x002
522 522 s> \r\n
523 523 s> 0\r\n
524 524 s> \r\n
525 525
526 526 Interleaved requests to "multirequest" are processed
527 527
528 528 $ sendhttpraw << EOF
529 529 > httprequest POST api/$HTTPV2/ro/multirequest
530 530 > accept: $MEDIATYPE
531 531 > content-type: $MEDIATYPE
532 532 > user-agent: test
533 533 > frame 1 1 stream-begin command-request new|more \xa2Dargs\xa1Inamespace
534 534 > frame 3 1 0 command-request new|more \xa2Dargs\xa1Inamespace
535 535 > frame 3 1 0 command-request continuation JnamespacesDnameHlistkeys
536 536 > frame 1 1 0 command-request continuation IbookmarksDnameHlistkeys
537 537 > EOF
538 538 using raw connection to peer
539 s> POST /api/exp-http-v2-0001/ro/multirequest HTTP/1.1\r\n
539 s> POST /api/exp-http-v2-0002/ro/multirequest HTTP/1.1\r\n
540 540 s> Accept-Encoding: identity\r\n
541 541 s> accept: application/mercurial-exp-framing-0005\r\n
542 542 s> content-type: application/mercurial-exp-framing-0005\r\n
543 543 s> user-agent: test\r\n
544 544 s> content-length: 115\r\n
545 545 s> host: $LOCALIP:$HGPORT\r\n (glob)
546 546 s> \r\n
547 547 s> \x11\x00\x00\x01\x00\x01\x01\x15\xa2Dargs\xa1Inamespace\x11\x00\x00\x03\x00\x01\x00\x15\xa2Dargs\xa1Inamespace\x19\x00\x00\x03\x00\x01\x00\x12JnamespacesDnameHlistkeys\x18\x00\x00\x01\x00\x01\x00\x12IbookmarksDnameHlistkeys
548 548 s> makefile('rb', None)
549 549 s> HTTP/1.1 200 OK\r\n
550 550 s> Server: testing stub value\r\n
551 551 s> Date: $HTTP_DATE$\r\n
552 552 s> Content-Type: application/mercurial-exp-framing-0005\r\n
553 553 s> Transfer-Encoding: chunked\r\n
554 554 s> \r\n
555 555 s> 13\r\n
556 556 s> \x0b\x00\x00\x03\x00\x02\x011\xa1FstatusBok
557 557 s> \r\n
558 558 s> 28\r\n
559 559 s> \x00\x00\x03\x00\x02\x001\xa3Ibookmarks@Jnamespaces@Fphases@
560 560 s> \r\n
561 561 s> 8\r\n
562 562 s> \x00\x00\x00\x03\x00\x02\x002
563 563 s> \r\n
564 564 s> 13\r\n
565 565 s> \x0b\x00\x00\x01\x00\x02\x001\xa1FstatusBok
566 566 s> \r\n
567 567 s> 9\r\n
568 568 s> \x01\x00\x00\x01\x00\x02\x001\xa0
569 569 s> \r\n
570 570 s> 8\r\n
571 571 s> \x00\x00\x00\x01\x00\x02\x002
572 572 s> \r\n
573 573 s> 0\r\n
574 574 s> \r\n
575 575
576 576 Restart server to disable read-write access
577 577
578 578 $ killdaemons.py
579 579 $ cat > server/.hg/hgrc << EOF
580 580 > [experimental]
581 581 > web.apiserver = true
582 582 > web.api.debugreflect = true
583 583 > web.api.http-v2 = true
584 584 > [web]
585 585 > push_ssl = false
586 586 > EOF
587 587
588 588 $ hg -R server serve -p $HGPORT -d --pid-file hg.pid -E error.log
589 589 $ cat hg.pid > $DAEMON_PIDS
590 590
591 591 Attempting to run a read-write command via multirequest on read-only URL is not allowed
592 592
593 593 $ sendhttpraw << EOF
594 594 > httprequest POST api/$HTTPV2/ro/multirequest
595 595 > accept: $MEDIATYPE
596 596 > content-type: $MEDIATYPE
597 597 > user-agent: test
598 598 > frame 1 1 stream-begin command-request new cbor:{b'name': b'pushkey'}
599 599 > EOF
600 600 using raw connection to peer
601 s> POST /api/exp-http-v2-0001/ro/multirequest HTTP/1.1\r\n
601 s> POST /api/exp-http-v2-0002/ro/multirequest HTTP/1.1\r\n
602 602 s> Accept-Encoding: identity\r\n
603 603 s> accept: application/mercurial-exp-framing-0005\r\n
604 604 s> content-type: application/mercurial-exp-framing-0005\r\n
605 605 s> user-agent: test\r\n
606 606 s> content-length: 22\r\n
607 607 s> host: $LOCALIP:$HGPORT\r\n (glob)
608 608 s> \r\n
609 609 s> \x0e\x00\x00\x01\x00\x01\x01\x11\xa1DnameGpushkey
610 610 s> makefile('rb', None)
611 611 s> HTTP/1.1 403 Forbidden\r\n
612 612 s> Server: testing stub value\r\n
613 613 s> Date: $HTTP_DATE$\r\n
614 614 s> Content-Type: text/plain\r\n
615 615 s> Content-Length: 52\r\n
616 616 s> \r\n
617 617 s> insufficient permissions to execute command: pushkey
618 618
619 619 $ cat error.log
@@ -1,293 +1,293 b''
1 1 #require no-chg
2 2
3 3 $ send() {
4 4 > hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT/
5 5 > }
6 6
7 7 $ hg init server
8 8 $ hg -R server serve -p $HGPORT -d --pid-file hg.pid
9 9 $ cat hg.pid > $DAEMON_PIDS
10 10
11 11 Request to /api fails unless web.apiserver is enabled
12 12
13 13 $ get-with-headers.py $LOCALIP:$HGPORT api
14 14 400 no such method: api
15 15
16 16 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
17 17 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
18 18 <head>
19 19 <link rel="icon" href="/static/hgicon.png" type="image/png" />
20 20 <meta name="robots" content="index, nofollow" />
21 21 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
22 22 <script type="text/javascript" src="/static/mercurial.js"></script>
23 23
24 24 <title>$TESTTMP/server: error</title>
25 25 </head>
26 26 <body>
27 27
28 28 <div class="container">
29 29 <div class="menu">
30 30 <div class="logo">
31 31 <a href="https://mercurial-scm.org/">
32 32 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
33 33 </div>
34 34 <ul>
35 35 <li><a href="/shortlog">log</a></li>
36 36 <li><a href="/graph">graph</a></li>
37 37 <li><a href="/tags">tags</a></li>
38 38 <li><a href="/bookmarks">bookmarks</a></li>
39 39 <li><a href="/branches">branches</a></li>
40 40 </ul>
41 41 <ul>
42 42 <li><a href="/help">help</a></li>
43 43 </ul>
44 44 </div>
45 45
46 46 <div class="main">
47 47
48 48 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
49 49 <h3>error</h3>
50 50
51 51
52 52 <form class="search" action="/log">
53 53
54 54 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
55 55 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
56 56 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
57 57 </form>
58 58
59 59 <div class="description">
60 60 <p>
61 61 An error occurred while processing your request:
62 62 </p>
63 63 <p>
64 64 no such method: api
65 65 </p>
66 66 </div>
67 67 </div>
68 68 </div>
69 69
70 70
71 71
72 72 </body>
73 73 </html>
74 74
75 75 [1]
76 76
77 77 $ get-with-headers.py $LOCALIP:$HGPORT api/
78 78 400 no such method: api
79 79
80 80 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
81 81 <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">
82 82 <head>
83 83 <link rel="icon" href="/static/hgicon.png" type="image/png" />
84 84 <meta name="robots" content="index, nofollow" />
85 85 <link rel="stylesheet" href="/static/style-paper.css" type="text/css" />
86 86 <script type="text/javascript" src="/static/mercurial.js"></script>
87 87
88 88 <title>$TESTTMP/server: error</title>
89 89 </head>
90 90 <body>
91 91
92 92 <div class="container">
93 93 <div class="menu">
94 94 <div class="logo">
95 95 <a href="https://mercurial-scm.org/">
96 96 <img src="/static/hglogo.png" width=75 height=90 border=0 alt="mercurial" /></a>
97 97 </div>
98 98 <ul>
99 99 <li><a href="/shortlog">log</a></li>
100 100 <li><a href="/graph">graph</a></li>
101 101 <li><a href="/tags">tags</a></li>
102 102 <li><a href="/bookmarks">bookmarks</a></li>
103 103 <li><a href="/branches">branches</a></li>
104 104 </ul>
105 105 <ul>
106 106 <li><a href="/help">help</a></li>
107 107 </ul>
108 108 </div>
109 109
110 110 <div class="main">
111 111
112 112 <h2 class="breadcrumb"><a href="/">Mercurial</a> </h2>
113 113 <h3>error</h3>
114 114
115 115
116 116 <form class="search" action="/log">
117 117
118 118 <p><input name="rev" id="search1" type="text" size="30" value="" /></p>
119 119 <div id="hint">Find changesets by keywords (author, files, the commit message), revision
120 120 number or hash, or <a href="/help/revsets">revset expression</a>.</div>
121 121 </form>
122 122
123 123 <div class="description">
124 124 <p>
125 125 An error occurred while processing your request:
126 126 </p>
127 127 <p>
128 128 no such method: api
129 129 </p>
130 130 </div>
131 131 </div>
132 132 </div>
133 133
134 134
135 135
136 136 </body>
137 137 </html>
138 138
139 139 [1]
140 140
141 141 Restart server with support for API server
142 142
143 143 $ killdaemons.py
144 144 $ cat > server/.hg/hgrc << EOF
145 145 > [experimental]
146 146 > web.apiserver = true
147 147 > EOF
148 148
149 149 $ hg -R server serve -p $HGPORT -d --pid-file hg.pid
150 150 $ cat hg.pid > $DAEMON_PIDS
151 151
152 152 /api lists available APIs (empty since none are available by default)
153 153
154 154 $ send << EOF
155 155 > httprequest GET api
156 156 > user-agent: test
157 157 > EOF
158 158 using raw connection to peer
159 159 s> GET /api HTTP/1.1\r\n
160 160 s> Accept-Encoding: identity\r\n
161 161 s> user-agent: test\r\n
162 162 s> host: $LOCALIP:$HGPORT\r\n (glob)
163 163 s> \r\n
164 164 s> makefile('rb', None)
165 165 s> HTTP/1.1 200 OK\r\n
166 166 s> Server: testing stub value\r\n
167 167 s> Date: $HTTP_DATE$\r\n
168 168 s> Content-Type: text/plain\r\n
169 169 s> Content-Length: 100\r\n
170 170 s> \r\n
171 171 s> APIs can be accessed at /api/<name>, where <name> can be one of the following:\n
172 172 s> \n
173 173 s> (no available APIs)\n
174 174
175 175 $ send << EOF
176 176 > httprequest GET api/
177 177 > user-agent: test
178 178 > EOF
179 179 using raw connection to peer
180 180 s> GET /api/ HTTP/1.1\r\n
181 181 s> Accept-Encoding: identity\r\n
182 182 s> user-agent: test\r\n
183 183 s> host: $LOCALIP:$HGPORT\r\n (glob)
184 184 s> \r\n
185 185 s> makefile('rb', None)
186 186 s> HTTP/1.1 200 OK\r\n
187 187 s> Server: testing stub value\r\n
188 188 s> Date: $HTTP_DATE$\r\n
189 189 s> Content-Type: text/plain\r\n
190 190 s> Content-Length: 100\r\n
191 191 s> \r\n
192 192 s> APIs can be accessed at /api/<name>, where <name> can be one of the following:\n
193 193 s> \n
194 194 s> (no available APIs)\n
195 195
196 196 Accessing an unknown API yields a 404
197 197
198 198 $ send << EOF
199 199 > httprequest GET api/unknown
200 200 > user-agent: test
201 201 > EOF
202 202 using raw connection to peer
203 203 s> GET /api/unknown HTTP/1.1\r\n
204 204 s> Accept-Encoding: identity\r\n
205 205 s> user-agent: test\r\n
206 206 s> host: $LOCALIP:$HGPORT\r\n (glob)
207 207 s> \r\n
208 208 s> makefile('rb', None)
209 209 s> HTTP/1.1 404 Not Found\r\n
210 210 s> Server: testing stub value\r\n
211 211 s> Date: $HTTP_DATE$\r\n
212 212 s> Content-Type: text/plain\r\n
213 213 s> Content-Length: 33\r\n
214 214 s> \r\n
215 215 s> Unknown API: unknown\n
216 216 s> Known APIs:
217 217
218 218 Accessing a known but not enabled API yields a different error
219 219
220 220 $ send << EOF
221 > httprequest GET api/exp-http-v2-0001
221 > httprequest GET api/exp-http-v2-0002
222 222 > user-agent: test
223 223 > EOF
224 224 using raw connection to peer
225 s> GET /api/exp-http-v2-0001 HTTP/1.1\r\n
225 s> GET /api/exp-http-v2-0002 HTTP/1.1\r\n
226 226 s> Accept-Encoding: identity\r\n
227 227 s> user-agent: test\r\n
228 228 s> host: $LOCALIP:$HGPORT\r\n (glob)
229 229 s> \r\n
230 230 s> makefile('rb', None)
231 231 s> HTTP/1.1 404 Not Found\r\n
232 232 s> Server: testing stub value\r\n
233 233 s> Date: $HTTP_DATE$\r\n
234 234 s> Content-Type: text/plain\r\n
235 235 s> Content-Length: 33\r\n
236 236 s> \r\n
237 s> API exp-http-v2-0001 not enabled\n
237 s> API exp-http-v2-0002 not enabled\n
238 238
239 239 Restart server with support for HTTP v2 API
240 240
241 241 $ killdaemons.py
242 242 $ cat > server/.hg/hgrc << EOF
243 243 > [experimental]
244 244 > web.apiserver = true
245 245 > web.api.http-v2 = true
246 246 > EOF
247 247
248 248 $ hg -R server serve -p $HGPORT -d --pid-file hg.pid
249 249 $ cat hg.pid > $DAEMON_PIDS
250 250
251 251 /api lists the HTTP v2 protocol as available
252 252
253 253 $ send << EOF
254 254 > httprequest GET api
255 255 > user-agent: test
256 256 > EOF
257 257 using raw connection to peer
258 258 s> GET /api HTTP/1.1\r\n
259 259 s> Accept-Encoding: identity\r\n
260 260 s> user-agent: test\r\n
261 261 s> host: $LOCALIP:$HGPORT\r\n (glob)
262 262 s> \r\n
263 263 s> makefile('rb', None)
264 264 s> HTTP/1.1 200 OK\r\n
265 265 s> Server: testing stub value\r\n
266 266 s> Date: $HTTP_DATE$\r\n
267 267 s> Content-Type: text/plain\r\n
268 268 s> Content-Length: 96\r\n
269 269 s> \r\n
270 270 s> APIs can be accessed at /api/<name>, where <name> can be one of the following:\n
271 271 s> \n
272 s> exp-http-v2-0001
272 s> exp-http-v2-0002
273 273
274 274 $ send << EOF
275 275 > httprequest GET api/
276 276 > user-agent: test
277 277 > EOF
278 278 using raw connection to peer
279 279 s> GET /api/ HTTP/1.1\r\n
280 280 s> Accept-Encoding: identity\r\n
281 281 s> user-agent: test\r\n
282 282 s> host: $LOCALIP:$HGPORT\r\n (glob)
283 283 s> \r\n
284 284 s> makefile('rb', None)
285 285 s> HTTP/1.1 200 OK\r\n
286 286 s> Server: testing stub value\r\n
287 287 s> Date: $HTTP_DATE$\r\n
288 288 s> Content-Type: text/plain\r\n
289 289 s> Content-Length: 96\r\n
290 290 s> \r\n
291 291 s> APIs can be accessed at /api/<name>, where <name> can be one of the following:\n
292 292 s> \n
293 s> exp-http-v2-0001
293 s> exp-http-v2-0002
@@ -1,749 +1,749 b''
1 1 #require no-chg
2 2
3 3 $ . $TESTDIR/wireprotohelpers.sh
4 4
5 5 $ cat >> $HGRCPATH << EOF
6 6 > [web]
7 7 > push_ssl = false
8 8 > allow_push = *
9 9 > EOF
10 10
11 11 $ hg init server
12 12 $ cd server
13 13 $ touch a
14 14 $ hg -q commit -A -m initial
15 15 $ cd ..
16 16
17 17 $ hg serve -R server -p $HGPORT -d --pid-file hg.pid
18 18 $ cat hg.pid >> $DAEMON_PIDS
19 19
20 20 compression formats are advertised in compression capability
21 21
22 22 #if zstd
23 23 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities' | tr ' ' '\n' | grep '^compression=zstd,zlib$' > /dev/null
24 24 #else
25 25 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities' | tr ' ' '\n' | grep '^compression=zlib$' > /dev/null
26 26 #endif
27 27
28 28 $ killdaemons.py
29 29
30 30 server.compressionengines can replace engines list wholesale
31 31
32 32 $ hg serve --config server.compressionengines=none -R server -p $HGPORT -d --pid-file hg.pid
33 33 $ cat hg.pid > $DAEMON_PIDS
34 34 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities' | tr ' ' '\n' | grep '^compression=none$' > /dev/null
35 35
36 36 $ killdaemons.py
37 37
38 38 Order of engines can also change
39 39
40 40 $ hg serve --config server.compressionengines=none,zlib -R server -p $HGPORT -d --pid-file hg.pid
41 41 $ cat hg.pid > $DAEMON_PIDS
42 42 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=capabilities' | tr ' ' '\n' | grep '^compression=none,zlib$' > /dev/null
43 43
44 44 $ killdaemons.py
45 45
46 46 Start a default server again
47 47
48 48 $ hg serve -R server -p $HGPORT -d --pid-file hg.pid
49 49 $ cat hg.pid > $DAEMON_PIDS
50 50
51 51 Server should send application/mercurial-0.1 to clients if no Accept is used
52 52
53 53 $ get-with-headers.py --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
54 54 200 Script output follows
55 55 content-type: application/mercurial-0.1
56 56 date: $HTTP_DATE$
57 57 server: testing stub value
58 58 transfer-encoding: chunked
59 59
60 60 Server should send application/mercurial-0.1 when client says it wants it
61 61
62 62 $ get-with-headers.py --hgproto '0.1' --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
63 63 200 Script output follows
64 64 content-type: application/mercurial-0.1
65 65 date: $HTTP_DATE$
66 66 server: testing stub value
67 67 transfer-encoding: chunked
68 68
69 69 Server should send application/mercurial-0.2 when client says it wants it
70 70
71 71 $ get-with-headers.py --hgproto '0.2' --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
72 72 200 Script output follows
73 73 content-type: application/mercurial-0.2
74 74 date: $HTTP_DATE$
75 75 server: testing stub value
76 76 transfer-encoding: chunked
77 77
78 78 $ get-with-headers.py --hgproto '0.1 0.2' --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
79 79 200 Script output follows
80 80 content-type: application/mercurial-0.2
81 81 date: $HTTP_DATE$
82 82 server: testing stub value
83 83 transfer-encoding: chunked
84 84
85 85 Requesting a compression format that server doesn't support results will fall back to 0.1
86 86
87 87 $ get-with-headers.py --hgproto '0.2 comp=aa' --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' -
88 88 200 Script output follows
89 89 content-type: application/mercurial-0.1
90 90 date: $HTTP_DATE$
91 91 server: testing stub value
92 92 transfer-encoding: chunked
93 93
94 94 #if zstd
95 95 zstd is used if available
96 96
97 97 $ get-with-headers.py --hgproto '0.2 comp=zstd' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
98 98 $ f --size --hexdump --bytes 36 --sha1 resp
99 99 resp: size=248, sha1=4d8d8f87fb82bd542ce52881fdc94f850748
100 100 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
101 101 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 7a 73 74 64 |t follows...zstd|
102 102 0020: 28 b5 2f fd |(./.|
103 103
104 104 #endif
105 105
106 106 application/mercurial-0.2 is not yet used on non-streaming responses
107 107
108 108 $ get-with-headers.py --hgproto '0.2' $LOCALIP:$HGPORT '?cmd=heads' -
109 109 200 Script output follows
110 110 content-length: 41
111 111 content-type: application/mercurial-0.1
112 112 date: $HTTP_DATE$
113 113 server: testing stub value
114 114
115 115 e93700bd72895c5addab234c56d4024b487a362f
116 116
117 117 Now test protocol preference usage
118 118
119 119 $ killdaemons.py
120 120 $ hg serve --config server.compressionengines=none,zlib -R server -p $HGPORT -d --pid-file hg.pid
121 121 $ cat hg.pid > $DAEMON_PIDS
122 122
123 123 No Accept will send 0.1+zlib, even though "none" is preferred b/c "none" isn't supported on 0.1
124 124
125 125 $ get-with-headers.py --headeronly $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' Content-Type
126 126 200 Script output follows
127 127 content-type: application/mercurial-0.1
128 128
129 129 $ get-with-headers.py $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
130 130 $ f --size --hexdump --bytes 28 --sha1 resp
131 131 resp: size=227, sha1=35a4c074da74f32f5440da3cbf04
132 132 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
133 133 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 78 |t follows..x|
134 134
135 135 Explicit 0.1 will send zlib because "none" isn't supported on 0.1
136 136
137 137 $ get-with-headers.py --hgproto '0.1' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
138 138 $ f --size --hexdump --bytes 28 --sha1 resp
139 139 resp: size=227, sha1=35a4c074da74f32f5440da3cbf04
140 140 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
141 141 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 78 |t follows..x|
142 142
143 143 0.2 with no compression will get "none" because that is server's preference
144 144 (spec says ZL and UN are implicitly supported)
145 145
146 146 $ get-with-headers.py --hgproto '0.2' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
147 147 $ f --size --hexdump --bytes 32 --sha1 resp
148 148 resp: size=432, sha1=ac931b412ec185a02e0e5bcff98dac83
149 149 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
150 150 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 6e 6f 6e 65 |t follows...none|
151 151
152 152 Client receives server preference even if local order doesn't match
153 153
154 154 $ get-with-headers.py --hgproto '0.2 comp=zlib,none' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
155 155 $ f --size --hexdump --bytes 32 --sha1 resp
156 156 resp: size=432, sha1=ac931b412ec185a02e0e5bcff98dac83
157 157 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
158 158 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 6e 6f 6e 65 |t follows...none|
159 159
160 160 Client receives only supported format even if not server preferred format
161 161
162 162 $ get-with-headers.py --hgproto '0.2 comp=zlib' $LOCALIP:$HGPORT '?cmd=getbundle&heads=e93700bd72895c5addab234c56d4024b487a362f&common=0000000000000000000000000000000000000000' > resp
163 163 $ f --size --hexdump --bytes 33 --sha1 resp
164 164 resp: size=232, sha1=a1c727f0c9693ca15742a75c30419bc36
165 165 0000: 32 30 30 20 53 63 72 69 70 74 20 6f 75 74 70 75 |200 Script outpu|
166 166 0010: 74 20 66 6f 6c 6c 6f 77 73 0a 0a 04 7a 6c 69 62 |t follows...zlib|
167 167 0020: 78 |x|
168 168
169 169 $ killdaemons.py
170 170 $ cd ..
171 171
172 172 Test listkeys for listing namespaces
173 173
174 174 $ hg init empty
175 175 $ hg -R empty serve -p $HGPORT -d --pid-file hg.pid
176 176 $ cat hg.pid > $DAEMON_PIDS
177 177
178 178 $ hg --verbose debugwireproto http://$LOCALIP:$HGPORT << EOF
179 179 > command listkeys
180 180 > namespace namespaces
181 181 > EOF
182 182 s> GET /?cmd=capabilities HTTP/1.1\r\n
183 183 s> Accept-Encoding: identity\r\n
184 184 s> accept: application/mercurial-0.1\r\n
185 185 s> host: $LOCALIP:$HGPORT\r\n (glob)
186 186 s> user-agent: Mercurial debugwireproto\r\n
187 187 s> \r\n
188 188 s> makefile('rb', None)
189 189 s> HTTP/1.1 200 Script output follows\r\n
190 190 s> Server: testing stub value\r\n
191 191 s> Date: $HTTP_DATE$\r\n
192 192 s> Content-Type: application/mercurial-0.1\r\n
193 193 s> Content-Length: *\r\n (glob)
194 194 s> \r\n
195 195 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
196 196 sending listkeys command
197 197 s> GET /?cmd=listkeys HTTP/1.1\r\n
198 198 s> Accept-Encoding: identity\r\n
199 199 s> vary: X-HgArg-1,X-HgProto-1\r\n
200 200 s> x-hgarg-1: namespace=namespaces\r\n
201 201 s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
202 202 s> accept: application/mercurial-0.1\r\n
203 203 s> host: $LOCALIP:$HGPORT\r\n (glob)
204 204 s> user-agent: Mercurial debugwireproto\r\n
205 205 s> \r\n
206 206 s> makefile('rb', None)
207 207 s> HTTP/1.1 200 Script output follows\r\n
208 208 s> Server: testing stub value\r\n
209 209 s> Date: $HTTP_DATE$\r\n
210 210 s> Content-Type: application/mercurial-0.1\r\n
211 211 s> Content-Length: 30\r\n
212 212 s> \r\n
213 213 s> bookmarks\t\n
214 214 s> namespaces\t\n
215 215 s> phases\t
216 216 response: {
217 217 b'bookmarks': b'',
218 218 b'namespaces': b'',
219 219 b'phases': b''
220 220 }
221 221
222 222 Same thing, but with "httprequest" command
223 223
224 224 $ hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT << EOF
225 225 > httprequest GET ?cmd=listkeys
226 226 > user-agent: test
227 227 > x-hgarg-1: namespace=namespaces
228 228 > EOF
229 229 using raw connection to peer
230 230 s> GET /?cmd=listkeys HTTP/1.1\r\n
231 231 s> Accept-Encoding: identity\r\n
232 232 s> user-agent: test\r\n
233 233 s> x-hgarg-1: namespace=namespaces\r\n
234 234 s> host: $LOCALIP:$HGPORT\r\n (glob)
235 235 s> \r\n
236 236 s> makefile('rb', None)
237 237 s> HTTP/1.1 200 Script output follows\r\n
238 238 s> Server: testing stub value\r\n
239 239 s> Date: $HTTP_DATE$\r\n
240 240 s> Content-Type: application/mercurial-0.1\r\n
241 241 s> Content-Length: 30\r\n
242 242 s> \r\n
243 243 s> bookmarks\t\n
244 244 s> namespaces\t\n
245 245 s> phases\t
246 246
247 247 Client with HTTPv2 enabled advertises that and gets old capabilities response from old server
248 248
249 249 $ hg --config experimental.httppeer.advertise-v2=true --verbose debugwireproto http://$LOCALIP:$HGPORT << EOF
250 250 > command heads
251 251 > EOF
252 252 s> GET /?cmd=capabilities HTTP/1.1\r\n
253 253 s> Accept-Encoding: identity\r\n
254 254 s> vary: X-HgProto-1,X-HgUpgrade-1\r\n
255 255 s> x-hgproto-1: cbor\r\n
256 s> x-hgupgrade-1: exp-http-v2-0001\r\n
256 s> x-hgupgrade-1: exp-http-v2-0002\r\n
257 257 s> accept: application/mercurial-0.1\r\n
258 258 s> host: $LOCALIP:$HGPORT\r\n (glob)
259 259 s> user-agent: Mercurial debugwireproto\r\n
260 260 s> \r\n
261 261 s> makefile('rb', None)
262 262 s> HTTP/1.1 200 Script output follows\r\n
263 263 s> Server: testing stub value\r\n
264 264 s> Date: $HTTP_DATE$\r\n
265 265 s> Content-Type: application/mercurial-0.1\r\n
266 266 s> Content-Length: *\r\n (glob)
267 267 s> \r\n
268 268 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
269 269 sending heads command
270 270 s> GET /?cmd=heads HTTP/1.1\r\n
271 271 s> Accept-Encoding: identity\r\n
272 272 s> vary: X-HgProto-1\r\n
273 273 s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
274 274 s> accept: application/mercurial-0.1\r\n
275 275 s> host: $LOCALIP:$HGPORT\r\n (glob)
276 276 s> user-agent: Mercurial debugwireproto\r\n
277 277 s> \r\n
278 278 s> makefile('rb', None)
279 279 s> HTTP/1.1 200 Script output follows\r\n
280 280 s> Server: testing stub value\r\n
281 281 s> Date: $HTTP_DATE$\r\n
282 282 s> Content-Type: application/mercurial-0.1\r\n
283 283 s> Content-Length: 41\r\n
284 284 s> \r\n
285 285 s> 0000000000000000000000000000000000000000\n
286 286 response: [
287 287 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
288 288 ]
289 289
290 290 $ killdaemons.py
291 291 $ enablehttpv2 empty
292 292 $ hg --config server.compressionengines=zlib -R empty serve -p $HGPORT -d --pid-file hg.pid
293 293 $ cat hg.pid > $DAEMON_PIDS
294 294
295 295 Client with HTTPv2 enabled automatically upgrades if the server supports it
296 296
297 297 $ hg --config experimental.httppeer.advertise-v2=true --verbose debugwireproto http://$LOCALIP:$HGPORT << EOF
298 298 > command heads
299 299 > EOF
300 300 s> GET /?cmd=capabilities HTTP/1.1\r\n
301 301 s> Accept-Encoding: identity\r\n
302 302 s> vary: X-HgProto-1,X-HgUpgrade-1\r\n
303 303 s> x-hgproto-1: cbor\r\n
304 s> x-hgupgrade-1: exp-http-v2-0001\r\n
304 s> x-hgupgrade-1: exp-http-v2-0002\r\n
305 305 s> accept: application/mercurial-0.1\r\n
306 306 s> host: $LOCALIP:$HGPORT\r\n (glob)
307 307 s> user-agent: Mercurial debugwireproto\r\n
308 308 s> \r\n
309 309 s> makefile('rb', None)
310 310 s> HTTP/1.1 200 OK\r\n
311 311 s> Server: testing stub value\r\n
312 312 s> Date: $HTTP_DATE$\r\n
313 313 s> Content-Type: application/mercurial-cbor\r\n
314 314 s> Content-Length: *\r\n (glob)
315 315 s> \r\n
316 s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0001\xa5Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa3Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionInoderange\xa3Gdefault\xf6Hrequired\xf4DtypeDlistEnodes\xa3Gdefault\xf6Hrequired\xf4DtypeDlistKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullGpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushKcompression\x81\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x82LgeneraldeltaHrevlogv1Nv1capabilitiesY\x01\xd3batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
316 s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0002\xa5Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa3Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionInoderange\xa3Gdefault\xf6Hrequired\xf4DtypeDlistEnodes\xa3Gdefault\xf6Hrequired\xf4DtypeDlistKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullGpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushKcompression\x81\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x82LgeneraldeltaHrevlogv1Nv1capabilitiesY\x01\xd3batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
317 317 sending heads command
318 s> POST /api/exp-http-v2-0001/ro/heads HTTP/1.1\r\n
318 s> POST /api/exp-http-v2-0002/ro/heads HTTP/1.1\r\n
319 319 s> Accept-Encoding: identity\r\n
320 320 s> accept: application/mercurial-exp-framing-0005\r\n
321 321 s> content-type: application/mercurial-exp-framing-0005\r\n
322 322 s> content-length: 20\r\n
323 323 s> host: $LOCALIP:$HGPORT\r\n (glob)
324 324 s> user-agent: Mercurial debugwireproto\r\n
325 325 s> \r\n
326 326 s> \x0c\x00\x00\x01\x00\x01\x01\x11\xa1DnameEheads
327 327 s> makefile('rb', None)
328 328 s> HTTP/1.1 200 OK\r\n
329 329 s> Server: testing stub value\r\n
330 330 s> Date: $HTTP_DATE$\r\n
331 331 s> Content-Type: application/mercurial-exp-framing-0005\r\n
332 332 s> Transfer-Encoding: chunked\r\n
333 333 s> \r\n
334 334 s> 13\r\n
335 335 s> \x0b\x00\x00\x01\x00\x02\x011
336 336 s> \xa1FstatusBok
337 337 s> \r\n
338 338 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
339 339 s> 1e\r\n
340 340 s> \x16\x00\x00\x01\x00\x02\x001
341 341 s> \x81T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
342 342 s> \r\n
343 343 received frame(size=22; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
344 344 s> 8\r\n
345 345 s> \x00\x00\x00\x01\x00\x02\x002
346 346 s> \r\n
347 347 s> 0\r\n
348 348 s> \r\n
349 349 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
350 350 response: [
351 351 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
352 352 ]
353 353
354 354 $ killdaemons.py
355 355
356 356 HTTP client follows HTTP redirect on handshake to new repo
357 357
358 358 $ cd $TESTTMP
359 359
360 360 $ hg init redirector
361 361 $ hg init redirected
362 362 $ cd redirected
363 363 $ touch foo
364 364 $ hg -q commit -A -m initial
365 365 $ cd ..
366 366
367 367 $ cat > paths.conf << EOF
368 368 > [paths]
369 369 > / = $TESTTMP/*
370 370 > EOF
371 371
372 372 $ cat > redirectext.py << EOF
373 373 > from mercurial import extensions, wireprotoserver
374 374 > def wrappedcallhttp(orig, repo, req, res, proto, cmd):
375 375 > path = req.advertisedurl[len(req.advertisedbaseurl):]
376 376 > if not path.startswith(b'/redirector'):
377 377 > return orig(repo, req, res, proto, cmd)
378 378 > relpath = path[len(b'/redirector'):]
379 379 > res.status = b'301 Redirect'
380 380 > newurl = b'%s/redirected%s' % (req.baseurl, relpath)
381 381 > if not repo.ui.configbool('testing', 'redirectqs', True) and b'?' in newurl:
382 382 > newurl = newurl[0:newurl.index(b'?')]
383 383 > res.headers[b'Location'] = newurl
384 384 > res.headers[b'Content-Type'] = b'text/plain'
385 385 > res.setbodybytes(b'redirected')
386 386 > return True
387 387 >
388 388 > extensions.wrapfunction(wireprotoserver, '_callhttp', wrappedcallhttp)
389 389 > EOF
390 390
391 391 $ hg --config extensions.redirect=$TESTTMP/redirectext.py \
392 392 > --config server.compressionengines=zlib \
393 393 > serve --web-conf paths.conf --pid-file hg.pid -p $HGPORT -d
394 394 $ cat hg.pid > $DAEMON_PIDS
395 395
396 396 Verify our HTTP 301 is served properly
397 397
398 398 $ hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT << EOF
399 399 > httprequest GET /redirector?cmd=capabilities
400 400 > user-agent: test
401 401 > EOF
402 402 using raw connection to peer
403 403 s> GET /redirector?cmd=capabilities HTTP/1.1\r\n
404 404 s> Accept-Encoding: identity\r\n
405 405 s> user-agent: test\r\n
406 406 s> host: $LOCALIP:$HGPORT\r\n (glob)
407 407 s> \r\n
408 408 s> makefile('rb', None)
409 409 s> HTTP/1.1 301 Redirect\r\n
410 410 s> Server: testing stub value\r\n
411 411 s> Date: $HTTP_DATE$\r\n
412 412 s> Location: http://$LOCALIP:$HGPORT/redirected?cmd=capabilities\r\n (glob)
413 413 s> Content-Type: text/plain\r\n
414 414 s> Content-Length: 10\r\n
415 415 s> \r\n
416 416 s> redirected
417 417 s> GET /redirected?cmd=capabilities HTTP/1.1\r\n
418 418 s> Accept-Encoding: identity\r\n
419 419 s> user-agent: test\r\n
420 420 s> host: $LOCALIP:$HGPORT\r\n (glob)
421 421 s> \r\n
422 422 s> makefile('rb', None)
423 423 s> HTTP/1.1 200 Script output follows\r\n
424 424 s> Server: testing stub value\r\n
425 425 s> Date: $HTTP_DATE$\r\n
426 426 s> Content-Type: application/mercurial-0.1\r\n
427 427 s> Content-Length: 467\r\n
428 428 s> \r\n
429 429 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
430 430
431 431 Test with the HTTP peer
432 432
433 433 $ hg --verbose debugwireproto http://$LOCALIP:$HGPORT/redirector << EOF
434 434 > command heads
435 435 > EOF
436 436 s> GET /redirector?cmd=capabilities HTTP/1.1\r\n
437 437 s> Accept-Encoding: identity\r\n
438 438 s> accept: application/mercurial-0.1\r\n
439 439 s> host: $LOCALIP:$HGPORT\r\n (glob)
440 440 s> user-agent: Mercurial debugwireproto\r\n
441 441 s> \r\n
442 442 s> makefile('rb', None)
443 443 s> HTTP/1.1 301 Redirect\r\n
444 444 s> Server: testing stub value\r\n
445 445 s> Date: $HTTP_DATE$\r\n
446 446 s> Location: http://$LOCALIP:$HGPORT/redirected?cmd=capabilities\r\n (glob)
447 447 s> Content-Type: text/plain\r\n
448 448 s> Content-Length: 10\r\n
449 449 s> \r\n
450 450 s> redirected
451 451 s> GET /redirected?cmd=capabilities HTTP/1.1\r\n
452 452 s> Accept-Encoding: identity\r\n
453 453 s> accept: application/mercurial-0.1\r\n
454 454 s> host: $LOCALIP:$HGPORT\r\n (glob)
455 455 s> user-agent: Mercurial debugwireproto\r\n
456 456 s> \r\n
457 457 s> makefile('rb', None)
458 458 s> HTTP/1.1 200 Script output follows\r\n
459 459 s> Server: testing stub value\r\n
460 460 s> Date: $HTTP_DATE$\r\n
461 461 s> Content-Type: application/mercurial-0.1\r\n
462 462 s> Content-Length: 467\r\n
463 463 s> \r\n
464 464 real URL is http://$LOCALIP:$HGPORT/redirected (glob)
465 465 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
466 466 sending heads command
467 467 s> GET /redirected?cmd=heads HTTP/1.1\r\n
468 468 s> Accept-Encoding: identity\r\n
469 469 s> vary: X-HgProto-1\r\n
470 470 s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
471 471 s> accept: application/mercurial-0.1\r\n
472 472 s> host: $LOCALIP:$HGPORT\r\n (glob)
473 473 s> user-agent: Mercurial debugwireproto\r\n
474 474 s> \r\n
475 475 s> makefile('rb', None)
476 476 s> HTTP/1.1 200 Script output follows\r\n
477 477 s> Server: testing stub value\r\n
478 478 s> Date: $HTTP_DATE$\r\n
479 479 s> Content-Type: application/mercurial-0.1\r\n
480 480 s> Content-Length: 41\r\n
481 481 s> \r\n
482 482 s> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n
483 483 response: [
484 484 b'\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL'
485 485 ]
486 486
487 487 $ killdaemons.py
488 488
489 489 Now test a variation where we strip the query string from the redirect URL.
490 490 (SCM Manager apparently did this and clients would recover from it)
491 491
492 492 $ hg --config extensions.redirect=$TESTTMP/redirectext.py \
493 493 > --config server.compressionengines=zlib \
494 494 > --config testing.redirectqs=false \
495 495 > serve --web-conf paths.conf --pid-file hg.pid -p $HGPORT -d
496 496 $ cat hg.pid > $DAEMON_PIDS
497 497
498 498 $ hg --verbose debugwireproto --peer raw http://$LOCALIP:$HGPORT << EOF
499 499 > httprequest GET /redirector?cmd=capabilities
500 500 > user-agent: test
501 501 > EOF
502 502 using raw connection to peer
503 503 s> GET /redirector?cmd=capabilities HTTP/1.1\r\n
504 504 s> Accept-Encoding: identity\r\n
505 505 s> user-agent: test\r\n
506 506 s> host: $LOCALIP:$HGPORT\r\n (glob)
507 507 s> \r\n
508 508 s> makefile('rb', None)
509 509 s> HTTP/1.1 301 Redirect\r\n
510 510 s> Server: testing stub value\r\n
511 511 s> Date: $HTTP_DATE$\r\n
512 512 s> Location: http://$LOCALIP:$HGPORT/redirected\r\n (glob)
513 513 s> Content-Type: text/plain\r\n
514 514 s> Content-Length: 10\r\n
515 515 s> \r\n
516 516 s> redirected
517 517 s> GET /redirected HTTP/1.1\r\n
518 518 s> Accept-Encoding: identity\r\n
519 519 s> user-agent: test\r\n
520 520 s> host: $LOCALIP:$HGPORT\r\n (glob)
521 521 s> \r\n
522 522 s> makefile('rb', None)
523 523 s> HTTP/1.1 200 Script output follows\r\n
524 524 s> Server: testing stub value\r\n
525 525 s> Date: $HTTP_DATE$\r\n
526 526 s> ETag: W/"*"\r\n (glob)
527 527 s> Content-Type: text/html; charset=ascii\r\n
528 528 s> Transfer-Encoding: chunked\r\n
529 529 s> \r\n
530 530 s> 414\r\n
531 531 s> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\n
532 532 s> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">\n
533 533 s> <head>\n
534 534 s> <link rel="icon" href="/redirected/static/hgicon.png" type="image/png" />\n
535 535 s> <meta name="robots" content="index, nofollow" />\n
536 536 s> <link rel="stylesheet" href="/redirected/static/style-paper.css" type="text/css" />\n
537 537 s> <script type="text/javascript" src="/redirected/static/mercurial.js"></script>\n
538 538 s> \n
539 539 s> <title>redirected: log</title>\n
540 540 s> <link rel="alternate" type="application/atom+xml"\n
541 541 s> href="/redirected/atom-log" title="Atom feed for redirected" />\n
542 542 s> <link rel="alternate" type="application/rss+xml"\n
543 543 s> href="/redirected/rss-log" title="RSS feed for redirected" />\n
544 544 s> </head>\n
545 545 s> <body>\n
546 546 s> \n
547 547 s> <div class="container">\n
548 548 s> <div class="menu">\n
549 549 s> <div class="logo">\n
550 550 s> <a href="https://mercurial-scm.org/">\n
551 551 s> <img src="/redirected/static/hglogo.png" alt="mercurial" /></a>\n
552 552 s> </div>\n
553 553 s> <ul>\n
554 554 s> <li class="active">log</li>\n
555 555 s> <li><a href="/redirected/graph/tip">graph</a></li>\n
556 556 s> <li><a href="/redirected/tags">tags</a></li>\n
557 557 s> <li><a href="
558 558 s> \r\n
559 559 s> 810\r\n
560 560 s> /redirected/bookmarks">bookmarks</a></li>\n
561 561 s> <li><a href="/redirected/branches">branches</a></li>\n
562 562 s> </ul>\n
563 563 s> <ul>\n
564 564 s> <li><a href="/redirected/rev/tip">changeset</a></li>\n
565 565 s> <li><a href="/redirected/file/tip">browse</a></li>\n
566 566 s> </ul>\n
567 567 s> <ul>\n
568 568 s> \n
569 569 s> </ul>\n
570 570 s> <ul>\n
571 571 s> <li><a href="/redirected/help">help</a></li>\n
572 572 s> </ul>\n
573 573 s> <div class="atom-logo">\n
574 574 s> <a href="/redirected/atom-log" title="subscribe to atom feed">\n
575 575 s> <img class="atom-logo" src="/redirected/static/feed-icon-14x14.png" alt="atom feed" />\n
576 576 s> </a>\n
577 577 s> </div>\n
578 578 s> </div>\n
579 579 s> \n
580 580 s> <div class="main">\n
581 581 s> <h2 class="breadcrumb"><a href="/">Mercurial</a> &gt; <a href="/redirected">redirected</a> </h2>\n
582 582 s> <h3>log</h3>\n
583 583 s> \n
584 584 s> \n
585 585 s> <form class="search" action="/redirected/log">\n
586 586 s> \n
587 587 s> <p><input name="rev" id="search1" type="text" size="30" value="" /></p>\n
588 588 s> <div id="hint">Find changesets by keywords (author, files, the commit message), revision\n
589 589 s> number or hash, or <a href="/redirected/help/revsets">revset expression</a>.</div>\n
590 590 s> </form>\n
591 591 s> \n
592 592 s> <div class="navigate">\n
593 593 s> <a href="/redirected/shortlog/tip?revcount=30">less</a>\n
594 594 s> <a href="/redirected/shortlog/tip?revcount=120">more</a>\n
595 595 s> | rev 0: <a href="/redirected/shortlog/96ee1d7354c4">(0)</a> <a href="/redirected/shortlog/tip">tip</a> \n
596 596 s> </div>\n
597 597 s> \n
598 598 s> <table class="bigtable">\n
599 599 s> <thead>\n
600 600 s> <tr>\n
601 601 s> <th class="age">age</th>\n
602 602 s> <th class="author">author</th>\n
603 603 s> <th class="description">description</th>\n
604 604 s> </tr>\n
605 605 s> </thead>\n
606 606 s> <tbody class="stripes2">\n
607 607 s> <tr>\n
608 608 s> <td class="age">Thu, 01 Jan 1970 00:00:00 +0000</td>\n
609 609 s> <td class="author">test</td>\n
610 610 s> <td class="description">\n
611 611 s> <a href="/redirected/rev/96ee1d7354c4">initial</a>\n
612 612 s> <span class="phase">draft</span> <span class="branchhead">default</span> <span class="tag">tip</span> \n
613 613 s> </td>\n
614 614 s> </tr>\n
615 615 s> \n
616 616 s> </tbody>\n
617 617 s> </table>\n
618 618 s> \n
619 619 s> <div class="navigate">\n
620 620 s> <a href="/redirected/shortlog/tip?revcount=30">less</a>\n
621 621 s> <a href="/redirected/shortlog/tip?revcount=120">more</a>\n
622 622 s> | rev 0: <a href="/redirected/shortlog/96ee1d7354c4">(0)</a> <a href="/redirected/shortlog/tip">tip</a> \n
623 623 s> </div>\n
624 624 s> \n
625 625 s> <script type="text/javascript">\n
626 626 s> ajaxScrollInit(\n
627 627 s> \'/redirected/shortlog/%next%\',\n
628 628 s> \'\', <!-- NEXTHASH\n
629 629 s> function (htmlText) {
630 630 s> \r\n
631 631 s> 14a\r\n
632 632 s> \n
633 633 s> var m = htmlText.match(/\'(\\w+)\', <!-- NEXTHASH/);\n
634 634 s> return m ? m[1] : null;\n
635 635 s> },\n
636 636 s> \'.bigtable > tbody\',\n
637 637 s> \'<tr class="%class%">\\\n
638 638 s> <td colspan="3" style="text-align: center;">%text%</td>\\\n
639 639 s> </tr>\'\n
640 640 s> );\n
641 641 s> </script>\n
642 642 s> \n
643 643 s> </div>\n
644 644 s> </div>\n
645 645 s> \n
646 646 s> \n
647 647 s> \n
648 648 s> </body>\n
649 649 s> </html>\n
650 650 s> \n
651 651 s> \r\n
652 652 s> 0\r\n
653 653 s> \r\n
654 654
655 655 $ hg --verbose debugwireproto http://$LOCALIP:$HGPORT/redirector << EOF
656 656 > command heads
657 657 > EOF
658 658 s> GET /redirector?cmd=capabilities HTTP/1.1\r\n
659 659 s> Accept-Encoding: identity\r\n
660 660 s> accept: application/mercurial-0.1\r\n
661 661 s> host: $LOCALIP:$HGPORT\r\n (glob)
662 662 s> user-agent: Mercurial debugwireproto\r\n
663 663 s> \r\n
664 664 s> makefile('rb', None)
665 665 s> HTTP/1.1 301 Redirect\r\n
666 666 s> Server: testing stub value\r\n
667 667 s> Date: $HTTP_DATE$\r\n
668 668 s> Location: http://$LOCALIP:$HGPORT/redirected\r\n (glob)
669 669 s> Content-Type: text/plain\r\n
670 670 s> Content-Length: 10\r\n
671 671 s> \r\n
672 672 s> redirected
673 673 s> GET /redirected HTTP/1.1\r\n
674 674 s> Accept-Encoding: identity\r\n
675 675 s> accept: application/mercurial-0.1\r\n
676 676 s> host: $LOCALIP:$HGPORT\r\n (glob)
677 677 s> user-agent: Mercurial debugwireproto\r\n
678 678 s> \r\n
679 679 s> makefile('rb', None)
680 680 s> HTTP/1.1 200 Script output follows\r\n
681 681 s> Server: testing stub value\r\n
682 682 s> Date: $HTTP_DATE$\r\n
683 683 s> ETag: W/"*"\r\n (glob)
684 684 s> Content-Type: text/html; charset=ascii\r\n
685 685 s> Transfer-Encoding: chunked\r\n
686 686 s> \r\n
687 687 real URL is http://$LOCALIP:$HGPORT/redirected (glob)
688 688 s> 414\r\n
689 689 s> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">\n
690 690 s> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US">\n
691 691 s> <head>\n
692 692 s> <link rel="icon" href="/redirected/static/hgicon.png" type="image/png" />\n
693 693 s> <meta name="robots" content="index, nofollow" />\n
694 694 s> <link rel="stylesheet" href="/redirected/static/style-paper.css" type="text/css" />\n
695 695 s> <script type="text/javascript" src="/redirected/static/mercurial.js"></script>\n
696 696 s> \n
697 697 s> <title>redirected: log</title>\n
698 698 s> <link rel="alternate" type="application/atom+xml"\n
699 699 s> href="/redirected/atom-log" title="Atom feed for redirected" />\n
700 700 s> <link rel="alternate" type="application/rss+xml"\n
701 701 s> href="/redirected/rss-log" title="RSS feed for redirected" />\n
702 702 s> </head>\n
703 703 s> <body>\n
704 704 s> \n
705 705 s> <div class="container">\n
706 706 s> <div class="menu">\n
707 707 s> <div class="logo">\n
708 708 s> <a href="https://mercurial-scm.org/">\n
709 709 s> <img src="/redirected/static/hglogo.png" alt="mercurial" /></a>\n
710 710 s> </div>\n
711 711 s> <ul>\n
712 712 s> <li class="active">log</li>\n
713 713 s> <li><a href="/redirected/graph/tip">graph</a></li>\n
714 714 s> <li><a href="/redirected/tags">tags</a
715 715 s> GET /redirected?cmd=capabilities HTTP/1.1\r\n
716 716 s> Accept-Encoding: identity\r\n
717 717 s> accept: application/mercurial-0.1\r\n
718 718 s> host: $LOCALIP:$HGPORT\r\n (glob)
719 719 s> user-agent: Mercurial debugwireproto\r\n
720 720 s> \r\n
721 721 s> makefile('rb', None)
722 722 s> HTTP/1.1 200 Script output follows\r\n
723 723 s> Server: testing stub value\r\n
724 724 s> Date: $HTTP_DATE$\r\n
725 725 s> Content-Type: application/mercurial-0.1\r\n
726 726 s> Content-Length: 467\r\n
727 727 s> \r\n
728 728 real URL is http://$LOCALIP:$HGPORT/redirected (glob)
729 729 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
730 730 sending heads command
731 731 s> GET /redirected?cmd=heads HTTP/1.1\r\n
732 732 s> Accept-Encoding: identity\r\n
733 733 s> vary: X-HgProto-1\r\n
734 734 s> x-hgproto-1: 0.1 0.2 comp=$USUAL_COMPRESSIONS$ partial-pull\r\n
735 735 s> accept: application/mercurial-0.1\r\n
736 736 s> host: $LOCALIP:$HGPORT\r\n (glob)
737 737 s> user-agent: Mercurial debugwireproto\r\n
738 738 s> \r\n
739 739 s> makefile('rb', None)
740 740 s> HTTP/1.1 200 Script output follows\r\n
741 741 s> Server: testing stub value\r\n
742 742 s> Date: $HTTP_DATE$\r\n
743 743 s> Content-Type: application/mercurial-0.1\r\n
744 744 s> Content-Length: 41\r\n
745 745 s> \r\n
746 746 s> 96ee1d7354c4ad7372047672c36a1f561e3a6a4c\n
747 747 response: [
748 748 b'\x96\xee\x1dsT\xc4\xadsr\x04vr\xc3j\x1fV\x1e:jL'
749 749 ]
@@ -1,582 +1,582 b''
1 1 This test is a duplicate of 'test-http.t' feel free to factor out
2 2 parts that are not bundle1/bundle2 specific.
3 3
4 4 #testcases sshv1 sshv2
5 5
6 6 #if sshv2
7 7 $ cat >> $HGRCPATH << EOF
8 8 > [experimental]
9 9 > sshpeer.advertise-v2 = true
10 10 > sshserver.support-v2 = true
11 11 > EOF
12 12 #endif
13 13
14 14 $ cat << EOF >> $HGRCPATH
15 15 > [devel]
16 16 > # This test is dedicated to interaction through old bundle
17 17 > legacy.exchange = bundle1
18 18 > EOF
19 19
20 20
21 21 This test tries to exercise the ssh functionality with a dummy script
22 22
23 23 creating 'remote' repo
24 24
25 25 $ hg init remote
26 26 $ cd remote
27 27 $ echo this > foo
28 28 $ echo this > fooO
29 29 $ hg ci -A -m "init" foo fooO
30 30
31 31 insert a closed branch (issue4428)
32 32
33 33 $ hg up null
34 34 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
35 35 $ hg branch closed
36 36 marked working directory as branch closed
37 37 (branches are permanent and global, did you want a bookmark?)
38 38 $ hg ci -mc0
39 39 $ hg ci --close-branch -mc1
40 40 $ hg up -q default
41 41
42 42 configure for serving
43 43
44 44 $ cat <<EOF > .hg/hgrc
45 45 > [server]
46 46 > uncompressed = True
47 47 >
48 48 > [hooks]
49 49 > changegroup = sh -c "printenv.py changegroup-in-remote 0 ../dummylog"
50 50 > EOF
51 51 $ cd ..
52 52
53 53 repo not found error
54 54
55 55 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/nonexistent local
56 56 remote: abort: repository nonexistent not found!
57 57 abort: no suitable response from remote hg!
58 58 [255]
59 59
60 60 non-existent absolute path
61 61
62 62 #if no-msys
63 63 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy//`pwd`/nonexistent local
64 64 remote: abort: repository /$TESTTMP/nonexistent not found!
65 65 abort: no suitable response from remote hg!
66 66 [255]
67 67 #endif
68 68
69 69 clone remote via stream
70 70
71 71 #if no-reposimplestore
72 72
73 73 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" --stream ssh://user@dummy/remote local-stream
74 74 streaming all changes
75 75 4 files to transfer, 602 bytes of data
76 76 transferred 602 bytes in * seconds (*) (glob)
77 77 searching for changes
78 78 no changes found
79 79 updating to branch default
80 80 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
81 81 $ cd local-stream
82 82 $ hg verify
83 83 checking changesets
84 84 checking manifests
85 85 crosschecking files in changesets and manifests
86 86 checking files
87 87 checked 3 changesets with 2 changes to 2 files
88 88 $ hg branches
89 89 default 0:1160648e36ce
90 90 $ cd ..
91 91
92 92 clone bookmarks via stream
93 93
94 94 $ hg -R local-stream book mybook
95 95 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" --stream ssh://user@dummy/local-stream stream2
96 96 streaming all changes
97 97 4 files to transfer, 602 bytes of data
98 98 transferred 602 bytes in * seconds (*) (glob)
99 99 searching for changes
100 100 no changes found
101 101 updating to branch default
102 102 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
103 103 $ cd stream2
104 104 $ hg book
105 105 mybook 0:1160648e36ce
106 106 $ cd ..
107 107 $ rm -rf local-stream stream2
108 108
109 109 #endif
110 110
111 111 clone remote via pull
112 112
113 113 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local
114 114 requesting all changes
115 115 adding changesets
116 116 adding manifests
117 117 adding file changes
118 118 added 3 changesets with 2 changes to 2 files
119 119 new changesets 1160648e36ce:ad076bfb429d
120 120 updating to branch default
121 121 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
122 122
123 123 verify
124 124
125 125 $ cd local
126 126 $ hg verify
127 127 checking changesets
128 128 checking manifests
129 129 crosschecking files in changesets and manifests
130 130 checking files
131 131 checked 3 changesets with 2 changes to 2 files
132 132 $ cat >> .hg/hgrc <<EOF
133 133 > [hooks]
134 134 > changegroup = sh -c "printenv.py changegroup-in-local 0 ../dummylog"
135 135 > EOF
136 136
137 137 empty default pull
138 138
139 139 $ hg paths
140 140 default = ssh://user@dummy/remote
141 141 $ hg pull -e "\"$PYTHON\" \"$TESTDIR/dummyssh\""
142 142 pulling from ssh://user@dummy/remote
143 143 searching for changes
144 144 no changes found
145 145
146 146 pull from wrong ssh URL
147 147
148 148 $ hg pull -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/doesnotexist
149 149 pulling from ssh://user@dummy/doesnotexist
150 150 remote: abort: repository doesnotexist not found!
151 151 abort: no suitable response from remote hg!
152 152 [255]
153 153
154 154 local change
155 155
156 156 $ echo bleah > foo
157 157 $ hg ci -m "add"
158 158
159 159 updating rc
160 160
161 161 $ echo "default-push = ssh://user@dummy/remote" >> .hg/hgrc
162 162 $ echo "[ui]" >> .hg/hgrc
163 163 $ echo "ssh = \"$PYTHON\" \"$TESTDIR/dummyssh\"" >> .hg/hgrc
164 164
165 165 find outgoing
166 166
167 167 $ hg out ssh://user@dummy/remote
168 168 comparing with ssh://user@dummy/remote
169 169 searching for changes
170 170 changeset: 3:a28a9d1a809c
171 171 tag: tip
172 172 parent: 0:1160648e36ce
173 173 user: test
174 174 date: Thu Jan 01 00:00:00 1970 +0000
175 175 summary: add
176 176
177 177
178 178 find incoming on the remote side
179 179
180 180 $ hg incoming -R ../remote -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/local
181 181 comparing with ssh://user@dummy/local
182 182 searching for changes
183 183 changeset: 3:a28a9d1a809c
184 184 tag: tip
185 185 parent: 0:1160648e36ce
186 186 user: test
187 187 date: Thu Jan 01 00:00:00 1970 +0000
188 188 summary: add
189 189
190 190
191 191 find incoming on the remote side (using absolute path)
192 192
193 193 $ hg incoming -R ../remote -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" "ssh://user@dummy/`pwd`"
194 194 comparing with ssh://user@dummy/$TESTTMP/local
195 195 searching for changes
196 196 changeset: 3:a28a9d1a809c
197 197 tag: tip
198 198 parent: 0:1160648e36ce
199 199 user: test
200 200 date: Thu Jan 01 00:00:00 1970 +0000
201 201 summary: add
202 202
203 203
204 204 push
205 205
206 206 $ hg push
207 207 pushing to ssh://user@dummy/remote
208 208 searching for changes
209 209 remote: adding changesets
210 210 remote: adding manifests
211 211 remote: adding file changes
212 212 remote: added 1 changesets with 1 changes to 1 files
213 213 $ cd ../remote
214 214
215 215 check remote tip
216 216
217 217 $ hg tip
218 218 changeset: 3:a28a9d1a809c
219 219 tag: tip
220 220 parent: 0:1160648e36ce
221 221 user: test
222 222 date: Thu Jan 01 00:00:00 1970 +0000
223 223 summary: add
224 224
225 225 $ hg verify
226 226 checking changesets
227 227 checking manifests
228 228 crosschecking files in changesets and manifests
229 229 checking files
230 230 checked 4 changesets with 3 changes to 2 files
231 231 $ hg cat -r tip foo
232 232 bleah
233 233 $ echo z > z
234 234 $ hg ci -A -m z z
235 235 created new head
236 236
237 237 test pushkeys and bookmarks
238 238
239 239 $ cd ../local
240 240 $ hg debugpushkey --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote namespaces
241 241 bookmarks
242 242 namespaces
243 243 phases
244 244 $ hg book foo -r 0
245 245 $ hg out -B
246 246 comparing with ssh://user@dummy/remote
247 247 searching for changed bookmarks
248 248 foo 1160648e36ce
249 249 $ hg push -B foo
250 250 pushing to ssh://user@dummy/remote
251 251 searching for changes
252 252 no changes found
253 253 exporting bookmark foo
254 254 [1]
255 255 $ hg debugpushkey --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote bookmarks
256 256 foo 1160648e36cec0054048a7edc4110c6f84fde594
257 257 $ hg book -f foo
258 258 $ hg push --traceback
259 259 pushing to ssh://user@dummy/remote
260 260 searching for changes
261 261 no changes found
262 262 updating bookmark foo
263 263 [1]
264 264 $ hg book -d foo
265 265 $ hg in -B
266 266 comparing with ssh://user@dummy/remote
267 267 searching for changed bookmarks
268 268 foo a28a9d1a809c
269 269 $ hg book -f -r 0 foo
270 270 $ hg pull -B foo
271 271 pulling from ssh://user@dummy/remote
272 272 no changes found
273 273 updating bookmark foo
274 274 $ hg book -d foo
275 275 $ hg push -B foo
276 276 pushing to ssh://user@dummy/remote
277 277 searching for changes
278 278 no changes found
279 279 deleting remote bookmark foo
280 280 [1]
281 281
282 282 a bad, evil hook that prints to stdout
283 283
284 284 $ cat <<EOF > $TESTTMP/badhook
285 285 > import sys
286 286 > sys.stdout.write("KABOOM\n")
287 287 > EOF
288 288
289 289 $ echo '[hooks]' >> ../remote/.hg/hgrc
290 290 $ echo "changegroup.stdout = \"$PYTHON\" $TESTTMP/badhook" >> ../remote/.hg/hgrc
291 291 $ echo r > r
292 292 $ hg ci -A -m z r
293 293
294 294 push should succeed even though it has an unexpected response
295 295
296 296 $ hg push
297 297 pushing to ssh://user@dummy/remote
298 298 searching for changes
299 299 remote has heads on branch 'default' that are not known locally: 6c0482d977a3
300 300 remote: adding changesets
301 301 remote: adding manifests
302 302 remote: adding file changes
303 303 remote: added 1 changesets with 1 changes to 1 files
304 304 remote: KABOOM
305 305 $ hg -R ../remote heads
306 306 changeset: 5:1383141674ec
307 307 tag: tip
308 308 parent: 3:a28a9d1a809c
309 309 user: test
310 310 date: Thu Jan 01 00:00:00 1970 +0000
311 311 summary: z
312 312
313 313 changeset: 4:6c0482d977a3
314 314 parent: 0:1160648e36ce
315 315 user: test
316 316 date: Thu Jan 01 00:00:00 1970 +0000
317 317 summary: z
318 318
319 319
320 320 clone bookmarks
321 321
322 322 $ hg -R ../remote bookmark test
323 323 $ hg -R ../remote bookmarks
324 324 * test 4:6c0482d977a3
325 325 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local-bookmarks
326 326 requesting all changes
327 327 adding changesets
328 328 adding manifests
329 329 adding file changes
330 330 added 6 changesets with 5 changes to 4 files (+1 heads)
331 331 new changesets 1160648e36ce:1383141674ec
332 332 updating to branch default
333 333 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
334 334 $ hg -R local-bookmarks bookmarks
335 335 test 4:6c0482d977a3
336 336
337 337 passwords in ssh urls are not supported
338 338 (we use a glob here because different Python versions give different
339 339 results here)
340 340
341 341 $ hg push ssh://user:erroneouspwd@dummy/remote
342 342 pushing to ssh://user:*@dummy/remote (glob)
343 343 abort: password in URL not supported!
344 344 [255]
345 345
346 346 $ cd ..
347 347
348 348 hide outer repo
349 349 $ hg init
350 350
351 351 Test remote paths with spaces (issue2983):
352 352
353 353 $ hg init --ssh "\"$PYTHON\" \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
354 354 $ touch "$TESTTMP/a repo/test"
355 355 $ hg -R 'a repo' commit -A -m "test"
356 356 adding test
357 357 $ hg -R 'a repo' tag tag
358 358 $ hg id --ssh "\"$PYTHON\" \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
359 359 73649e48688a
360 360
361 361 $ hg id --ssh "\"$PYTHON\" \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo#noNoNO"
362 362 abort: unknown revision 'noNoNO'!
363 363 [255]
364 364
365 365 Test (non-)escaping of remote paths with spaces when cloning (issue3145):
366 366
367 367 $ hg clone --ssh "\"$PYTHON\" \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
368 368 destination directory: a repo
369 369 abort: destination 'a repo' is not empty
370 370 [255]
371 371
372 372 Test hg-ssh using a helper script that will restore PYTHONPATH (which might
373 373 have been cleared by a hg.exe wrapper) and invoke hg-ssh with the right
374 374 parameters:
375 375
376 376 $ cat > ssh.sh << EOF
377 377 > userhost="\$1"
378 378 > SSH_ORIGINAL_COMMAND="\$2"
379 379 > export SSH_ORIGINAL_COMMAND
380 380 > PYTHONPATH="$PYTHONPATH"
381 381 > export PYTHONPATH
382 382 > "$PYTHON" "$TESTDIR/../contrib/hg-ssh" "$TESTTMP/a repo"
383 383 > EOF
384 384
385 385 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a repo"
386 386 73649e48688a
387 387
388 388 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a'repo"
389 389 remote: Illegal repository "$TESTTMP/a'repo"
390 390 abort: no suitable response from remote hg!
391 391 [255]
392 392
393 393 $ hg id --ssh "sh ssh.sh" --remotecmd hacking "ssh://user@dummy/a'repo"
394 394 remote: Illegal command "hacking -R 'a'\''repo' serve --stdio"
395 395 abort: no suitable response from remote hg!
396 396 [255]
397 397
398 398 $ SSH_ORIGINAL_COMMAND="'hg' serve -R 'a'repo' --stdio" "$PYTHON" "$TESTDIR/../contrib/hg-ssh"
399 399 Illegal command "'hg' serve -R 'a'repo' --stdio": No closing quotation
400 400 [255]
401 401
402 402 Test hg-ssh in read-only mode:
403 403
404 404 $ cat > ssh.sh << EOF
405 405 > userhost="\$1"
406 406 > SSH_ORIGINAL_COMMAND="\$2"
407 407 > export SSH_ORIGINAL_COMMAND
408 408 > PYTHONPATH="$PYTHONPATH"
409 409 > export PYTHONPATH
410 410 > "$PYTHON" "$TESTDIR/../contrib/hg-ssh" --read-only "$TESTTMP/remote"
411 411 > EOF
412 412
413 413 $ hg clone --ssh "sh ssh.sh" "ssh://user@dummy/$TESTTMP/remote" read-only-local
414 414 requesting all changes
415 415 adding changesets
416 416 adding manifests
417 417 adding file changes
418 418 added 6 changesets with 5 changes to 4 files (+1 heads)
419 419 new changesets 1160648e36ce:1383141674ec
420 420 updating to branch default
421 421 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
422 422
423 423 $ cd read-only-local
424 424 $ echo "baz" > bar
425 425 $ hg ci -A -m "unpushable commit" bar
426 426 $ hg push --ssh "sh ../ssh.sh"
427 427 pushing to ssh://user@dummy/*/remote (glob)
428 428 searching for changes
429 429 remote: Permission denied
430 430 remote: abort: pretxnopen.hg-ssh hook failed
431 431 remote: Permission denied
432 432 remote: pushkey-abort: prepushkey.hg-ssh hook failed
433 433 updating 6c0482d977a3 to public failed!
434 434 [1]
435 435
436 436 $ cd ..
437 437
438 438 stderr from remote commands should be printed before stdout from local code (issue4336)
439 439
440 440 $ hg clone remote stderr-ordering
441 441 updating to branch default
442 442 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
443 443 $ cd stderr-ordering
444 444 $ cat >> localwrite.py << EOF
445 445 > from mercurial import exchange, extensions
446 446 >
447 447 > def wrappedpush(orig, repo, *args, **kwargs):
448 448 > res = orig(repo, *args, **kwargs)
449 449 > repo.ui.write(b'local stdout\n')
450 450 > return res
451 451 >
452 452 > def extsetup(ui):
453 453 > extensions.wrapfunction(exchange, b'push', wrappedpush)
454 454 > EOF
455 455
456 456 $ cat >> .hg/hgrc << EOF
457 457 > [paths]
458 458 > default-push = ssh://user@dummy/remote
459 459 > [ui]
460 460 > ssh = "$PYTHON" "$TESTDIR/dummyssh"
461 461 > [extensions]
462 462 > localwrite = localwrite.py
463 463 > EOF
464 464
465 465 $ echo localwrite > foo
466 466 $ hg commit -m 'testing localwrite'
467 467 $ hg push
468 468 pushing to ssh://user@dummy/remote
469 469 searching for changes
470 470 remote: adding changesets
471 471 remote: adding manifests
472 472 remote: adding file changes
473 473 remote: added 1 changesets with 1 changes to 1 files
474 474 remote: KABOOM
475 475 local stdout
476 476
477 477 debug output
478 478
479 479 $ hg pull --debug ssh://user@dummy/remote
480 480 pulling from ssh://user@dummy/remote
481 481 running .* ".*/dummyssh" ['"]user@dummy['"] ('|")hg -R remote serve --stdio('|") (re)
482 sending upgrade request: * proto=exp-ssh-v2-0001 (glob) (sshv2 !)
482 sending upgrade request: * proto=exp-ssh-v2-0002 (glob) (sshv2 !)
483 483 sending hello command
484 484 sending between command
485 485 remote: 427 (sshv1 !)
486 protocol upgraded to exp-ssh-v2-0001 (sshv2 !)
486 protocol upgraded to exp-ssh-v2-0002 (sshv2 !)
487 487 remote: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
488 488 remote: 1 (sshv1 !)
489 489 sending protocaps command
490 490 preparing listkeys for "bookmarks"
491 491 sending listkeys command
492 492 received listkey for "bookmarks": 45 bytes
493 493 query 1; heads
494 494 sending batch command
495 495 searching for changes
496 496 all remote heads known locally
497 497 no changes found
498 498 preparing listkeys for "phases"
499 499 sending listkeys command
500 500 received listkey for "phases": 15 bytes
501 501 checking for updated bookmarks
502 502
503 503 $ cd ..
504 504
505 505 $ cat dummylog
506 506 Got arguments 1:user@dummy 2:hg -R nonexistent serve --stdio
507 507 Got arguments 1:user@dummy 2:hg -R /$TESTTMP/nonexistent serve --stdio (no-msys !)
508 508 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
509 509 Got arguments 1:user@dummy 2:hg -R local-stream serve --stdio (no-reposimplestore !)
510 510 Got arguments 1:user@dummy 2:hg -R remote serve --stdio (no-reposimplestore !)
511 511 Got arguments 1:user@dummy 2:hg -R remote serve --stdio (no-reposimplestore !)
512 512 Got arguments 1:user@dummy 2:hg -R doesnotexist serve --stdio
513 513 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
514 514 Got arguments 1:user@dummy 2:hg -R local serve --stdio
515 515 Got arguments 1:user@dummy 2:hg -R $TESTTMP/local serve --stdio
516 516 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
517 517 changegroup-in-remote hook: HG_HOOKNAME=changegroup HG_HOOKTYPE=changegroup HG_NODE=a28a9d1a809cab7d4e2fde4bee738a9ede948b60 HG_NODE_LAST=a28a9d1a809cab7d4e2fde4bee738a9ede948b60 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:ssh:$LOCALIP
518 518 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
519 519 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
520 520 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
521 521 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
522 522 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
523 523 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
524 524 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
525 525 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
526 526 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
527 527 changegroup-in-remote hook: HG_HOOKNAME=changegroup HG_HOOKTYPE=changegroup HG_NODE=1383141674ec756a6056f6a9097618482fe0f4a6 HG_NODE_LAST=1383141674ec756a6056f6a9097618482fe0f4a6 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:ssh:$LOCALIP
528 528 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
529 529 Got arguments 1:user@dummy 2:hg init 'a repo'
530 530 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
531 531 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
532 532 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
533 533 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
534 534 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
535 535 changegroup-in-remote hook: HG_HOOKNAME=changegroup HG_HOOKTYPE=changegroup HG_NODE=65c38f4125f9602c8db4af56530cc221d93b8ef8 HG_NODE_LAST=65c38f4125f9602c8db4af56530cc221d93b8ef8 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:ssh:$LOCALIP
536 536 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
537 537
538 538 remote hook failure is attributed to remote
539 539
540 540 $ cat > $TESTTMP/failhook << EOF
541 541 > def hook(ui, repo, **kwargs):
542 542 > ui.write(b'hook failure!\n')
543 543 > ui.flush()
544 544 > return 1
545 545 > EOF
546 546
547 547 $ echo "pretxnchangegroup.fail = python:$TESTTMP/failhook:hook" >> remote/.hg/hgrc
548 548
549 549 $ hg -q --config ui.ssh="\"$PYTHON\" $TESTDIR/dummyssh" clone ssh://user@dummy/remote hookout
550 550 $ cd hookout
551 551 $ touch hookfailure
552 552 $ hg -q commit -A -m 'remote hook failure'
553 553 $ hg --config ui.ssh="\"$PYTHON\" $TESTDIR/dummyssh" push
554 554 pushing to ssh://user@dummy/remote
555 555 searching for changes
556 556 remote: adding changesets
557 557 remote: adding manifests
558 558 remote: adding file changes
559 559 remote: added 1 changesets with 1 changes to 1 files
560 560 remote: hook failure!
561 561 remote: transaction abort!
562 562 remote: rollback completed
563 563 remote: abort: pretxnchangegroup.fail hook failed
564 564 [1]
565 565
566 566 abort during pull is properly reported as such
567 567
568 568 $ echo morefoo >> ../remote/foo
569 569 $ hg -R ../remote commit --message "more foo to be pulled"
570 570 $ cat >> ../remote/.hg/hgrc << EOF
571 571 > [extensions]
572 572 > crash = ${TESTDIR}/crashgetbundler.py
573 573 > EOF
574 574 $ hg --config ui.ssh="\"$PYTHON\" $TESTDIR/dummyssh" pull
575 575 pulling from ssh://user@dummy/remote
576 576 searching for changes
577 577 adding changesets
578 578 remote: abort: this is an exercise
579 579 transaction abort!
580 580 rollback completed
581 581 abort: stream ended unexpectedly (got 0 bytes, expected 4)
582 582 [255]
@@ -1,2046 +1,2046 b''
1 1 $ cat > hgrc-sshv2 << EOF
2 2 > %include $HGRCPATH
3 3 > [experimental]
4 4 > sshpeer.advertise-v2 = true
5 5 > sshserver.support-v2 = true
6 6 > EOF
7 7
8 8 $ debugwireproto() {
9 9 > commands=`cat -`
10 10 > echo 'testing ssh1'
11 11 > tip=`hg log -r tip -T '{node}'`
12 12 > echo "${commands}" | hg --verbose debugwireproto --localssh --noreadstderr
13 13 > if [ -n "$1" ]; then
14 14 > hg --config extensions.strip= strip --no-backup -r "all() - ::${tip}"
15 15 > fi
16 16 > echo ""
17 17 > echo 'testing ssh2'
18 18 > echo "${commands}" | HGRCPATH=$TESTTMP/hgrc-sshv2 hg --verbose debugwireproto --localssh --noreadstderr
19 19 > if [ -n "$1" ]; then
20 20 > hg --config extensions.strip= strip --no-backup -r "all() - ::${tip}"
21 21 > fi
22 22 > }
23 23
24 24 Generate some bundle files
25 25
26 26 $ hg init repo
27 27 $ cd repo
28 28 $ echo 0 > foo
29 29 $ hg -q commit -A -m initial
30 30 $ hg bundle --all -t none-v1 ../initial.v1.hg
31 31 1 changesets found
32 32 $ cd ..
33 33
34 34 Test pushing bundle1 payload to a server with bundle1 disabled
35 35
36 36 $ hg init no-bundle1
37 37 $ cd no-bundle1
38 38 $ cat > .hg/hgrc << EOF
39 39 > [server]
40 40 > bundle1 = false
41 41 > EOF
42 42
43 43 $ debugwireproto << EOF
44 44 > command unbundle
45 45 > # This is "force" in hex.
46 46 > heads 666f726365
47 47 > PUSHFILE ../initial.v1.hg
48 48 > readavailable
49 49 > EOF
50 50 testing ssh1
51 51 creating ssh peer from handshake results
52 52 i> write(104) -> 104:
53 53 i> hello\n
54 54 i> between\n
55 55 i> pairs 81\n
56 56 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
57 57 i> flush() -> None
58 58 o> readline() -> 4:
59 59 o> 427\n
60 60 o> readline() -> 427:
61 61 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
62 62 o> readline() -> 2:
63 63 o> 1\n
64 64 o> readline() -> 1:
65 65 o> \n
66 66 sending unbundle command
67 67 i> write(9) -> 9:
68 68 i> unbundle\n
69 69 i> write(9) -> 9:
70 70 i> heads 10\n
71 71 i> write(10) -> 10: 666f726365
72 72 i> flush() -> None
73 73 o> readline() -> 2:
74 74 o> 0\n
75 75 i> write(4) -> 4:
76 76 i> 426\n
77 77 i> write(426) -> 426:
78 78 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
79 79 i> test\n
80 80 i> 0 0\n
81 81 i> foo\n
82 82 i> \n
83 83 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
84 84 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
85 85 i> \x00\x00\x00\x00\x00\x00\x00\x00
86 86 i> write(2) -> 2:
87 87 i> 0\n
88 88 i> flush() -> None
89 89 o> readline() -> 2:
90 90 o> 0\n
91 91 o> readline() -> 2:
92 92 o> 1\n
93 93 o> read(1) -> 1: 0
94 94 result: 0
95 95 remote output:
96 96 e> read(-1) -> 115:
97 97 e> abort: incompatible Mercurial client; bundle2 required\n
98 98 e> (see https://www.mercurial-scm.org/wiki/IncompatibleClient)\n
99 99
100 100 testing ssh2
101 101 creating ssh peer from handshake results
102 102 i> write(171) -> 171:
103 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
103 i> upgrade * proto=exp-ssh-v2-0002\n (glob)
104 104 i> hello\n
105 105 i> between\n
106 106 i> pairs 81\n
107 107 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
108 108 i> flush() -> None
109 109 o> readline() -> 62:
110 o> upgraded * exp-ssh-v2-0001\n (glob)
110 o> upgraded * exp-ssh-v2-0002\n (glob)
111 111 o> readline() -> 4:
112 112 o> 426\n
113 113 o> read(426) -> 426: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
114 114 o> read(1) -> 1:
115 115 o> \n
116 116 sending unbundle command
117 117 i> write(9) -> 9:
118 118 i> unbundle\n
119 119 i> write(9) -> 9:
120 120 i> heads 10\n
121 121 i> write(10) -> 10: 666f726365
122 122 i> flush() -> None
123 123 o> readline() -> 2:
124 124 o> 0\n
125 125 i> write(4) -> 4:
126 126 i> 426\n
127 127 i> write(426) -> 426:
128 128 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
129 129 i> test\n
130 130 i> 0 0\n
131 131 i> foo\n
132 132 i> \n
133 133 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
134 134 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
135 135 i> \x00\x00\x00\x00\x00\x00\x00\x00
136 136 i> write(2) -> 2:
137 137 i> 0\n
138 138 i> flush() -> None
139 139 o> readline() -> 2:
140 140 o> 0\n
141 141 o> readline() -> 2:
142 142 o> 1\n
143 143 o> read(1) -> 1: 0
144 144 result: 0
145 145 remote output:
146 146 e> read(-1) -> 115:
147 147 e> abort: incompatible Mercurial client; bundle2 required\n
148 148 e> (see https://www.mercurial-scm.org/wiki/IncompatibleClient)\n
149 149
150 150 $ cd ..
151 151
152 152 Create a pretxnchangegroup hook that fails. Give it multiple modes of printing
153 153 output so we can test I/O capture and behavior.
154 154
155 155 Test pushing to a server that has a pretxnchangegroup Python hook that fails
156 156
157 157 $ cat > $TESTTMP/failhook << EOF
158 158 > from __future__ import print_function
159 159 > import sys
160 160 > def hook1line(ui, repo, **kwargs):
161 161 > ui.write(b'ui.write 1 line\n')
162 162 > ui.flush()
163 163 > return 1
164 164 > def hook2lines(ui, repo, **kwargs):
165 165 > ui.write(b'ui.write 2 lines 1\n')
166 166 > ui.write(b'ui.write 2 lines 2\n')
167 167 > ui.flush()
168 168 > return 1
169 169 > def hook1lineflush(ui, repo, **kwargs):
170 170 > ui.write(b'ui.write 1 line flush\n')
171 171 > ui.flush()
172 172 > return 1
173 173 > def hookmultiflush(ui, repo, **kwargs):
174 174 > ui.write(b'ui.write 1st\n')
175 175 > ui.flush()
176 176 > ui.write(b'ui.write 2nd\n')
177 177 > ui.flush()
178 178 > return 1
179 179 > def hookwriteandwriteerr(ui, repo, **kwargs):
180 180 > ui.write(b'ui.write 1\n')
181 181 > ui.write_err(b'ui.write_err 1\n')
182 182 > ui.write(b'ui.write 2\n')
183 183 > ui.write_err(b'ui.write_err 2\n')
184 184 > ui.flush()
185 185 > return 1
186 186 > def hookprintstdout(ui, repo, **kwargs):
187 187 > print('printed line')
188 188 > sys.stdout.flush()
189 189 > return 1
190 190 > def hookprintandwrite(ui, repo, **kwargs):
191 191 > print('print 1')
192 192 > sys.stdout.flush()
193 193 > ui.write(b'ui.write 1\n')
194 194 > ui.flush()
195 195 > print('print 2')
196 196 > sys.stdout.flush()
197 197 > ui.write(b'ui.write 2\n')
198 198 > ui.flush()
199 199 > return 1
200 200 > def hookprintstderrandstdout(ui, repo, **kwargs):
201 201 > print('stdout 1')
202 202 > sys.stdout.flush()
203 203 > print('stderr 1', file=sys.stderr)
204 204 > sys.stderr.flush()
205 205 > print('stdout 2')
206 206 > sys.stdout.flush()
207 207 > print('stderr 2', file=sys.stderr)
208 208 > sys.stderr.flush()
209 209 > return 1
210 210 > EOF
211 211
212 212 $ hg init failrepo
213 213 $ cd failrepo
214 214
215 215 ui.write() in hook is redirected to stderr
216 216
217 217 $ cat > .hg/hgrc << EOF
218 218 > [hooks]
219 219 > pretxnchangegroup.fail = python:$TESTTMP/failhook:hook1line
220 220 > EOF
221 221
222 222 $ debugwireproto << EOF
223 223 > command unbundle
224 224 > # This is "force" in hex.
225 225 > heads 666f726365
226 226 > PUSHFILE ../initial.v1.hg
227 227 > readavailable
228 228 > EOF
229 229 testing ssh1
230 230 creating ssh peer from handshake results
231 231 i> write(104) -> 104:
232 232 i> hello\n
233 233 i> between\n
234 234 i> pairs 81\n
235 235 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
236 236 i> flush() -> None
237 237 o> readline() -> 4:
238 238 o> 427\n
239 239 o> readline() -> 427:
240 240 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
241 241 o> readline() -> 2:
242 242 o> 1\n
243 243 o> readline() -> 1:
244 244 o> \n
245 245 sending unbundle command
246 246 i> write(9) -> 9:
247 247 i> unbundle\n
248 248 i> write(9) -> 9:
249 249 i> heads 10\n
250 250 i> write(10) -> 10: 666f726365
251 251 i> flush() -> None
252 252 o> readline() -> 2:
253 253 o> 0\n
254 254 i> write(4) -> 4:
255 255 i> 426\n
256 256 i> write(426) -> 426:
257 257 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
258 258 i> test\n
259 259 i> 0 0\n
260 260 i> foo\n
261 261 i> \n
262 262 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
263 263 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
264 264 i> \x00\x00\x00\x00\x00\x00\x00\x00
265 265 i> write(2) -> 2:
266 266 i> 0\n
267 267 i> flush() -> None
268 268 o> readline() -> 2:
269 269 o> 0\n
270 270 o> readline() -> 2:
271 271 o> 1\n
272 272 o> read(1) -> 1: 0
273 273 result: 0
274 274 remote output:
275 275 e> read(-1) -> 196:
276 276 e> adding changesets\n
277 277 e> adding manifests\n
278 278 e> adding file changes\n
279 279 e> added 1 changesets with 1 changes to 1 files\n
280 280 e> ui.write 1 line\n
281 281 e> transaction abort!\n
282 282 e> rollback completed\n
283 283 e> abort: pretxnchangegroup.fail hook failed\n
284 284
285 285 testing ssh2
286 286 creating ssh peer from handshake results
287 287 i> write(171) -> 171:
288 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
288 i> upgrade * proto=exp-ssh-v2-0002\n (glob)
289 289 i> hello\n
290 290 i> between\n
291 291 i> pairs 81\n
292 292 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
293 293 i> flush() -> None
294 294 o> readline() -> 62:
295 o> upgraded * exp-ssh-v2-0001\n (glob)
295 o> upgraded * exp-ssh-v2-0002\n (glob)
296 296 o> readline() -> 4:
297 297 o> 426\n
298 298 o> read(426) -> 426: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
299 299 o> read(1) -> 1:
300 300 o> \n
301 301 sending unbundle command
302 302 i> write(9) -> 9:
303 303 i> unbundle\n
304 304 i> write(9) -> 9:
305 305 i> heads 10\n
306 306 i> write(10) -> 10: 666f726365
307 307 i> flush() -> None
308 308 o> readline() -> 2:
309 309 o> 0\n
310 310 i> write(4) -> 4:
311 311 i> 426\n
312 312 i> write(426) -> 426:
313 313 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
314 314 i> test\n
315 315 i> 0 0\n
316 316 i> foo\n
317 317 i> \n
318 318 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
319 319 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
320 320 i> \x00\x00\x00\x00\x00\x00\x00\x00
321 321 i> write(2) -> 2:
322 322 i> 0\n
323 323 i> flush() -> None
324 324 o> readline() -> 2:
325 325 o> 0\n
326 326 o> readline() -> 2:
327 327 o> 1\n
328 328 o> read(1) -> 1: 0
329 329 result: 0
330 330 remote output:
331 331 e> read(-1) -> 196:
332 332 e> adding changesets\n
333 333 e> adding manifests\n
334 334 e> adding file changes\n
335 335 e> added 1 changesets with 1 changes to 1 files\n
336 336 e> ui.write 1 line\n
337 337 e> transaction abort!\n
338 338 e> rollback completed\n
339 339 e> abort: pretxnchangegroup.fail hook failed\n
340 340
341 341 And a variation that writes multiple lines using ui.write
342 342
343 343 $ cat > .hg/hgrc << EOF
344 344 > [hooks]
345 345 > pretxnchangegroup.fail = python:$TESTTMP/failhook:hook2lines
346 346 > EOF
347 347
348 348 $ debugwireproto << EOF
349 349 > command unbundle
350 350 > # This is "force" in hex.
351 351 > heads 666f726365
352 352 > PUSHFILE ../initial.v1.hg
353 353 > readavailable
354 354 > EOF
355 355 testing ssh1
356 356 creating ssh peer from handshake results
357 357 i> write(104) -> 104:
358 358 i> hello\n
359 359 i> between\n
360 360 i> pairs 81\n
361 361 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
362 362 i> flush() -> None
363 363 o> readline() -> 4:
364 364 o> 427\n
365 365 o> readline() -> 427:
366 366 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
367 367 o> readline() -> 2:
368 368 o> 1\n
369 369 o> readline() -> 1:
370 370 o> \n
371 371 sending unbundle command
372 372 i> write(9) -> 9:
373 373 i> unbundle\n
374 374 i> write(9) -> 9:
375 375 i> heads 10\n
376 376 i> write(10) -> 10: 666f726365
377 377 i> flush() -> None
378 378 o> readline() -> 2:
379 379 o> 0\n
380 380 i> write(4) -> 4:
381 381 i> 426\n
382 382 i> write(426) -> 426:
383 383 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
384 384 i> test\n
385 385 i> 0 0\n
386 386 i> foo\n
387 387 i> \n
388 388 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
389 389 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
390 390 i> \x00\x00\x00\x00\x00\x00\x00\x00
391 391 i> write(2) -> 2:
392 392 i> 0\n
393 393 i> flush() -> None
394 394 o> readline() -> 2:
395 395 o> 0\n
396 396 o> readline() -> 2:
397 397 o> 1\n
398 398 o> read(1) -> 1: 0
399 399 result: 0
400 400 remote output:
401 401 e> read(-1) -> 218:
402 402 e> adding changesets\n
403 403 e> adding manifests\n
404 404 e> adding file changes\n
405 405 e> added 1 changesets with 1 changes to 1 files\n
406 406 e> ui.write 2 lines 1\n
407 407 e> ui.write 2 lines 2\n
408 408 e> transaction abort!\n
409 409 e> rollback completed\n
410 410 e> abort: pretxnchangegroup.fail hook failed\n
411 411
412 412 testing ssh2
413 413 creating ssh peer from handshake results
414 414 i> write(171) -> 171:
415 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
415 i> upgrade * proto=exp-ssh-v2-0002\n (glob)
416 416 i> hello\n
417 417 i> between\n
418 418 i> pairs 81\n
419 419 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
420 420 i> flush() -> None
421 421 o> readline() -> 62:
422 o> upgraded * exp-ssh-v2-0001\n (glob)
422 o> upgraded * exp-ssh-v2-0002\n (glob)
423 423 o> readline() -> 4:
424 424 o> 426\n
425 425 o> read(426) -> 426: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
426 426 o> read(1) -> 1:
427 427 o> \n
428 428 sending unbundle command
429 429 i> write(9) -> 9:
430 430 i> unbundle\n
431 431 i> write(9) -> 9:
432 432 i> heads 10\n
433 433 i> write(10) -> 10: 666f726365
434 434 i> flush() -> None
435 435 o> readline() -> 2:
436 436 o> 0\n
437 437 i> write(4) -> 4:
438 438 i> 426\n
439 439 i> write(426) -> 426:
440 440 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
441 441 i> test\n
442 442 i> 0 0\n
443 443 i> foo\n
444 444 i> \n
445 445 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
446 446 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
447 447 i> \x00\x00\x00\x00\x00\x00\x00\x00
448 448 i> write(2) -> 2:
449 449 i> 0\n
450 450 i> flush() -> None
451 451 o> readline() -> 2:
452 452 o> 0\n
453 453 o> readline() -> 2:
454 454 o> 1\n
455 455 o> read(1) -> 1: 0
456 456 result: 0
457 457 remote output:
458 458 e> read(-1) -> 218:
459 459 e> adding changesets\n
460 460 e> adding manifests\n
461 461 e> adding file changes\n
462 462 e> added 1 changesets with 1 changes to 1 files\n
463 463 e> ui.write 2 lines 1\n
464 464 e> ui.write 2 lines 2\n
465 465 e> transaction abort!\n
466 466 e> rollback completed\n
467 467 e> abort: pretxnchangegroup.fail hook failed\n
468 468
469 469 And a variation that does a ui.flush() after writing output
470 470
471 471 $ cat > .hg/hgrc << EOF
472 472 > [hooks]
473 473 > pretxnchangegroup.fail = python:$TESTTMP/failhook:hook1lineflush
474 474 > EOF
475 475
476 476 $ debugwireproto << EOF
477 477 > command unbundle
478 478 > # This is "force" in hex.
479 479 > heads 666f726365
480 480 > PUSHFILE ../initial.v1.hg
481 481 > readavailable
482 482 > EOF
483 483 testing ssh1
484 484 creating ssh peer from handshake results
485 485 i> write(104) -> 104:
486 486 i> hello\n
487 487 i> between\n
488 488 i> pairs 81\n
489 489 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
490 490 i> flush() -> None
491 491 o> readline() -> 4:
492 492 o> 427\n
493 493 o> readline() -> 427:
494 494 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
495 495 o> readline() -> 2:
496 496 o> 1\n
497 497 o> readline() -> 1:
498 498 o> \n
499 499 sending unbundle command
500 500 i> write(9) -> 9:
501 501 i> unbundle\n
502 502 i> write(9) -> 9:
503 503 i> heads 10\n
504 504 i> write(10) -> 10: 666f726365
505 505 i> flush() -> None
506 506 o> readline() -> 2:
507 507 o> 0\n
508 508 i> write(4) -> 4:
509 509 i> 426\n
510 510 i> write(426) -> 426:
511 511 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
512 512 i> test\n
513 513 i> 0 0\n
514 514 i> foo\n
515 515 i> \n
516 516 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
517 517 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
518 518 i> \x00\x00\x00\x00\x00\x00\x00\x00
519 519 i> write(2) -> 2:
520 520 i> 0\n
521 521 i> flush() -> None
522 522 o> readline() -> 2:
523 523 o> 0\n
524 524 o> readline() -> 2:
525 525 o> 1\n
526 526 o> read(1) -> 1: 0
527 527 result: 0
528 528 remote output:
529 529 e> read(-1) -> 202:
530 530 e> adding changesets\n
531 531 e> adding manifests\n
532 532 e> adding file changes\n
533 533 e> added 1 changesets with 1 changes to 1 files\n
534 534 e> ui.write 1 line flush\n
535 535 e> transaction abort!\n
536 536 e> rollback completed\n
537 537 e> abort: pretxnchangegroup.fail hook failed\n
538 538
539 539 testing ssh2
540 540 creating ssh peer from handshake results
541 541 i> write(171) -> 171:
542 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
542 i> upgrade * proto=exp-ssh-v2-0002\n (glob)
543 543 i> hello\n
544 544 i> between\n
545 545 i> pairs 81\n
546 546 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
547 547 i> flush() -> None
548 548 o> readline() -> 62:
549 o> upgraded * exp-ssh-v2-0001\n (glob)
549 o> upgraded * exp-ssh-v2-0002\n (glob)
550 550 o> readline() -> 4:
551 551 o> 426\n
552 552 o> read(426) -> 426: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
553 553 o> read(1) -> 1:
554 554 o> \n
555 555 sending unbundle command
556 556 i> write(9) -> 9:
557 557 i> unbundle\n
558 558 i> write(9) -> 9:
559 559 i> heads 10\n
560 560 i> write(10) -> 10: 666f726365
561 561 i> flush() -> None
562 562 o> readline() -> 2:
563 563 o> 0\n
564 564 i> write(4) -> 4:
565 565 i> 426\n
566 566 i> write(426) -> 426:
567 567 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
568 568 i> test\n
569 569 i> 0 0\n
570 570 i> foo\n
571 571 i> \n
572 572 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
573 573 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
574 574 i> \x00\x00\x00\x00\x00\x00\x00\x00
575 575 i> write(2) -> 2:
576 576 i> 0\n
577 577 i> flush() -> None
578 578 o> readline() -> 2:
579 579 o> 0\n
580 580 o> readline() -> 2:
581 581 o> 1\n
582 582 o> read(1) -> 1: 0
583 583 result: 0
584 584 remote output:
585 585 e> read(-1) -> 202:
586 586 e> adding changesets\n
587 587 e> adding manifests\n
588 588 e> adding file changes\n
589 589 e> added 1 changesets with 1 changes to 1 files\n
590 590 e> ui.write 1 line flush\n
591 591 e> transaction abort!\n
592 592 e> rollback completed\n
593 593 e> abort: pretxnchangegroup.fail hook failed\n
594 594
595 595 Multiple writes + flush
596 596
597 597 $ cat > .hg/hgrc << EOF
598 598 > [hooks]
599 599 > pretxnchangegroup.fail = python:$TESTTMP/failhook:hookmultiflush
600 600 > EOF
601 601
602 602 $ debugwireproto << EOF
603 603 > command unbundle
604 604 > # This is "force" in hex.
605 605 > heads 666f726365
606 606 > PUSHFILE ../initial.v1.hg
607 607 > readavailable
608 608 > EOF
609 609 testing ssh1
610 610 creating ssh peer from handshake results
611 611 i> write(104) -> 104:
612 612 i> hello\n
613 613 i> between\n
614 614 i> pairs 81\n
615 615 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
616 616 i> flush() -> None
617 617 o> readline() -> 4:
618 618 o> 427\n
619 619 o> readline() -> 427:
620 620 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
621 621 o> readline() -> 2:
622 622 o> 1\n
623 623 o> readline() -> 1:
624 624 o> \n
625 625 sending unbundle command
626 626 i> write(9) -> 9:
627 627 i> unbundle\n
628 628 i> write(9) -> 9:
629 629 i> heads 10\n
630 630 i> write(10) -> 10: 666f726365
631 631 i> flush() -> None
632 632 o> readline() -> 2:
633 633 o> 0\n
634 634 i> write(4) -> 4:
635 635 i> 426\n
636 636 i> write(426) -> 426:
637 637 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
638 638 i> test\n
639 639 i> 0 0\n
640 640 i> foo\n
641 641 i> \n
642 642 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
643 643 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
644 644 i> \x00\x00\x00\x00\x00\x00\x00\x00
645 645 i> write(2) -> 2:
646 646 i> 0\n
647 647 i> flush() -> None
648 648 o> readline() -> 2:
649 649 o> 0\n
650 650 o> readline() -> 2:
651 651 o> 1\n
652 652 o> read(1) -> 1: 0
653 653 result: 0
654 654 remote output:
655 655 e> read(-1) -> 206:
656 656 e> adding changesets\n
657 657 e> adding manifests\n
658 658 e> adding file changes\n
659 659 e> added 1 changesets with 1 changes to 1 files\n
660 660 e> ui.write 1st\n
661 661 e> ui.write 2nd\n
662 662 e> transaction abort!\n
663 663 e> rollback completed\n
664 664 e> abort: pretxnchangegroup.fail hook failed\n
665 665
666 666 testing ssh2
667 667 creating ssh peer from handshake results
668 668 i> write(171) -> 171:
669 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
669 i> upgrade * proto=exp-ssh-v2-0002\n (glob)
670 670 i> hello\n
671 671 i> between\n
672 672 i> pairs 81\n
673 673 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
674 674 i> flush() -> None
675 675 o> readline() -> 62:
676 o> upgraded * exp-ssh-v2-0001\n (glob)
676 o> upgraded * exp-ssh-v2-0002\n (glob)
677 677 o> readline() -> 4:
678 678 o> 426\n
679 679 o> read(426) -> 426: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
680 680 o> read(1) -> 1:
681 681 o> \n
682 682 sending unbundle command
683 683 i> write(9) -> 9:
684 684 i> unbundle\n
685 685 i> write(9) -> 9:
686 686 i> heads 10\n
687 687 i> write(10) -> 10: 666f726365
688 688 i> flush() -> None
689 689 o> readline() -> 2:
690 690 o> 0\n
691 691 i> write(4) -> 4:
692 692 i> 426\n
693 693 i> write(426) -> 426:
694 694 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
695 695 i> test\n
696 696 i> 0 0\n
697 697 i> foo\n
698 698 i> \n
699 699 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
700 700 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
701 701 i> \x00\x00\x00\x00\x00\x00\x00\x00
702 702 i> write(2) -> 2:
703 703 i> 0\n
704 704 i> flush() -> None
705 705 o> readline() -> 2:
706 706 o> 0\n
707 707 o> readline() -> 2:
708 708 o> 1\n
709 709 o> read(1) -> 1: 0
710 710 result: 0
711 711 remote output:
712 712 e> read(-1) -> 206:
713 713 e> adding changesets\n
714 714 e> adding manifests\n
715 715 e> adding file changes\n
716 716 e> added 1 changesets with 1 changes to 1 files\n
717 717 e> ui.write 1st\n
718 718 e> ui.write 2nd\n
719 719 e> transaction abort!\n
720 720 e> rollback completed\n
721 721 e> abort: pretxnchangegroup.fail hook failed\n
722 722
723 723 ui.write() + ui.write_err() output is captured
724 724
725 725 $ cat > .hg/hgrc << EOF
726 726 > [hooks]
727 727 > pretxnchangegroup.fail = python:$TESTTMP/failhook:hookwriteandwriteerr
728 728 > EOF
729 729
730 730 $ debugwireproto << EOF
731 731 > command unbundle
732 732 > # This is "force" in hex.
733 733 > heads 666f726365
734 734 > PUSHFILE ../initial.v1.hg
735 735 > readavailable
736 736 > EOF
737 737 testing ssh1
738 738 creating ssh peer from handshake results
739 739 i> write(104) -> 104:
740 740 i> hello\n
741 741 i> between\n
742 742 i> pairs 81\n
743 743 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
744 744 i> flush() -> None
745 745 o> readline() -> 4:
746 746 o> 427\n
747 747 o> readline() -> 427:
748 748 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
749 749 o> readline() -> 2:
750 750 o> 1\n
751 751 o> readline() -> 1:
752 752 o> \n
753 753 sending unbundle command
754 754 i> write(9) -> 9:
755 755 i> unbundle\n
756 756 i> write(9) -> 9:
757 757 i> heads 10\n
758 758 i> write(10) -> 10: 666f726365
759 759 i> flush() -> None
760 760 o> readline() -> 2:
761 761 o> 0\n
762 762 i> write(4) -> 4:
763 763 i> 426\n
764 764 i> write(426) -> 426:
765 765 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
766 766 i> test\n
767 767 i> 0 0\n
768 768 i> foo\n
769 769 i> \n
770 770 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
771 771 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
772 772 i> \x00\x00\x00\x00\x00\x00\x00\x00
773 773 i> write(2) -> 2:
774 774 i> 0\n
775 775 i> flush() -> None
776 776 o> readline() -> 2:
777 777 o> 0\n
778 778 o> readline() -> 2:
779 779 o> 1\n
780 780 o> read(1) -> 1: 0
781 781 result: 0
782 782 remote output:
783 783 e> read(-1) -> 232:
784 784 e> adding changesets\n
785 785 e> adding manifests\n
786 786 e> adding file changes\n
787 787 e> added 1 changesets with 1 changes to 1 files\n
788 788 e> ui.write 1\n
789 789 e> ui.write_err 1\n
790 790 e> ui.write 2\n
791 791 e> ui.write_err 2\n
792 792 e> transaction abort!\n
793 793 e> rollback completed\n
794 794 e> abort: pretxnchangegroup.fail hook failed\n
795 795
796 796 testing ssh2
797 797 creating ssh peer from handshake results
798 798 i> write(171) -> 171:
799 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
799 i> upgrade * proto=exp-ssh-v2-0002\n (glob)
800 800 i> hello\n
801 801 i> between\n
802 802 i> pairs 81\n
803 803 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
804 804 i> flush() -> None
805 805 o> readline() -> 62:
806 o> upgraded * exp-ssh-v2-0001\n (glob)
806 o> upgraded * exp-ssh-v2-0002\n (glob)
807 807 o> readline() -> 4:
808 808 o> 426\n
809 809 o> read(426) -> 426: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
810 810 o> read(1) -> 1:
811 811 o> \n
812 812 sending unbundle command
813 813 i> write(9) -> 9:
814 814 i> unbundle\n
815 815 i> write(9) -> 9:
816 816 i> heads 10\n
817 817 i> write(10) -> 10: 666f726365
818 818 i> flush() -> None
819 819 o> readline() -> 2:
820 820 o> 0\n
821 821 i> write(4) -> 4:
822 822 i> 426\n
823 823 i> write(426) -> 426:
824 824 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
825 825 i> test\n
826 826 i> 0 0\n
827 827 i> foo\n
828 828 i> \n
829 829 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
830 830 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
831 831 i> \x00\x00\x00\x00\x00\x00\x00\x00
832 832 i> write(2) -> 2:
833 833 i> 0\n
834 834 i> flush() -> None
835 835 o> readline() -> 2:
836 836 o> 0\n
837 837 o> readline() -> 2:
838 838 o> 1\n
839 839 o> read(1) -> 1: 0
840 840 result: 0
841 841 remote output:
842 842 e> read(-1) -> 232:
843 843 e> adding changesets\n
844 844 e> adding manifests\n
845 845 e> adding file changes\n
846 846 e> added 1 changesets with 1 changes to 1 files\n
847 847 e> ui.write 1\n
848 848 e> ui.write_err 1\n
849 849 e> ui.write 2\n
850 850 e> ui.write_err 2\n
851 851 e> transaction abort!\n
852 852 e> rollback completed\n
853 853 e> abort: pretxnchangegroup.fail hook failed\n
854 854
855 855 print() output is captured
856 856
857 857 $ cat > .hg/hgrc << EOF
858 858 > [hooks]
859 859 > pretxnchangegroup.fail = python:$TESTTMP/failhook:hookprintstdout
860 860 > EOF
861 861
862 862 $ debugwireproto << EOF
863 863 > command unbundle
864 864 > # This is "force" in hex.
865 865 > heads 666f726365
866 866 > PUSHFILE ../initial.v1.hg
867 867 > readavailable
868 868 > EOF
869 869 testing ssh1
870 870 creating ssh peer from handshake results
871 871 i> write(104) -> 104:
872 872 i> hello\n
873 873 i> between\n
874 874 i> pairs 81\n
875 875 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
876 876 i> flush() -> None
877 877 o> readline() -> 4:
878 878 o> 427\n
879 879 o> readline() -> 427:
880 880 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
881 881 o> readline() -> 2:
882 882 o> 1\n
883 883 o> readline() -> 1:
884 884 o> \n
885 885 sending unbundle command
886 886 i> write(9) -> 9:
887 887 i> unbundle\n
888 888 i> write(9) -> 9:
889 889 i> heads 10\n
890 890 i> write(10) -> 10: 666f726365
891 891 i> flush() -> None
892 892 o> readline() -> 2:
893 893 o> 0\n
894 894 i> write(4) -> 4:
895 895 i> 426\n
896 896 i> write(426) -> 426:
897 897 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
898 898 i> test\n
899 899 i> 0 0\n
900 900 i> foo\n
901 901 i> \n
902 902 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
903 903 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
904 904 i> \x00\x00\x00\x00\x00\x00\x00\x00
905 905 i> write(2) -> 2:
906 906 i> 0\n
907 907 i> flush() -> None
908 908 o> readline() -> 2:
909 909 o> 0\n
910 910 o> readline() -> 2:
911 911 o> 1\n
912 912 o> read(1) -> 1: 0
913 913 result: 0
914 914 remote output:
915 915 e> read(-1) -> 193:
916 916 e> adding changesets\n
917 917 e> adding manifests\n
918 918 e> adding file changes\n
919 919 e> added 1 changesets with 1 changes to 1 files\n
920 920 e> printed line\n
921 921 e> transaction abort!\n
922 922 e> rollback completed\n
923 923 e> abort: pretxnchangegroup.fail hook failed\n
924 924
925 925 testing ssh2
926 926 creating ssh peer from handshake results
927 927 i> write(171) -> 171:
928 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
928 i> upgrade * proto=exp-ssh-v2-0002\n (glob)
929 929 i> hello\n
930 930 i> between\n
931 931 i> pairs 81\n
932 932 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
933 933 i> flush() -> None
934 934 o> readline() -> 62:
935 o> upgraded * exp-ssh-v2-0001\n (glob)
935 o> upgraded * exp-ssh-v2-0002\n (glob)
936 936 o> readline() -> 4:
937 937 o> 426\n
938 938 o> read(426) -> 426: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
939 939 o> read(1) -> 1:
940 940 o> \n
941 941 sending unbundle command
942 942 i> write(9) -> 9:
943 943 i> unbundle\n
944 944 i> write(9) -> 9:
945 945 i> heads 10\n
946 946 i> write(10) -> 10: 666f726365
947 947 i> flush() -> None
948 948 o> readline() -> 2:
949 949 o> 0\n
950 950 i> write(4) -> 4:
951 951 i> 426\n
952 952 i> write(426) -> 426:
953 953 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
954 954 i> test\n
955 955 i> 0 0\n
956 956 i> foo\n
957 957 i> \n
958 958 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
959 959 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
960 960 i> \x00\x00\x00\x00\x00\x00\x00\x00
961 961 i> write(2) -> 2:
962 962 i> 0\n
963 963 i> flush() -> None
964 964 o> readline() -> 2:
965 965 o> 0\n
966 966 o> readline() -> 2:
967 967 o> 1\n
968 968 o> read(1) -> 1: 0
969 969 result: 0
970 970 remote output:
971 971 e> read(-1) -> 193:
972 972 e> adding changesets\n
973 973 e> adding manifests\n
974 974 e> adding file changes\n
975 975 e> added 1 changesets with 1 changes to 1 files\n
976 976 e> printed line\n
977 977 e> transaction abort!\n
978 978 e> rollback completed\n
979 979 e> abort: pretxnchangegroup.fail hook failed\n
980 980
981 981 Mixed print() and ui.write() are both captured
982 982
983 983 $ cat > .hg/hgrc << EOF
984 984 > [hooks]
985 985 > pretxnchangegroup.fail = python:$TESTTMP/failhook:hookprintandwrite
986 986 > EOF
987 987
988 988 $ debugwireproto << EOF
989 989 > command unbundle
990 990 > # This is "force" in hex.
991 991 > heads 666f726365
992 992 > PUSHFILE ../initial.v1.hg
993 993 > readavailable
994 994 > EOF
995 995 testing ssh1
996 996 creating ssh peer from handshake results
997 997 i> write(104) -> 104:
998 998 i> hello\n
999 999 i> between\n
1000 1000 i> pairs 81\n
1001 1001 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1002 1002 i> flush() -> None
1003 1003 o> readline() -> 4:
1004 1004 o> 427\n
1005 1005 o> readline() -> 427:
1006 1006 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
1007 1007 o> readline() -> 2:
1008 1008 o> 1\n
1009 1009 o> readline() -> 1:
1010 1010 o> \n
1011 1011 sending unbundle command
1012 1012 i> write(9) -> 9:
1013 1013 i> unbundle\n
1014 1014 i> write(9) -> 9:
1015 1015 i> heads 10\n
1016 1016 i> write(10) -> 10: 666f726365
1017 1017 i> flush() -> None
1018 1018 o> readline() -> 2:
1019 1019 o> 0\n
1020 1020 i> write(4) -> 4:
1021 1021 i> 426\n
1022 1022 i> write(426) -> 426:
1023 1023 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1024 1024 i> test\n
1025 1025 i> 0 0\n
1026 1026 i> foo\n
1027 1027 i> \n
1028 1028 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1029 1029 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1030 1030 i> \x00\x00\x00\x00\x00\x00\x00\x00
1031 1031 i> write(2) -> 2:
1032 1032 i> 0\n
1033 1033 i> flush() -> None
1034 1034 o> readline() -> 2:
1035 1035 o> 0\n
1036 1036 o> readline() -> 2:
1037 1037 o> 1\n
1038 1038 o> read(1) -> 1: 0
1039 1039 result: 0
1040 1040 remote output:
1041 1041 e> read(-1) -> 218:
1042 1042 e> adding changesets\n
1043 1043 e> adding manifests\n
1044 1044 e> adding file changes\n
1045 1045 e> added 1 changesets with 1 changes to 1 files\n
1046 1046 e> print 1\n
1047 1047 e> ui.write 1\n
1048 1048 e> print 2\n
1049 1049 e> ui.write 2\n
1050 1050 e> transaction abort!\n
1051 1051 e> rollback completed\n
1052 1052 e> abort: pretxnchangegroup.fail hook failed\n
1053 1053
1054 1054 testing ssh2
1055 1055 creating ssh peer from handshake results
1056 1056 i> write(171) -> 171:
1057 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1057 i> upgrade * proto=exp-ssh-v2-0002\n (glob)
1058 1058 i> hello\n
1059 1059 i> between\n
1060 1060 i> pairs 81\n
1061 1061 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1062 1062 i> flush() -> None
1063 1063 o> readline() -> 62:
1064 o> upgraded * exp-ssh-v2-0001\n (glob)
1064 o> upgraded * exp-ssh-v2-0002\n (glob)
1065 1065 o> readline() -> 4:
1066 1066 o> 426\n
1067 1067 o> read(426) -> 426: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
1068 1068 o> read(1) -> 1:
1069 1069 o> \n
1070 1070 sending unbundle command
1071 1071 i> write(9) -> 9:
1072 1072 i> unbundle\n
1073 1073 i> write(9) -> 9:
1074 1074 i> heads 10\n
1075 1075 i> write(10) -> 10: 666f726365
1076 1076 i> flush() -> None
1077 1077 o> readline() -> 2:
1078 1078 o> 0\n
1079 1079 i> write(4) -> 4:
1080 1080 i> 426\n
1081 1081 i> write(426) -> 426:
1082 1082 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1083 1083 i> test\n
1084 1084 i> 0 0\n
1085 1085 i> foo\n
1086 1086 i> \n
1087 1087 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1088 1088 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1089 1089 i> \x00\x00\x00\x00\x00\x00\x00\x00
1090 1090 i> write(2) -> 2:
1091 1091 i> 0\n
1092 1092 i> flush() -> None
1093 1093 o> readline() -> 2:
1094 1094 o> 0\n
1095 1095 o> readline() -> 2:
1096 1096 o> 1\n
1097 1097 o> read(1) -> 1: 0
1098 1098 result: 0
1099 1099 remote output:
1100 1100 e> read(-1) -> 218:
1101 1101 e> adding changesets\n
1102 1102 e> adding manifests\n
1103 1103 e> adding file changes\n
1104 1104 e> added 1 changesets with 1 changes to 1 files\n
1105 1105 e> print 1\n
1106 1106 e> ui.write 1\n
1107 1107 e> print 2\n
1108 1108 e> ui.write 2\n
1109 1109 e> transaction abort!\n
1110 1110 e> rollback completed\n
1111 1111 e> abort: pretxnchangegroup.fail hook failed\n
1112 1112
1113 1113 print() to stdout and stderr both get captured
1114 1114
1115 1115 $ cat > .hg/hgrc << EOF
1116 1116 > [hooks]
1117 1117 > pretxnchangegroup.fail = python:$TESTTMP/failhook:hookprintstderrandstdout
1118 1118 > EOF
1119 1119
1120 1120 $ debugwireproto << EOF
1121 1121 > command unbundle
1122 1122 > # This is "force" in hex.
1123 1123 > heads 666f726365
1124 1124 > PUSHFILE ../initial.v1.hg
1125 1125 > readavailable
1126 1126 > EOF
1127 1127 testing ssh1
1128 1128 creating ssh peer from handshake results
1129 1129 i> write(104) -> 104:
1130 1130 i> hello\n
1131 1131 i> between\n
1132 1132 i> pairs 81\n
1133 1133 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1134 1134 i> flush() -> None
1135 1135 o> readline() -> 4:
1136 1136 o> 427\n
1137 1137 o> readline() -> 427:
1138 1138 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
1139 1139 o> readline() -> 2:
1140 1140 o> 1\n
1141 1141 o> readline() -> 1:
1142 1142 o> \n
1143 1143 sending unbundle command
1144 1144 i> write(9) -> 9:
1145 1145 i> unbundle\n
1146 1146 i> write(9) -> 9:
1147 1147 i> heads 10\n
1148 1148 i> write(10) -> 10: 666f726365
1149 1149 i> flush() -> None
1150 1150 o> readline() -> 2:
1151 1151 o> 0\n
1152 1152 i> write(4) -> 4:
1153 1153 i> 426\n
1154 1154 i> write(426) -> 426:
1155 1155 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1156 1156 i> test\n
1157 1157 i> 0 0\n
1158 1158 i> foo\n
1159 1159 i> \n
1160 1160 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1161 1161 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1162 1162 i> \x00\x00\x00\x00\x00\x00\x00\x00
1163 1163 i> write(2) -> 2:
1164 1164 i> 0\n
1165 1165 i> flush() -> None
1166 1166 o> readline() -> 2:
1167 1167 o> 0\n
1168 1168 o> readline() -> 2:
1169 1169 o> 1\n
1170 1170 o> read(1) -> 1: 0
1171 1171 result: 0
1172 1172 remote output:
1173 1173 e> read(-1) -> 216:
1174 1174 e> adding changesets\n
1175 1175 e> adding manifests\n
1176 1176 e> adding file changes\n
1177 1177 e> added 1 changesets with 1 changes to 1 files\n
1178 1178 e> stdout 1\n
1179 1179 e> stderr 1\n
1180 1180 e> stdout 2\n
1181 1181 e> stderr 2\n
1182 1182 e> transaction abort!\n
1183 1183 e> rollback completed\n
1184 1184 e> abort: pretxnchangegroup.fail hook failed\n
1185 1185
1186 1186 testing ssh2
1187 1187 creating ssh peer from handshake results
1188 1188 i> write(171) -> 171:
1189 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1189 i> upgrade * proto=exp-ssh-v2-0002\n (glob)
1190 1190 i> hello\n
1191 1191 i> between\n
1192 1192 i> pairs 81\n
1193 1193 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1194 1194 i> flush() -> None
1195 1195 o> readline() -> 62:
1196 o> upgraded * exp-ssh-v2-0001\n (glob)
1196 o> upgraded * exp-ssh-v2-0002\n (glob)
1197 1197 o> readline() -> 4:
1198 1198 o> 426\n
1199 1199 o> read(426) -> 426: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
1200 1200 o> read(1) -> 1:
1201 1201 o> \n
1202 1202 sending unbundle command
1203 1203 i> write(9) -> 9:
1204 1204 i> unbundle\n
1205 1205 i> write(9) -> 9:
1206 1206 i> heads 10\n
1207 1207 i> write(10) -> 10: 666f726365
1208 1208 i> flush() -> None
1209 1209 o> readline() -> 2:
1210 1210 o> 0\n
1211 1211 i> write(4) -> 4:
1212 1212 i> 426\n
1213 1213 i> write(426) -> 426:
1214 1214 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1215 1215 i> test\n
1216 1216 i> 0 0\n
1217 1217 i> foo\n
1218 1218 i> \n
1219 1219 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1220 1220 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1221 1221 i> \x00\x00\x00\x00\x00\x00\x00\x00
1222 1222 i> write(2) -> 2:
1223 1223 i> 0\n
1224 1224 i> flush() -> None
1225 1225 o> readline() -> 2:
1226 1226 o> 0\n
1227 1227 o> readline() -> 2:
1228 1228 o> 1\n
1229 1229 o> read(1) -> 1: 0
1230 1230 result: 0
1231 1231 remote output:
1232 1232 e> read(-1) -> 216:
1233 1233 e> adding changesets\n
1234 1234 e> adding manifests\n
1235 1235 e> adding file changes\n
1236 1236 e> added 1 changesets with 1 changes to 1 files\n
1237 1237 e> stdout 1\n
1238 1238 e> stderr 1\n
1239 1239 e> stdout 2\n
1240 1240 e> stderr 2\n
1241 1241 e> transaction abort!\n
1242 1242 e> rollback completed\n
1243 1243 e> abort: pretxnchangegroup.fail hook failed\n
1244 1244
1245 1245 Shell hook writing to stdout has output captured
1246 1246
1247 1247 $ cat > $TESTTMP/hook.sh << EOF
1248 1248 > echo 'stdout 1'
1249 1249 > echo 'stdout 2'
1250 1250 > exit 1
1251 1251 > EOF
1252 1252
1253 1253 $ cat > .hg/hgrc << EOF
1254 1254 > [hooks]
1255 1255 > pretxnchangegroup.fail = sh $TESTTMP/hook.sh
1256 1256 > EOF
1257 1257
1258 1258 $ debugwireproto << EOF
1259 1259 > command unbundle
1260 1260 > # This is "force" in hex.
1261 1261 > heads 666f726365
1262 1262 > PUSHFILE ../initial.v1.hg
1263 1263 > readavailable
1264 1264 > EOF
1265 1265 testing ssh1
1266 1266 creating ssh peer from handshake results
1267 1267 i> write(104) -> 104:
1268 1268 i> hello\n
1269 1269 i> between\n
1270 1270 i> pairs 81\n
1271 1271 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1272 1272 i> flush() -> None
1273 1273 o> readline() -> 4:
1274 1274 o> 427\n
1275 1275 o> readline() -> 427:
1276 1276 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
1277 1277 o> readline() -> 2:
1278 1278 o> 1\n
1279 1279 o> readline() -> 1:
1280 1280 o> \n
1281 1281 sending unbundle command
1282 1282 i> write(9) -> 9:
1283 1283 i> unbundle\n
1284 1284 i> write(9) -> 9:
1285 1285 i> heads 10\n
1286 1286 i> write(10) -> 10: 666f726365
1287 1287 i> flush() -> None
1288 1288 o> readline() -> 2:
1289 1289 o> 0\n
1290 1290 i> write(4) -> 4:
1291 1291 i> 426\n
1292 1292 i> write(426) -> 426:
1293 1293 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1294 1294 i> test\n
1295 1295 i> 0 0\n
1296 1296 i> foo\n
1297 1297 i> \n
1298 1298 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1299 1299 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1300 1300 i> \x00\x00\x00\x00\x00\x00\x00\x00
1301 1301 i> write(2) -> 2:
1302 1302 i> 0\n
1303 1303 i> flush() -> None
1304 1304 o> readline() -> 2:
1305 1305 o> 0\n
1306 1306 o> readline() -> 2:
1307 1307 o> 1\n
1308 1308 o> read(1) -> 1: 0
1309 1309 result: 0
1310 1310 remote output:
1311 1311 e> read(-1) -> 212:
1312 1312 e> adding changesets\n
1313 1313 e> adding manifests\n
1314 1314 e> adding file changes\n
1315 1315 e> added 1 changesets with 1 changes to 1 files\n
1316 1316 e> stdout 1\n
1317 1317 e> stdout 2\n
1318 1318 e> transaction abort!\n
1319 1319 e> rollback completed\n
1320 1320 e> abort: pretxnchangegroup.fail hook exited with status 1\n
1321 1321
1322 1322 testing ssh2
1323 1323 creating ssh peer from handshake results
1324 1324 i> write(171) -> 171:
1325 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1325 i> upgrade * proto=exp-ssh-v2-0002\n (glob)
1326 1326 i> hello\n
1327 1327 i> between\n
1328 1328 i> pairs 81\n
1329 1329 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1330 1330 i> flush() -> None
1331 1331 o> readline() -> 62:
1332 o> upgraded * exp-ssh-v2-0001\n (glob)
1332 o> upgraded * exp-ssh-v2-0002\n (glob)
1333 1333 o> readline() -> 4:
1334 1334 o> 426\n
1335 1335 o> read(426) -> 426: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
1336 1336 o> read(1) -> 1:
1337 1337 o> \n
1338 1338 sending unbundle command
1339 1339 i> write(9) -> 9:
1340 1340 i> unbundle\n
1341 1341 i> write(9) -> 9:
1342 1342 i> heads 10\n
1343 1343 i> write(10) -> 10: 666f726365
1344 1344 i> flush() -> None
1345 1345 o> readline() -> 2:
1346 1346 o> 0\n
1347 1347 i> write(4) -> 4:
1348 1348 i> 426\n
1349 1349 i> write(426) -> 426:
1350 1350 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1351 1351 i> test\n
1352 1352 i> 0 0\n
1353 1353 i> foo\n
1354 1354 i> \n
1355 1355 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1356 1356 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1357 1357 i> \x00\x00\x00\x00\x00\x00\x00\x00
1358 1358 i> write(2) -> 2:
1359 1359 i> 0\n
1360 1360 i> flush() -> None
1361 1361 o> readline() -> 2:
1362 1362 o> 0\n
1363 1363 o> readline() -> 2:
1364 1364 o> 1\n
1365 1365 o> read(1) -> 1: 0
1366 1366 result: 0
1367 1367 remote output:
1368 1368 e> read(-1) -> 212:
1369 1369 e> adding changesets\n
1370 1370 e> adding manifests\n
1371 1371 e> adding file changes\n
1372 1372 e> added 1 changesets with 1 changes to 1 files\n
1373 1373 e> stdout 1\n
1374 1374 e> stdout 2\n
1375 1375 e> transaction abort!\n
1376 1376 e> rollback completed\n
1377 1377 e> abort: pretxnchangegroup.fail hook exited with status 1\n
1378 1378
1379 1379 Shell hook writing to stderr has output captured
1380 1380
1381 1381 $ cat > $TESTTMP/hook.sh << EOF
1382 1382 > echo 'stderr 1' 1>&2
1383 1383 > echo 'stderr 2' 1>&2
1384 1384 > exit 1
1385 1385 > EOF
1386 1386
1387 1387 $ debugwireproto << EOF
1388 1388 > command unbundle
1389 1389 > # This is "force" in hex.
1390 1390 > heads 666f726365
1391 1391 > PUSHFILE ../initial.v1.hg
1392 1392 > readavailable
1393 1393 > EOF
1394 1394 testing ssh1
1395 1395 creating ssh peer from handshake results
1396 1396 i> write(104) -> 104:
1397 1397 i> hello\n
1398 1398 i> between\n
1399 1399 i> pairs 81\n
1400 1400 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1401 1401 i> flush() -> None
1402 1402 o> readline() -> 4:
1403 1403 o> 427\n
1404 1404 o> readline() -> 427:
1405 1405 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
1406 1406 o> readline() -> 2:
1407 1407 o> 1\n
1408 1408 o> readline() -> 1:
1409 1409 o> \n
1410 1410 sending unbundle command
1411 1411 i> write(9) -> 9:
1412 1412 i> unbundle\n
1413 1413 i> write(9) -> 9:
1414 1414 i> heads 10\n
1415 1415 i> write(10) -> 10: 666f726365
1416 1416 i> flush() -> None
1417 1417 o> readline() -> 2:
1418 1418 o> 0\n
1419 1419 i> write(4) -> 4:
1420 1420 i> 426\n
1421 1421 i> write(426) -> 426:
1422 1422 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1423 1423 i> test\n
1424 1424 i> 0 0\n
1425 1425 i> foo\n
1426 1426 i> \n
1427 1427 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1428 1428 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1429 1429 i> \x00\x00\x00\x00\x00\x00\x00\x00
1430 1430 i> write(2) -> 2:
1431 1431 i> 0\n
1432 1432 i> flush() -> None
1433 1433 o> readline() -> 2:
1434 1434 o> 0\n
1435 1435 o> readline() -> 2:
1436 1436 o> 1\n
1437 1437 o> read(1) -> 1: 0
1438 1438 result: 0
1439 1439 remote output:
1440 1440 e> read(-1) -> 212:
1441 1441 e> adding changesets\n
1442 1442 e> adding manifests\n
1443 1443 e> adding file changes\n
1444 1444 e> added 1 changesets with 1 changes to 1 files\n
1445 1445 e> stderr 1\n
1446 1446 e> stderr 2\n
1447 1447 e> transaction abort!\n
1448 1448 e> rollback completed\n
1449 1449 e> abort: pretxnchangegroup.fail hook exited with status 1\n
1450 1450
1451 1451 testing ssh2
1452 1452 creating ssh peer from handshake results
1453 1453 i> write(171) -> 171:
1454 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1454 i> upgrade * proto=exp-ssh-v2-0002\n (glob)
1455 1455 i> hello\n
1456 1456 i> between\n
1457 1457 i> pairs 81\n
1458 1458 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1459 1459 i> flush() -> None
1460 1460 o> readline() -> 62:
1461 o> upgraded * exp-ssh-v2-0001\n (glob)
1461 o> upgraded * exp-ssh-v2-0002\n (glob)
1462 1462 o> readline() -> 4:
1463 1463 o> 426\n
1464 1464 o> read(426) -> 426: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
1465 1465 o> read(1) -> 1:
1466 1466 o> \n
1467 1467 sending unbundle command
1468 1468 i> write(9) -> 9:
1469 1469 i> unbundle\n
1470 1470 i> write(9) -> 9:
1471 1471 i> heads 10\n
1472 1472 i> write(10) -> 10: 666f726365
1473 1473 i> flush() -> None
1474 1474 o> readline() -> 2:
1475 1475 o> 0\n
1476 1476 i> write(4) -> 4:
1477 1477 i> 426\n
1478 1478 i> write(426) -> 426:
1479 1479 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1480 1480 i> test\n
1481 1481 i> 0 0\n
1482 1482 i> foo\n
1483 1483 i> \n
1484 1484 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1485 1485 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1486 1486 i> \x00\x00\x00\x00\x00\x00\x00\x00
1487 1487 i> write(2) -> 2:
1488 1488 i> 0\n
1489 1489 i> flush() -> None
1490 1490 o> readline() -> 2:
1491 1491 o> 0\n
1492 1492 o> readline() -> 2:
1493 1493 o> 1\n
1494 1494 o> read(1) -> 1: 0
1495 1495 result: 0
1496 1496 remote output:
1497 1497 e> read(-1) -> 212:
1498 1498 e> adding changesets\n
1499 1499 e> adding manifests\n
1500 1500 e> adding file changes\n
1501 1501 e> added 1 changesets with 1 changes to 1 files\n
1502 1502 e> stderr 1\n
1503 1503 e> stderr 2\n
1504 1504 e> transaction abort!\n
1505 1505 e> rollback completed\n
1506 1506 e> abort: pretxnchangegroup.fail hook exited with status 1\n
1507 1507
1508 1508 Shell hook writing to stdout and stderr has output captured
1509 1509
1510 1510 $ cat > $TESTTMP/hook.sh << EOF
1511 1511 > echo 'stdout 1'
1512 1512 > echo 'stderr 1' 1>&2
1513 1513 > echo 'stdout 2'
1514 1514 > echo 'stderr 2' 1>&2
1515 1515 > exit 1
1516 1516 > EOF
1517 1517
1518 1518 $ debugwireproto << EOF
1519 1519 > command unbundle
1520 1520 > # This is "force" in hex.
1521 1521 > heads 666f726365
1522 1522 > PUSHFILE ../initial.v1.hg
1523 1523 > readavailable
1524 1524 > EOF
1525 1525 testing ssh1
1526 1526 creating ssh peer from handshake results
1527 1527 i> write(104) -> 104:
1528 1528 i> hello\n
1529 1529 i> between\n
1530 1530 i> pairs 81\n
1531 1531 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1532 1532 i> flush() -> None
1533 1533 o> readline() -> 4:
1534 1534 o> 427\n
1535 1535 o> readline() -> 427:
1536 1536 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
1537 1537 o> readline() -> 2:
1538 1538 o> 1\n
1539 1539 o> readline() -> 1:
1540 1540 o> \n
1541 1541 sending unbundle command
1542 1542 i> write(9) -> 9:
1543 1543 i> unbundle\n
1544 1544 i> write(9) -> 9:
1545 1545 i> heads 10\n
1546 1546 i> write(10) -> 10: 666f726365
1547 1547 i> flush() -> None
1548 1548 o> readline() -> 2:
1549 1549 o> 0\n
1550 1550 i> write(4) -> 4:
1551 1551 i> 426\n
1552 1552 i> write(426) -> 426:
1553 1553 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1554 1554 i> test\n
1555 1555 i> 0 0\n
1556 1556 i> foo\n
1557 1557 i> \n
1558 1558 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1559 1559 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1560 1560 i> \x00\x00\x00\x00\x00\x00\x00\x00
1561 1561 i> write(2) -> 2:
1562 1562 i> 0\n
1563 1563 i> flush() -> None
1564 1564 o> readline() -> 2:
1565 1565 o> 0\n
1566 1566 o> readline() -> 2:
1567 1567 o> 1\n
1568 1568 o> read(1) -> 1: 0
1569 1569 result: 0
1570 1570 remote output:
1571 1571 e> read(-1) -> 230:
1572 1572 e> adding changesets\n
1573 1573 e> adding manifests\n
1574 1574 e> adding file changes\n
1575 1575 e> added 1 changesets with 1 changes to 1 files\n
1576 1576 e> stdout 1\n
1577 1577 e> stderr 1\n
1578 1578 e> stdout 2\n
1579 1579 e> stderr 2\n
1580 1580 e> transaction abort!\n
1581 1581 e> rollback completed\n
1582 1582 e> abort: pretxnchangegroup.fail hook exited with status 1\n
1583 1583
1584 1584 testing ssh2
1585 1585 creating ssh peer from handshake results
1586 1586 i> write(171) -> 171:
1587 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1587 i> upgrade * proto=exp-ssh-v2-0002\n (glob)
1588 1588 i> hello\n
1589 1589 i> between\n
1590 1590 i> pairs 81\n
1591 1591 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1592 1592 i> flush() -> None
1593 1593 o> readline() -> 62:
1594 o> upgraded * exp-ssh-v2-0001\n (glob)
1594 o> upgraded * exp-ssh-v2-0002\n (glob)
1595 1595 o> readline() -> 4:
1596 1596 o> 426\n
1597 1597 o> read(426) -> 426: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
1598 1598 o> read(1) -> 1:
1599 1599 o> \n
1600 1600 sending unbundle command
1601 1601 i> write(9) -> 9:
1602 1602 i> unbundle\n
1603 1603 i> write(9) -> 9:
1604 1604 i> heads 10\n
1605 1605 i> write(10) -> 10: 666f726365
1606 1606 i> flush() -> None
1607 1607 o> readline() -> 2:
1608 1608 o> 0\n
1609 1609 i> write(4) -> 4:
1610 1610 i> 426\n
1611 1611 i> write(426) -> 426:
1612 1612 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1613 1613 i> test\n
1614 1614 i> 0 0\n
1615 1615 i> foo\n
1616 1616 i> \n
1617 1617 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1618 1618 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1619 1619 i> \x00\x00\x00\x00\x00\x00\x00\x00
1620 1620 i> write(2) -> 2:
1621 1621 i> 0\n
1622 1622 i> flush() -> None
1623 1623 o> readline() -> 2:
1624 1624 o> 0\n
1625 1625 o> readline() -> 2:
1626 1626 o> 1\n
1627 1627 o> read(1) -> 1: 0
1628 1628 result: 0
1629 1629 remote output:
1630 1630 e> read(-1) -> 230:
1631 1631 e> adding changesets\n
1632 1632 e> adding manifests\n
1633 1633 e> adding file changes\n
1634 1634 e> added 1 changesets with 1 changes to 1 files\n
1635 1635 e> stdout 1\n
1636 1636 e> stderr 1\n
1637 1637 e> stdout 2\n
1638 1638 e> stderr 2\n
1639 1639 e> transaction abort!\n
1640 1640 e> rollback completed\n
1641 1641 e> abort: pretxnchangegroup.fail hook exited with status 1\n
1642 1642
1643 1643 Shell and Python hooks writing to stdout and stderr have output captured
1644 1644
1645 1645 $ cat > $TESTTMP/hook.sh << EOF
1646 1646 > echo 'shell stdout 1'
1647 1647 > echo 'shell stderr 1' 1>&2
1648 1648 > echo 'shell stdout 2'
1649 1649 > echo 'shell stderr 2' 1>&2
1650 1650 > exit 0
1651 1651 > EOF
1652 1652
1653 1653 $ cat > .hg/hgrc << EOF
1654 1654 > [hooks]
1655 1655 > pretxnchangegroup.a = sh $TESTTMP/hook.sh
1656 1656 > pretxnchangegroup.b = python:$TESTTMP/failhook:hookprintstderrandstdout
1657 1657 > EOF
1658 1658
1659 1659 $ debugwireproto << EOF
1660 1660 > command unbundle
1661 1661 > # This is "force" in hex.
1662 1662 > heads 666f726365
1663 1663 > PUSHFILE ../initial.v1.hg
1664 1664 > readavailable
1665 1665 > EOF
1666 1666 testing ssh1
1667 1667 creating ssh peer from handshake results
1668 1668 i> write(104) -> 104:
1669 1669 i> hello\n
1670 1670 i> between\n
1671 1671 i> pairs 81\n
1672 1672 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1673 1673 i> flush() -> None
1674 1674 o> readline() -> 4:
1675 1675 o> 427\n
1676 1676 o> readline() -> 427:
1677 1677 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
1678 1678 o> readline() -> 2:
1679 1679 o> 1\n
1680 1680 o> readline() -> 1:
1681 1681 o> \n
1682 1682 sending unbundle command
1683 1683 i> write(9) -> 9:
1684 1684 i> unbundle\n
1685 1685 i> write(9) -> 9:
1686 1686 i> heads 10\n
1687 1687 i> write(10) -> 10: 666f726365
1688 1688 i> flush() -> None
1689 1689 o> readline() -> 2:
1690 1690 o> 0\n
1691 1691 i> write(4) -> 4:
1692 1692 i> 426\n
1693 1693 i> write(426) -> 426:
1694 1694 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1695 1695 i> test\n
1696 1696 i> 0 0\n
1697 1697 i> foo\n
1698 1698 i> \n
1699 1699 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1700 1700 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1701 1701 i> \x00\x00\x00\x00\x00\x00\x00\x00
1702 1702 i> write(2) -> 2:
1703 1703 i> 0\n
1704 1704 i> flush() -> None
1705 1705 o> readline() -> 2:
1706 1706 o> 0\n
1707 1707 o> readline() -> 2:
1708 1708 o> 1\n
1709 1709 o> read(1) -> 1: 0
1710 1710 result: 0
1711 1711 remote output:
1712 1712 e> read(-1) -> 273:
1713 1713 e> adding changesets\n
1714 1714 e> adding manifests\n
1715 1715 e> adding file changes\n
1716 1716 e> added 1 changesets with 1 changes to 1 files\n
1717 1717 e> shell stdout 1\n
1718 1718 e> shell stderr 1\n
1719 1719 e> shell stdout 2\n
1720 1720 e> shell stderr 2\n
1721 1721 e> stdout 1\n
1722 1722 e> stderr 1\n
1723 1723 e> stdout 2\n
1724 1724 e> stderr 2\n
1725 1725 e> transaction abort!\n
1726 1726 e> rollback completed\n
1727 1727 e> abort: pretxnchangegroup.b hook failed\n
1728 1728
1729 1729 testing ssh2
1730 1730 creating ssh peer from handshake results
1731 1731 i> write(171) -> 171:
1732 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1732 i> upgrade * proto=exp-ssh-v2-0002\n (glob)
1733 1733 i> hello\n
1734 1734 i> between\n
1735 1735 i> pairs 81\n
1736 1736 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1737 1737 i> flush() -> None
1738 1738 o> readline() -> 62:
1739 o> upgraded * exp-ssh-v2-0001\n (glob)
1739 o> upgraded * exp-ssh-v2-0002\n (glob)
1740 1740 o> readline() -> 4:
1741 1741 o> 426\n
1742 1742 o> read(426) -> 426: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
1743 1743 o> read(1) -> 1:
1744 1744 o> \n
1745 1745 sending unbundle command
1746 1746 i> write(9) -> 9:
1747 1747 i> unbundle\n
1748 1748 i> write(9) -> 9:
1749 1749 i> heads 10\n
1750 1750 i> write(10) -> 10: 666f726365
1751 1751 i> flush() -> None
1752 1752 o> readline() -> 2:
1753 1753 o> 0\n
1754 1754 i> write(4) -> 4:
1755 1755 i> 426\n
1756 1756 i> write(426) -> 426:
1757 1757 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1758 1758 i> test\n
1759 1759 i> 0 0\n
1760 1760 i> foo\n
1761 1761 i> \n
1762 1762 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1763 1763 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1764 1764 i> \x00\x00\x00\x00\x00\x00\x00\x00
1765 1765 i> write(2) -> 2:
1766 1766 i> 0\n
1767 1767 i> flush() -> None
1768 1768 o> readline() -> 2:
1769 1769 o> 0\n
1770 1770 o> readline() -> 2:
1771 1771 o> 1\n
1772 1772 o> read(1) -> 1: 0
1773 1773 result: 0
1774 1774 remote output:
1775 1775 e> read(-1) -> 273:
1776 1776 e> adding changesets\n
1777 1777 e> adding manifests\n
1778 1778 e> adding file changes\n
1779 1779 e> added 1 changesets with 1 changes to 1 files\n
1780 1780 e> shell stdout 1\n
1781 1781 e> shell stderr 1\n
1782 1782 e> shell stdout 2\n
1783 1783 e> shell stderr 2\n
1784 1784 e> stdout 1\n
1785 1785 e> stderr 1\n
1786 1786 e> stdout 2\n
1787 1787 e> stderr 2\n
1788 1788 e> transaction abort!\n
1789 1789 e> rollback completed\n
1790 1790 e> abort: pretxnchangegroup.b hook failed\n
1791 1791
1792 1792 $ cd ..
1793 1793
1794 1794 Pushing a bundle1 with no output
1795 1795
1796 1796 $ hg init simplerepo
1797 1797 $ cd simplerepo
1798 1798
1799 1799 $ debugwireproto 1 << EOF
1800 1800 > command unbundle
1801 1801 > # This is "force" in hex.
1802 1802 > heads 666f726365
1803 1803 > PUSHFILE ../initial.v1.hg
1804 1804 > readavailable
1805 1805 > EOF
1806 1806 testing ssh1
1807 1807 creating ssh peer from handshake results
1808 1808 i> write(104) -> 104:
1809 1809 i> hello\n
1810 1810 i> between\n
1811 1811 i> pairs 81\n
1812 1812 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1813 1813 i> flush() -> None
1814 1814 o> readline() -> 4:
1815 1815 o> 427\n
1816 1816 o> readline() -> 427:
1817 1817 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
1818 1818 o> readline() -> 2:
1819 1819 o> 1\n
1820 1820 o> readline() -> 1:
1821 1821 o> \n
1822 1822 sending unbundle command
1823 1823 i> write(9) -> 9:
1824 1824 i> unbundle\n
1825 1825 i> write(9) -> 9:
1826 1826 i> heads 10\n
1827 1827 i> write(10) -> 10: 666f726365
1828 1828 i> flush() -> None
1829 1829 o> readline() -> 2:
1830 1830 o> 0\n
1831 1831 i> write(4) -> 4:
1832 1832 i> 426\n
1833 1833 i> write(426) -> 426:
1834 1834 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1835 1835 i> test\n
1836 1836 i> 0 0\n
1837 1837 i> foo\n
1838 1838 i> \n
1839 1839 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1840 1840 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1841 1841 i> \x00\x00\x00\x00\x00\x00\x00\x00
1842 1842 i> write(2) -> 2:
1843 1843 i> 0\n
1844 1844 i> flush() -> None
1845 1845 o> readline() -> 2:
1846 1846 o> 0\n
1847 1847 o> readline() -> 2:
1848 1848 o> 1\n
1849 1849 o> read(1) -> 1: 1
1850 1850 result: 1
1851 1851 remote output:
1852 1852 e> read(-1) -> 100:
1853 1853 e> adding changesets\n
1854 1854 e> adding manifests\n
1855 1855 e> adding file changes\n
1856 1856 e> added 1 changesets with 1 changes to 1 files\n
1857 1857
1858 1858 testing ssh2
1859 1859 creating ssh peer from handshake results
1860 1860 i> write(171) -> 171:
1861 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1861 i> upgrade * proto=exp-ssh-v2-0002\n (glob)
1862 1862 i> hello\n
1863 1863 i> between\n
1864 1864 i> pairs 81\n
1865 1865 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1866 1866 i> flush() -> None
1867 1867 o> readline() -> 62:
1868 o> upgraded * exp-ssh-v2-0001\n (glob)
1868 o> upgraded * exp-ssh-v2-0002\n (glob)
1869 1869 o> readline() -> 4:
1870 1870 o> 426\n
1871 1871 o> read(426) -> 426: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
1872 1872 o> read(1) -> 1:
1873 1873 o> \n
1874 1874 sending unbundle command
1875 1875 i> write(9) -> 9:
1876 1876 i> unbundle\n
1877 1877 i> write(9) -> 9:
1878 1878 i> heads 10\n
1879 1879 i> write(10) -> 10: 666f726365
1880 1880 i> flush() -> None
1881 1881 o> readline() -> 2:
1882 1882 o> 0\n
1883 1883 i> write(4) -> 4:
1884 1884 i> 426\n
1885 1885 i> write(426) -> 426:
1886 1886 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1887 1887 i> test\n
1888 1888 i> 0 0\n
1889 1889 i> foo\n
1890 1890 i> \n
1891 1891 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1892 1892 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1893 1893 i> \x00\x00\x00\x00\x00\x00\x00\x00
1894 1894 i> write(2) -> 2:
1895 1895 i> 0\n
1896 1896 i> flush() -> None
1897 1897 o> readline() -> 2:
1898 1898 o> 0\n
1899 1899 o> readline() -> 2:
1900 1900 o> 1\n
1901 1901 o> read(1) -> 1: 1
1902 1902 result: 1
1903 1903 remote output:
1904 1904 e> read(-1) -> 100:
1905 1905 e> adding changesets\n
1906 1906 e> adding manifests\n
1907 1907 e> adding file changes\n
1908 1908 e> added 1 changesets with 1 changes to 1 files\n
1909 1909
1910 1910 $ cd ..
1911 1911
1912 1912 Pushing a bundle1 with ui.write() and ui.write_err()
1913 1913
1914 1914 $ cat > $TESTTMP/hook << EOF
1915 1915 > def hookuiwrite(ui, repo, **kwargs):
1916 1916 > ui.write(b'ui.write 1\n')
1917 1917 > ui.write_err(b'ui.write_err 1\n')
1918 1918 > ui.write(b'ui.write 2\n')
1919 1919 > ui.write_err(b'ui.write_err 2\n')
1920 1920 > EOF
1921 1921
1922 1922 $ hg init uiwriterepo
1923 1923 $ cd uiwriterepo
1924 1924 $ cat > .hg/hgrc << EOF
1925 1925 > [hooks]
1926 1926 > pretxnchangegroup.hook = python:$TESTTMP/hook:hookuiwrite
1927 1927 > EOF
1928 1928
1929 1929 $ debugwireproto 1 << EOF
1930 1930 > command unbundle
1931 1931 > # This is "force" in hex.
1932 1932 > heads 666f726365
1933 1933 > PUSHFILE ../initial.v1.hg
1934 1934 > readavailable
1935 1935 > EOF
1936 1936 testing ssh1
1937 1937 creating ssh peer from handshake results
1938 1938 i> write(104) -> 104:
1939 1939 i> hello\n
1940 1940 i> between\n
1941 1941 i> pairs 81\n
1942 1942 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1943 1943 i> flush() -> None
1944 1944 o> readline() -> 4:
1945 1945 o> 427\n
1946 1946 o> readline() -> 427:
1947 1947 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
1948 1948 o> readline() -> 2:
1949 1949 o> 1\n
1950 1950 o> readline() -> 1:
1951 1951 o> \n
1952 1952 sending unbundle command
1953 1953 i> write(9) -> 9:
1954 1954 i> unbundle\n
1955 1955 i> write(9) -> 9:
1956 1956 i> heads 10\n
1957 1957 i> write(10) -> 10: 666f726365
1958 1958 i> flush() -> None
1959 1959 o> readline() -> 2:
1960 1960 o> 0\n
1961 1961 i> write(4) -> 4:
1962 1962 i> 426\n
1963 1963 i> write(426) -> 426:
1964 1964 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
1965 1965 i> test\n
1966 1966 i> 0 0\n
1967 1967 i> foo\n
1968 1968 i> \n
1969 1969 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
1970 1970 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
1971 1971 i> \x00\x00\x00\x00\x00\x00\x00\x00
1972 1972 i> write(2) -> 2:
1973 1973 i> 0\n
1974 1974 i> flush() -> None
1975 1975 o> readline() -> 2:
1976 1976 o> 0\n
1977 1977 o> readline() -> 2:
1978 1978 o> 1\n
1979 1979 o> read(1) -> 1: 1
1980 1980 result: 1
1981 1981 remote output:
1982 1982 e> read(-1) -> 152:
1983 1983 e> adding changesets\n
1984 1984 e> adding manifests\n
1985 1985 e> adding file changes\n
1986 1986 e> added 1 changesets with 1 changes to 1 files\n
1987 1987 e> ui.write 1\n
1988 1988 e> ui.write_err 1\n
1989 1989 e> ui.write 2\n
1990 1990 e> ui.write_err 2\n
1991 1991
1992 1992 testing ssh2
1993 1993 creating ssh peer from handshake results
1994 1994 i> write(171) -> 171:
1995 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1995 i> upgrade * proto=exp-ssh-v2-0002\n (glob)
1996 1996 i> hello\n
1997 1997 i> between\n
1998 1998 i> pairs 81\n
1999 1999 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
2000 2000 i> flush() -> None
2001 2001 o> readline() -> 62:
2002 o> upgraded * exp-ssh-v2-0001\n (glob)
2002 o> upgraded * exp-ssh-v2-0002\n (glob)
2003 2003 o> readline() -> 4:
2004 2004 o> 426\n
2005 2005 o> read(426) -> 426: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
2006 2006 o> read(1) -> 1:
2007 2007 o> \n
2008 2008 sending unbundle command
2009 2009 i> write(9) -> 9:
2010 2010 i> unbundle\n
2011 2011 i> write(9) -> 9:
2012 2012 i> heads 10\n
2013 2013 i> write(10) -> 10: 666f726365
2014 2014 i> flush() -> None
2015 2015 o> readline() -> 2:
2016 2016 o> 0\n
2017 2017 i> write(4) -> 4:
2018 2018 i> 426\n
2019 2019 i> write(426) -> 426:
2020 2020 i> HG10UN\x00\x00\x00\x9eh\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00>cba485ca3678256e044428f70f58291196f6e9de\n
2021 2021 i> test\n
2022 2022 i> 0 0\n
2023 2023 i> foo\n
2024 2024 i> \n
2025 2025 i> initial\x00\x00\x00\x00\x00\x00\x00\x8d\xcb\xa4\x85\xca6x%n\x04D(\xf7\x0fX)\x11\x96\xf6\xe9\xde\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00-foo\x00362fef284ce2ca02aecc8de6d5e8a1c3af0556fe\n
2026 2026 i> \x00\x00\x00\x00\x00\x00\x00\x07foo\x00\x00\x00b6/\xef(L\xe2\xca\x02\xae\xcc\x8d\xe6\xd5\xe8\xa1\xc3\xaf\x05V\xfe\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00h\x98b\x13\xbdD\x85\xeaQS55\xe3\xfc\x9ex\x00zq\x1f\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x020\n
2027 2027 i> \x00\x00\x00\x00\x00\x00\x00\x00
2028 2028 i> write(2) -> 2:
2029 2029 i> 0\n
2030 2030 i> flush() -> None
2031 2031 o> readline() -> 2:
2032 2032 o> 0\n
2033 2033 o> readline() -> 2:
2034 2034 o> 1\n
2035 2035 o> read(1) -> 1: 1
2036 2036 result: 1
2037 2037 remote output:
2038 2038 e> read(-1) -> 152:
2039 2039 e> adding changesets\n
2040 2040 e> adding manifests\n
2041 2041 e> adding file changes\n
2042 2042 e> added 1 changesets with 1 changes to 1 files\n
2043 2043 e> ui.write 1\n
2044 2044 e> ui.write_err 1\n
2045 2045 e> ui.write 2\n
2046 2046 e> ui.write_err 2\n
@@ -1,2199 +1,2199 b''
1 1 #require no-chg
2 2
3 3 $ cat > hgrc-sshv2 << EOF
4 4 > %include $HGRCPATH
5 5 > [experimental]
6 6 > sshpeer.advertise-v2 = true
7 7 > sshserver.support-v2 = true
8 8 > EOF
9 9
10 10 Helper function to run protocol tests against multiple protocol versions.
11 11 This is easier than using #testcases because managing differences between
12 12 protocols with inline conditional output is hard to read.
13 13
14 14 $ debugwireproto() {
15 15 > commands=`cat -`
16 16 > echo 'testing ssh1'
17 17 > echo "${commands}" | hg --verbose debugwireproto --localssh
18 18 > echo ""
19 19 > echo 'testing ssh2'
20 20 > echo "${commands}" | HGRCPATH=$TESTTMP/hgrc-sshv2 hg --verbose debugwireproto --localssh
21 21 > }
22 22
23 23 $ cat >> $HGRCPATH << EOF
24 24 > [ui]
25 25 > ssh = "$PYTHON" "$TESTDIR/dummyssh"
26 26 > [devel]
27 27 > debug.peer-request = true
28 28 > [extensions]
29 29 > sshprotoext = $TESTDIR/sshprotoext.py
30 30 > EOF
31 31
32 32 $ hg init server
33 33 $ cd server
34 34 $ echo 0 > foo
35 35 $ hg -q add foo
36 36 $ hg commit -m initial
37 37
38 38 A no-op connection performs a handshake
39 39
40 40 $ hg debugwireproto --localssh << EOF
41 41 > EOF
42 42 creating ssh peer from handshake results
43 43
44 44 Raw peers don't perform any activity
45 45
46 46 $ hg debugwireproto --localssh --peer raw << EOF
47 47 > EOF
48 48 using raw connection to peer
49 49 $ hg debugwireproto --localssh --peer ssh1 << EOF
50 50 > EOF
51 51 creating ssh peer for wire protocol version 1
52 52 $ hg debugwireproto --localssh --peer ssh2 << EOF
53 53 > EOF
54 54 creating ssh peer for wire protocol version 2
55 55
56 56 Test a normal behaving server, for sanity
57 57
58 58 $ cd ..
59 59
60 60 $ hg --debug debugpeer ssh://user@dummy/server
61 61 running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) (no-windows !)
62 62 running * "*\tests/dummyssh" "user@dummy" "hg -R server serve --stdio" (glob) (windows !)
63 63 devel-peer-request: hello+between
64 64 devel-peer-request: pairs: 81 bytes
65 65 sending hello command
66 66 sending between command
67 67 remote: 427
68 68 remote: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
69 69 remote: 1
70 70 devel-peer-request: protocaps
71 71 devel-peer-request: caps: * bytes (glob)
72 72 sending protocaps command
73 73 url: ssh://user@dummy/server
74 74 local: no
75 75 pushable: yes
76 76
77 77 Server should answer the "hello" command in isolation
78 78
79 79 $ hg -R server debugwireproto --localssh --peer raw << EOF
80 80 > raw
81 81 > hello\n
82 82 > readline
83 83 > readline
84 84 > EOF
85 85 using raw connection to peer
86 86 i> write(6) -> 6:
87 87 i> hello\n
88 88 o> readline() -> 4:
89 89 o> 427\n
90 90 o> readline() -> 427:
91 91 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
92 92
93 93 `hg debugserve --sshstdio` works
94 94
95 95 $ cd server
96 96 $ hg debugserve --sshstdio << EOF
97 97 > hello
98 98 > EOF
99 99 427
100 100 capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
101 101
102 102 I/O logging works
103 103
104 104 $ hg debugserve --sshstdio --logiofd 1 << EOF
105 105 > hello
106 106 > EOF
107 107 o> write(4) -> 4:
108 108 o> 427\n
109 109 o> write(427) -> 427:
110 110 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
111 111 427
112 112 capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
113 113 o> flush() -> None
114 114
115 115 $ hg debugserve --sshstdio --logiofile $TESTTMP/io << EOF
116 116 > hello
117 117 > EOF
118 118 427
119 119 capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
120 120
121 121 $ cat $TESTTMP/io
122 122 o> write(4) -> 4:
123 123 o> 427\n
124 124 o> write(427) -> 427:
125 125 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
126 126 o> flush() -> None
127 127
128 128 $ cd ..
129 129
130 130 >=0.9.1 clients send a "hello" + "between" for the null range as part of handshake.
131 131 Server should reply with capabilities and should send "1\n\n" as a successful
132 132 reply with empty response to the "between".
133 133
134 134 $ hg -R server debugwireproto --localssh --peer raw << EOF
135 135 > raw
136 136 > hello\n
137 137 > readline
138 138 > readline
139 139 > raw
140 140 > between\n
141 141 > pairs 81\n
142 142 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
143 143 > readline
144 144 > readline
145 145 > EOF
146 146 using raw connection to peer
147 147 i> write(6) -> 6:
148 148 i> hello\n
149 149 o> readline() -> 4:
150 150 o> 427\n
151 151 o> readline() -> 427:
152 152 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
153 153 i> write(98) -> 98:
154 154 i> between\n
155 155 i> pairs 81\n
156 156 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
157 157 o> readline() -> 2:
158 158 o> 1\n
159 159 o> readline() -> 1:
160 160 o> \n
161 161
162 162 SSH banner is not printed by default, ignored by clients
163 163
164 164 $ SSHSERVERMODE=banner hg debugpeer ssh://user@dummy/server
165 165 url: ssh://user@dummy/server
166 166 local: no
167 167 pushable: yes
168 168
169 169 --debug will print the banner
170 170
171 171 $ SSHSERVERMODE=banner hg --debug debugpeer ssh://user@dummy/server
172 172 running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) (no-windows !)
173 173 running * "*\tests/dummyssh" "user@dummy" "hg -R server serve --stdio" (glob) (windows !)
174 174 devel-peer-request: hello+between
175 175 devel-peer-request: pairs: 81 bytes
176 176 sending hello command
177 177 sending between command
178 178 remote: banner: line 0
179 179 remote: banner: line 1
180 180 remote: banner: line 2
181 181 remote: banner: line 3
182 182 remote: banner: line 4
183 183 remote: banner: line 5
184 184 remote: banner: line 6
185 185 remote: banner: line 7
186 186 remote: banner: line 8
187 187 remote: banner: line 9
188 188 remote: 427
189 189 remote: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
190 190 remote: 1
191 191 devel-peer-request: protocaps
192 192 devel-peer-request: caps: * bytes (glob)
193 193 sending protocaps command
194 194 url: ssh://user@dummy/server
195 195 local: no
196 196 pushable: yes
197 197
198 198 And test the banner with the raw protocol
199 199
200 200 $ SSHSERVERMODE=banner hg -R server debugwireproto --localssh --peer raw << EOF
201 201 > raw
202 202 > hello\n
203 203 > readline
204 204 > readline
205 205 > readline
206 206 > readline
207 207 > readline
208 208 > readline
209 209 > readline
210 210 > readline
211 211 > readline
212 212 > readline
213 213 > readline
214 214 > readline
215 215 > raw
216 216 > between\n
217 217 > pairs 81\n
218 218 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
219 219 > readline
220 220 > readline
221 221 > EOF
222 222 using raw connection to peer
223 223 i> write(6) -> 6:
224 224 i> hello\n
225 225 o> readline() -> 15:
226 226 o> banner: line 0\n
227 227 o> readline() -> 15:
228 228 o> banner: line 1\n
229 229 o> readline() -> 15:
230 230 o> banner: line 2\n
231 231 o> readline() -> 15:
232 232 o> banner: line 3\n
233 233 o> readline() -> 15:
234 234 o> banner: line 4\n
235 235 o> readline() -> 15:
236 236 o> banner: line 5\n
237 237 o> readline() -> 15:
238 238 o> banner: line 6\n
239 239 o> readline() -> 15:
240 240 o> banner: line 7\n
241 241 o> readline() -> 15:
242 242 o> banner: line 8\n
243 243 o> readline() -> 15:
244 244 o> banner: line 9\n
245 245 o> readline() -> 4:
246 246 o> 427\n
247 247 o> readline() -> 427:
248 248 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
249 249 i> write(98) -> 98:
250 250 i> between\n
251 251 i> pairs 81\n
252 252 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
253 253 o> readline() -> 2:
254 254 o> 1\n
255 255 o> readline() -> 1:
256 256 o> \n
257 257
258 258 Connecting to a <0.9.1 server that doesn't support the hello command.
259 259 The client should refuse, as we dropped support for connecting to such
260 260 servers.
261 261
262 262 $ SSHSERVERMODE=no-hello hg --debug debugpeer ssh://user@dummy/server
263 263 running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) (no-windows !)
264 264 running * "*\tests/dummyssh" "user@dummy" "hg -R server serve --stdio" (glob) (windows !)
265 265 devel-peer-request: hello+between
266 266 devel-peer-request: pairs: 81 bytes
267 267 sending hello command
268 268 sending between command
269 269 remote: 0
270 270 remote: 1
271 271 abort: no suitable response from remote hg!
272 272 [255]
273 273
274 274 Sending an unknown command to the server results in an empty response to that command
275 275
276 276 $ hg -R server debugwireproto --localssh --peer raw << EOF
277 277 > raw
278 278 > pre-hello\n
279 279 > readline
280 280 > raw
281 281 > hello\n
282 282 > readline
283 283 > raw
284 284 > between\n
285 285 > pairs 81\n
286 286 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
287 287 > readline
288 288 > readline
289 289 > EOF
290 290 using raw connection to peer
291 291 i> write(10) -> 10:
292 292 i> pre-hello\n
293 293 o> readline() -> 2:
294 294 o> 0\n
295 295 i> write(6) -> 6:
296 296 i> hello\n
297 297 o> readline() -> 4:
298 298 o> 427\n
299 299 i> write(98) -> 98:
300 300 i> between\n
301 301 i> pairs 81\n
302 302 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
303 303 o> readline() -> 427:
304 304 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
305 305 o> readline() -> 2:
306 306 o> 1\n
307 307
308 308 $ hg --config sshpeer.mode=extra-handshake-commands --config sshpeer.handshake-mode=pre-no-args --debug debugpeer ssh://user@dummy/server
309 309 running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) (no-windows !)
310 310 running * "*\tests/dummyssh" "user@dummy" "hg -R server serve --stdio" (glob) (windows !)
311 311 sending no-args command
312 312 devel-peer-request: hello+between
313 313 devel-peer-request: pairs: 81 bytes
314 314 sending hello command
315 315 sending between command
316 316 remote: 0
317 317 remote: 427
318 318 remote: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
319 319 remote: 1
320 320 devel-peer-request: protocaps
321 321 devel-peer-request: caps: * bytes (glob)
322 322 sending protocaps command
323 323 url: ssh://user@dummy/server
324 324 local: no
325 325 pushable: yes
326 326
327 327 Send multiple unknown commands before hello
328 328
329 329 $ hg -R server debugwireproto --localssh --peer raw << EOF
330 330 > raw
331 331 > unknown1\n
332 332 > readline
333 333 > raw
334 334 > unknown2\n
335 335 > readline
336 336 > raw
337 337 > unknown3\n
338 338 > readline
339 339 > raw
340 340 > hello\n
341 341 > readline
342 342 > readline
343 343 > raw
344 344 > between\n
345 345 > pairs 81\n
346 346 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
347 347 > readline
348 348 > readline
349 349 > EOF
350 350 using raw connection to peer
351 351 i> write(9) -> 9:
352 352 i> unknown1\n
353 353 o> readline() -> 2:
354 354 o> 0\n
355 355 i> write(9) -> 9:
356 356 i> unknown2\n
357 357 o> readline() -> 2:
358 358 o> 0\n
359 359 i> write(9) -> 9:
360 360 i> unknown3\n
361 361 o> readline() -> 2:
362 362 o> 0\n
363 363 i> write(6) -> 6:
364 364 i> hello\n
365 365 o> readline() -> 4:
366 366 o> 427\n
367 367 o> readline() -> 427:
368 368 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
369 369 i> write(98) -> 98:
370 370 i> between\n
371 371 i> pairs 81\n
372 372 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
373 373 o> readline() -> 2:
374 374 o> 1\n
375 375 o> readline() -> 1:
376 376 o> \n
377 377
378 378 $ hg --config sshpeer.mode=extra-handshake-commands --config sshpeer.handshake-mode=pre-multiple-no-args --debug debugpeer ssh://user@dummy/server
379 379 running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) (no-windows !)
380 380 running * "*\tests/dummyssh" "user@dummy" "hg -R server serve --stdio" (glob) (windows !)
381 381 sending unknown1 command
382 382 sending unknown2 command
383 383 sending unknown3 command
384 384 devel-peer-request: hello+between
385 385 devel-peer-request: pairs: 81 bytes
386 386 sending hello command
387 387 sending between command
388 388 remote: 0
389 389 remote: 0
390 390 remote: 0
391 391 remote: 427
392 392 remote: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
393 393 remote: 1
394 394 devel-peer-request: protocaps
395 395 devel-peer-request: caps: * bytes (glob)
396 396 sending protocaps command
397 397 url: ssh://user@dummy/server
398 398 local: no
399 399 pushable: yes
400 400
401 401 Send an unknown command before hello that has arguments
402 402
403 403 $ cd server
404 404
405 405 $ hg debugwireproto --localssh --peer raw << EOF
406 406 > raw
407 407 > with-args\n
408 408 > foo 13\n
409 409 > value for foo\n
410 410 > bar 13\n
411 411 > value for bar\n
412 412 > readline
413 413 > readline
414 414 > readline
415 415 > readline
416 416 > readline
417 417 > raw
418 418 > hello\n
419 419 > readline
420 420 > readline
421 421 > raw
422 422 > between\n
423 423 > pairs 81\n
424 424 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
425 425 > readline
426 426 > readline
427 427 > EOF
428 428 using raw connection to peer
429 429 i> write(52) -> 52:
430 430 i> with-args\n
431 431 i> foo 13\n
432 432 i> value for foo\n
433 433 i> bar 13\n
434 434 i> value for bar\n
435 435 o> readline() -> 2:
436 436 o> 0\n
437 437 o> readline() -> 2:
438 438 o> 0\n
439 439 o> readline() -> 2:
440 440 o> 0\n
441 441 o> readline() -> 2:
442 442 o> 0\n
443 443 o> readline() -> 2:
444 444 o> 0\n
445 445 i> write(6) -> 6:
446 446 i> hello\n
447 447 o> readline() -> 4:
448 448 o> 427\n
449 449 o> readline() -> 427:
450 450 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
451 451 i> write(98) -> 98:
452 452 i> between\n
453 453 i> pairs 81\n
454 454 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
455 455 o> readline() -> 2:
456 456 o> 1\n
457 457 o> readline() -> 1:
458 458 o> \n
459 459
460 460 Send an unknown command having an argument that looks numeric
461 461
462 462 $ hg debugwireproto --localssh --peer raw << EOF
463 463 > raw
464 464 > unknown\n
465 465 > foo 1\n
466 466 > 0\n
467 467 > readline
468 468 > readline
469 469 > readline
470 470 > raw
471 471 > hello\n
472 472 > readline
473 473 > readline
474 474 > raw
475 475 > between\n
476 476 > pairs 81\n
477 477 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
478 478 > readline
479 479 > readline
480 480 > EOF
481 481 using raw connection to peer
482 482 i> write(16) -> 16:
483 483 i> unknown\n
484 484 i> foo 1\n
485 485 i> 0\n
486 486 o> readline() -> 2:
487 487 o> 0\n
488 488 o> readline() -> 2:
489 489 o> 0\n
490 490 o> readline() -> 2:
491 491 o> 0\n
492 492 i> write(6) -> 6:
493 493 i> hello\n
494 494 o> readline() -> 4:
495 495 o> 427\n
496 496 o> readline() -> 427:
497 497 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
498 498 i> write(98) -> 98:
499 499 i> between\n
500 500 i> pairs 81\n
501 501 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
502 502 o> readline() -> 2:
503 503 o> 1\n
504 504 o> readline() -> 1:
505 505 o> \n
506 506
507 507 $ hg debugwireproto --localssh --peer raw << EOF
508 508 > raw
509 509 > unknown\n
510 510 > foo 1\n
511 511 > 1\n
512 512 > readline
513 513 > readline
514 514 > readline
515 515 > raw
516 516 > hello\n
517 517 > readline
518 518 > readline
519 519 > raw
520 520 > between\n
521 521 > pairs 81\n
522 522 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
523 523 > readline
524 524 > readline
525 525 > EOF
526 526 using raw connection to peer
527 527 i> write(16) -> 16:
528 528 i> unknown\n
529 529 i> foo 1\n
530 530 i> 1\n
531 531 o> readline() -> 2:
532 532 o> 0\n
533 533 o> readline() -> 2:
534 534 o> 0\n
535 535 o> readline() -> 2:
536 536 o> 0\n
537 537 i> write(6) -> 6:
538 538 i> hello\n
539 539 o> readline() -> 4:
540 540 o> 427\n
541 541 o> readline() -> 427:
542 542 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
543 543 i> write(98) -> 98:
544 544 i> between\n
545 545 i> pairs 81\n
546 546 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
547 547 o> readline() -> 2:
548 548 o> 1\n
549 549 o> readline() -> 1:
550 550 o> \n
551 551
552 552 When sending a dict argument value, it is serialized to
553 553 "<arg> <item count>" followed by "<key> <len>\n<value>" for each item
554 554 in the dict.
555 555
556 556 Dictionary value for unknown command
557 557
558 558 $ hg debugwireproto --localssh --peer raw << EOF
559 559 > raw
560 560 > unknown\n
561 561 > dict 3\n
562 562 > key1 3\n
563 563 > foo\n
564 564 > key2 3\n
565 565 > bar\n
566 566 > key3 3\n
567 567 > baz\n
568 568 > readline
569 569 > readline
570 570 > readline
571 571 > readline
572 572 > readline
573 573 > readline
574 574 > readline
575 575 > readline
576 576 > raw
577 577 > hello\n
578 578 > readline
579 579 > readline
580 580 > EOF
581 581 using raw connection to peer
582 582 i> write(48) -> 48:
583 583 i> unknown\n
584 584 i> dict 3\n
585 585 i> key1 3\n
586 586 i> foo\n
587 587 i> key2 3\n
588 588 i> bar\n
589 589 i> key3 3\n
590 590 i> baz\n
591 591 o> readline() -> 2:
592 592 o> 0\n
593 593 o> readline() -> 2:
594 594 o> 0\n
595 595 o> readline() -> 2:
596 596 o> 0\n
597 597 o> readline() -> 2:
598 598 o> 0\n
599 599 o> readline() -> 2:
600 600 o> 0\n
601 601 o> readline() -> 2:
602 602 o> 0\n
603 603 o> readline() -> 2:
604 604 o> 0\n
605 605 o> readline() -> 2:
606 606 o> 0\n
607 607 i> write(6) -> 6:
608 608 i> hello\n
609 609 o> readline() -> 4:
610 610 o> 427\n
611 611 o> readline() -> 427:
612 612 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
613 613
614 614 Incomplete dictionary send
615 615
616 616 $ hg debugwireproto --localssh --peer raw << EOF
617 617 > raw
618 618 > unknown\n
619 619 > dict 3\n
620 620 > key1 3\n
621 621 > foo\n
622 622 > readline
623 623 > readline
624 624 > readline
625 625 > readline
626 626 > EOF
627 627 using raw connection to peer
628 628 i> write(26) -> 26:
629 629 i> unknown\n
630 630 i> dict 3\n
631 631 i> key1 3\n
632 632 i> foo\n
633 633 o> readline() -> 2:
634 634 o> 0\n
635 635 o> readline() -> 2:
636 636 o> 0\n
637 637 o> readline() -> 2:
638 638 o> 0\n
639 639 o> readline() -> 2:
640 640 o> 0\n
641 641
642 642 Incomplete value send
643 643
644 644 $ hg debugwireproto --localssh --peer raw << EOF
645 645 > raw
646 646 > unknown\n
647 647 > dict 3\n
648 648 > key1 3\n
649 649 > fo
650 650 > readline
651 651 > readline
652 652 > readline
653 653 > EOF
654 654 using raw connection to peer
655 655 i> write(24) -> 24:
656 656 i> unknown\n
657 657 i> dict 3\n
658 658 i> key1 3\n
659 659 i> fo
660 660 o> readline() -> 2:
661 661 o> 0\n
662 662 o> readline() -> 2:
663 663 o> 0\n
664 664 o> readline() -> 2:
665 665 o> 0\n
666 666
667 667 Send a command line with spaces
668 668
669 669 $ hg debugwireproto --localssh --peer raw << EOF
670 670 > raw
671 671 > unknown withspace\n
672 672 > readline
673 673 > raw
674 674 > hello\n
675 675 > readline
676 676 > readline
677 677 > raw
678 678 > between\n
679 679 > pairs 81\n
680 680 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
681 681 > readline
682 682 > readline
683 683 > EOF
684 684 using raw connection to peer
685 685 i> write(18) -> 18:
686 686 i> unknown withspace\n
687 687 o> readline() -> 2:
688 688 o> 0\n
689 689 i> write(6) -> 6:
690 690 i> hello\n
691 691 o> readline() -> 4:
692 692 o> 427\n
693 693 o> readline() -> 427:
694 694 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
695 695 i> write(98) -> 98:
696 696 i> between\n
697 697 i> pairs 81\n
698 698 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
699 699 o> readline() -> 2:
700 700 o> 1\n
701 701 o> readline() -> 1:
702 702 o> \n
703 703
704 704 $ hg debugwireproto --localssh --peer raw << EOF
705 705 > raw
706 706 > unknown with multiple spaces\n
707 707 > readline
708 708 > raw
709 709 > hello\n
710 710 > readline
711 711 > readline
712 712 > raw
713 713 > between\n
714 714 > pairs 81\n
715 715 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
716 716 > readline
717 717 > EOF
718 718 using raw connection to peer
719 719 i> write(29) -> 29:
720 720 i> unknown with multiple spaces\n
721 721 o> readline() -> 2:
722 722 o> 0\n
723 723 i> write(6) -> 6:
724 724 i> hello\n
725 725 o> readline() -> 4:
726 726 o> 427\n
727 727 o> readline() -> 427:
728 728 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
729 729 i> write(98) -> 98:
730 730 i> between\n
731 731 i> pairs 81\n
732 732 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
733 733 o> readline() -> 2:
734 734 o> 1\n
735 735
736 736 $ hg debugwireproto --localssh --peer raw << EOF
737 737 > raw
738 738 > unknown with spaces\n
739 739 > key 10\n
740 740 > some value\n
741 741 > readline
742 742 > readline
743 743 > readline
744 744 > raw
745 745 > hello\n
746 746 > readline
747 747 > readline
748 748 > raw
749 749 > between\n
750 750 > pairs 81\n
751 751 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
752 752 > readline
753 753 > readline
754 754 > EOF
755 755 using raw connection to peer
756 756 i> write(38) -> 38:
757 757 i> unknown with spaces\n
758 758 i> key 10\n
759 759 i> some value\n
760 760 o> readline() -> 2:
761 761 o> 0\n
762 762 o> readline() -> 2:
763 763 o> 0\n
764 764 o> readline() -> 2:
765 765 o> 0\n
766 766 i> write(6) -> 6:
767 767 i> hello\n
768 768 o> readline() -> 4:
769 769 o> 427\n
770 770 o> readline() -> 427:
771 771 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
772 772 i> write(98) -> 98:
773 773 i> between\n
774 774 i> pairs 81\n
775 775 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
776 776 o> readline() -> 2:
777 777 o> 1\n
778 778 o> readline() -> 1:
779 779 o> \n
780 780 Send an unknown command after the "between"
781 781
782 782 $ hg debugwireproto --localssh --peer raw << EOF
783 783 > raw
784 784 > hello\n
785 785 > readline
786 786 > readline
787 787 > raw
788 788 > between\n
789 789 > pairs 81\n
790 790 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000unknown
791 791 > readline
792 792 > readline
793 793 > EOF
794 794 using raw connection to peer
795 795 i> write(6) -> 6:
796 796 i> hello\n
797 797 o> readline() -> 4:
798 798 o> 427\n
799 799 o> readline() -> 427:
800 800 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
801 801 i> write(105) -> 105:
802 802 i> between\n
803 803 i> pairs 81\n
804 804 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000unknown
805 805 o> readline() -> 2:
806 806 o> 1\n
807 807 o> readline() -> 1:
808 808 o> \n
809 809
810 810 And one with arguments
811 811
812 812 $ hg debugwireproto --localssh --peer raw << EOF
813 813 > raw
814 814 > hello\n
815 815 > between\n
816 816 > pairs 81\n
817 817 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
818 818 > readline
819 819 > readline
820 820 > readline
821 821 > readline
822 822 > raw
823 823 > unknown\n
824 824 > foo 5\n
825 825 > \nvalue\n
826 826 > bar 3\n
827 827 > baz\n
828 828 > readline
829 829 > readline
830 830 > readline
831 831 > EOF
832 832 using raw connection to peer
833 833 i> write(104) -> 104:
834 834 i> hello\n
835 835 i> between\n
836 836 i> pairs 81\n
837 837 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
838 838 o> readline() -> 4:
839 839 o> 427\n
840 840 o> readline() -> 427:
841 841 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
842 842 o> readline() -> 2:
843 843 o> 1\n
844 844 o> readline() -> 1:
845 845 o> \n
846 846 i> write(31) -> 31:
847 847 i> unknown\n
848 848 i> foo 5\n
849 849 i> \n
850 850 i> value\n
851 851 i> bar 3\n
852 852 i> baz\n
853 853 o> readline() -> 2:
854 854 o> 0\n
855 855 o> readline() -> 2:
856 856 o> 0\n
857 857 o> readline() -> 0:
858 858
859 859 Send a valid command before the handshake
860 860
861 861 $ hg debugwireproto --localssh --peer raw << EOF
862 862 > raw
863 863 > heads\n
864 864 > readline
865 865 > raw
866 866 > hello\n
867 867 > between\n
868 868 > pairs 81\n
869 869 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
870 870 > readline
871 871 > readline
872 872 > readline
873 873 > readline
874 874 > EOF
875 875 using raw connection to peer
876 876 i> write(6) -> 6:
877 877 i> heads\n
878 878 o> readline() -> 3:
879 879 o> 41\n
880 880 i> write(104) -> 104:
881 881 i> hello\n
882 882 i> between\n
883 883 i> pairs 81\n
884 884 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
885 885 o> readline() -> 41:
886 886 o> 68986213bd4485ea51533535e3fc9e78007a711f\n
887 887 o> readline() -> 4:
888 888 o> 427\n
889 889 o> readline() -> 427:
890 890 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
891 891 o> readline() -> 2:
892 892 o> 1\n
893 893
894 894 And a variation that doesn't send the between command
895 895
896 896 $ hg debugwireproto --localssh --peer raw << EOF
897 897 > raw
898 898 > heads\n
899 899 > readline
900 900 > raw
901 901 > hello\n
902 902 > readline
903 903 > readline
904 904 > EOF
905 905 using raw connection to peer
906 906 i> write(6) -> 6:
907 907 i> heads\n
908 908 o> readline() -> 3:
909 909 o> 41\n
910 910 i> write(6) -> 6:
911 911 i> hello\n
912 912 o> readline() -> 41:
913 913 o> 68986213bd4485ea51533535e3fc9e78007a711f\n
914 914 o> readline() -> 4:
915 915 o> 427\n
916 916
917 917 Send an upgrade request to a server that doesn't support that command
918 918
919 919 $ hg debugwireproto --localssh --peer raw << EOF
920 920 > raw
921 921 > upgrade 2e82ab3f-9ce3-4b4e-8f8c-6fd1c0e9e23a proto=irrelevant1%2Cirrelevant2\n
922 922 > readline
923 923 > raw
924 924 > hello\n
925 925 > between\n
926 926 > pairs 81\n
927 927 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
928 928 > readline
929 929 > readline
930 930 > readline
931 931 > readline
932 932 > EOF
933 933 using raw connection to peer
934 934 i> write(77) -> 77:
935 935 i> upgrade 2e82ab3f-9ce3-4b4e-8f8c-6fd1c0e9e23a proto=irrelevant1%2Cirrelevant2\n
936 936 o> readline() -> 2:
937 937 o> 0\n
938 938 i> write(104) -> 104:
939 939 i> hello\n
940 940 i> between\n
941 941 i> pairs 81\n
942 942 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
943 943 o> readline() -> 4:
944 944 o> 427\n
945 945 o> readline() -> 427:
946 946 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
947 947 o> readline() -> 2:
948 948 o> 1\n
949 949 o> readline() -> 1:
950 950 o> \n
951 951
952 952 $ cd ..
953 953
954 954 $ hg --config experimental.sshpeer.advertise-v2=true --debug debugpeer ssh://user@dummy/server
955 955 running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) (no-windows !)
956 956 running * "*\tests/dummyssh" "user@dummy" "hg -R server serve --stdio" (glob) (windows !)
957 sending upgrade request: * proto=exp-ssh-v2-0001 (glob)
957 sending upgrade request: * proto=exp-ssh-v2-0002 (glob)
958 958 devel-peer-request: hello+between
959 959 devel-peer-request: pairs: 81 bytes
960 960 sending hello command
961 961 sending between command
962 962 remote: 0
963 963 remote: 427
964 964 remote: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
965 965 remote: 1
966 966 devel-peer-request: protocaps
967 967 devel-peer-request: caps: * bytes (glob)
968 968 sending protocaps command
969 969 url: ssh://user@dummy/server
970 970 local: no
971 971 pushable: yes
972 972
973 973 Enable version 2 support on server. We need to do this in hgrc because we can't
974 974 use --config with `hg serve --stdio`.
975 975
976 976 $ cat >> server/.hg/hgrc << EOF
977 977 > [experimental]
978 978 > sshserver.support-v2 = true
979 979 > EOF
980 980
981 981 Send an upgrade request to a server that supports upgrade
982 982
983 983 $ cd server
984 984
985 985 $ hg debugwireproto --localssh --peer raw << EOF
986 986 > raw
987 > upgrade this-is-some-token proto=exp-ssh-v2-0001\n
987 > upgrade this-is-some-token proto=exp-ssh-v2-0002\n
988 988 > hello\n
989 989 > between\n
990 990 > pairs 81\n
991 991 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
992 992 > readline
993 993 > readline
994 994 > readline
995 995 > EOF
996 996 using raw connection to peer
997 997 i> write(153) -> 153:
998 i> upgrade this-is-some-token proto=exp-ssh-v2-0001\n
998 i> upgrade this-is-some-token proto=exp-ssh-v2-0002\n
999 999 i> hello\n
1000 1000 i> between\n
1001 1001 i> pairs 81\n
1002 1002 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1003 1003 o> readline() -> 44:
1004 o> upgraded this-is-some-token exp-ssh-v2-0001\n
1004 o> upgraded this-is-some-token exp-ssh-v2-0002\n
1005 1005 o> readline() -> 4:
1006 1006 o> 426\n
1007 1007 o> readline() -> 427:
1008 1008 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
1009 1009
1010 1010 $ cd ..
1011 1011
1012 1012 $ hg --config experimental.sshpeer.advertise-v2=true --debug debugpeer ssh://user@dummy/server
1013 1013 running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) (no-windows !)
1014 1014 running * "*\tests/dummyssh" "user@dummy" "hg -R server serve --stdio" (glob) (windows !)
1015 sending upgrade request: * proto=exp-ssh-v2-0001 (glob)
1015 sending upgrade request: * proto=exp-ssh-v2-0002 (glob)
1016 1016 devel-peer-request: hello+between
1017 1017 devel-peer-request: pairs: 81 bytes
1018 1018 sending hello command
1019 1019 sending between command
1020 protocol upgraded to exp-ssh-v2-0001
1020 protocol upgraded to exp-ssh-v2-0002
1021 1021 remote: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
1022 1022 devel-peer-request: protocaps
1023 1023 devel-peer-request: caps: * bytes (glob)
1024 1024 sending protocaps command
1025 1025 url: ssh://user@dummy/server
1026 1026 local: no
1027 1027 pushable: yes
1028 1028
1029 1029 Verify the peer has capabilities
1030 1030
1031 1031 $ hg --config experimental.sshpeer.advertise-v2=true --debug debugcapabilities ssh://user@dummy/server
1032 1032 running * "*/tests/dummyssh" 'user@dummy' 'hg -R server serve --stdio' (glob) (no-windows !)
1033 1033 running * "*\tests/dummyssh" "user@dummy" "hg -R server serve --stdio" (glob) (windows !)
1034 sending upgrade request: * proto=exp-ssh-v2-0001 (glob)
1034 sending upgrade request: * proto=exp-ssh-v2-0002 (glob)
1035 1035 devel-peer-request: hello+between
1036 1036 devel-peer-request: pairs: 81 bytes
1037 1037 sending hello command
1038 1038 sending between command
1039 protocol upgraded to exp-ssh-v2-0001
1039 protocol upgraded to exp-ssh-v2-0002
1040 1040 remote: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
1041 1041 devel-peer-request: protocaps
1042 1042 devel-peer-request: caps: * bytes (glob)
1043 1043 sending protocaps command
1044 1044 Main capabilities:
1045 1045 batch
1046 1046 branchmap
1047 1047 $USUAL_BUNDLE2_CAPS$
1048 1048 changegroupsubset
1049 1049 getbundle
1050 1050 known
1051 1051 lookup
1052 1052 protocaps
1053 1053 pushkey
1054 1054 streamreqs=generaldelta,revlogv1
1055 1055 unbundle=HG10GZ,HG10BZ,HG10UN
1056 1056 unbundlehash
1057 1057 Bundle2 capabilities:
1058 1058 HG20
1059 1059 bookmarks
1060 1060 changegroup
1061 1061 01
1062 1062 02
1063 1063 digests
1064 1064 md5
1065 1065 sha1
1066 1066 sha512
1067 1067 error
1068 1068 abort
1069 1069 unsupportedcontent
1070 1070 pushraced
1071 1071 pushkey
1072 1072 hgtagsfnodes
1073 1073 listkeys
1074 1074 phases
1075 1075 heads
1076 1076 pushkey
1077 1077 remote-changegroup
1078 1078 http
1079 1079 https
1080 1080 rev-branch-cache
1081 1081 stream
1082 1082 v2
1083 1083
1084 1084 Command after upgrade to version 2 is processed
1085 1085
1086 1086 $ cd server
1087 1087
1088 1088 $ hg debugwireproto --localssh --peer raw << EOF
1089 1089 > raw
1090 > upgrade this-is-some-token proto=exp-ssh-v2-0001\n
1090 > upgrade this-is-some-token proto=exp-ssh-v2-0002\n
1091 1091 > hello\n
1092 1092 > between\n
1093 1093 > pairs 81\n
1094 1094 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1095 1095 > readline
1096 1096 > readline
1097 1097 > readline
1098 1098 > raw
1099 1099 > hello\n
1100 1100 > readline
1101 1101 > readline
1102 1102 > EOF
1103 1103 using raw connection to peer
1104 1104 i> write(153) -> 153:
1105 i> upgrade this-is-some-token proto=exp-ssh-v2-0001\n
1105 i> upgrade this-is-some-token proto=exp-ssh-v2-0002\n
1106 1106 i> hello\n
1107 1107 i> between\n
1108 1108 i> pairs 81\n
1109 1109 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1110 1110 o> readline() -> 44:
1111 o> upgraded this-is-some-token exp-ssh-v2-0001\n
1111 o> upgraded this-is-some-token exp-ssh-v2-0002\n
1112 1112 o> readline() -> 4:
1113 1113 o> 426\n
1114 1114 o> readline() -> 427:
1115 1115 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
1116 1116 i> write(6) -> 6:
1117 1117 i> hello\n
1118 1118 o> readline() -> 4:
1119 1119 o> 411\n
1120 1120 o> readline() -> 411:
1121 1121 o> capabilities: branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
1122 1122
1123 1123 Multiple upgrades is not allowed
1124 1124
1125 1125 $ hg debugwireproto --localssh --peer raw << EOF
1126 1126 > raw
1127 > upgrade this-is-some-token proto=exp-ssh-v2-0001\n
1127 > upgrade this-is-some-token proto=exp-ssh-v2-0002\n
1128 1128 > hello\n
1129 1129 > between\n
1130 1130 > pairs 81\n
1131 1131 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1132 1132 > readline
1133 1133 > readline
1134 1134 > readline
1135 1135 > raw
1136 1136 > upgrade another-token proto=irrelevant\n
1137 1137 > hello\n
1138 1138 > readline
1139 1139 > readavailable
1140 1140 > EOF
1141 1141 using raw connection to peer
1142 1142 i> write(153) -> 153:
1143 i> upgrade this-is-some-token proto=exp-ssh-v2-0001\n
1143 i> upgrade this-is-some-token proto=exp-ssh-v2-0002\n
1144 1144 i> hello\n
1145 1145 i> between\n
1146 1146 i> pairs 81\n
1147 1147 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1148 1148 o> readline() -> 44:
1149 o> upgraded this-is-some-token exp-ssh-v2-0001\n
1149 o> upgraded this-is-some-token exp-ssh-v2-0002\n
1150 1150 o> readline() -> 4:
1151 1151 o> 426\n
1152 1152 o> readline() -> 427:
1153 1153 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
1154 1154 i> write(45) -> 45:
1155 1155 i> upgrade another-token proto=irrelevant\n
1156 1156 i> hello\n
1157 1157 o> readline() -> 1:
1158 1158 o> \n
1159 1159 e> read(-1) -> 42:
1160 1160 e> cannot upgrade protocols multiple times\n
1161 1161 e> -\n
1162 1162
1163 1163 Malformed upgrade request line (not exactly 3 space delimited tokens)
1164 1164
1165 1165 $ hg debugwireproto --localssh --peer raw << EOF
1166 1166 > raw
1167 1167 > upgrade\n
1168 1168 > readline
1169 1169 > EOF
1170 1170 using raw connection to peer
1171 1171 i> write(8) -> 8:
1172 1172 i> upgrade\n
1173 1173 o> readline() -> 2:
1174 1174 o> 0\n
1175 1175
1176 1176 $ hg debugwireproto --localssh --peer raw << EOF
1177 1177 > raw
1178 1178 > upgrade token\n
1179 1179 > readline
1180 1180 > EOF
1181 1181 using raw connection to peer
1182 1182 i> write(14) -> 14:
1183 1183 i> upgrade token\n
1184 1184 o> readline() -> 2:
1185 1185 o> 0\n
1186 1186
1187 1187 $ hg debugwireproto --localssh --peer raw << EOF
1188 1188 > raw
1189 1189 > upgrade token foo=bar extra-token\n
1190 1190 > readline
1191 1191 > EOF
1192 1192 using raw connection to peer
1193 1193 i> write(34) -> 34:
1194 1194 i> upgrade token foo=bar extra-token\n
1195 1195 o> readline() -> 2:
1196 1196 o> 0\n
1197 1197
1198 1198 Upgrade request to unsupported protocol is ignored
1199 1199
1200 1200 $ hg debugwireproto --localssh --peer raw << EOF
1201 1201 > raw
1202 1202 > upgrade this-is-some-token proto=unknown1,unknown2\n
1203 1203 > readline
1204 1204 > raw
1205 1205 > hello\n
1206 1206 > readline
1207 1207 > readline
1208 1208 > raw
1209 1209 > between\n
1210 1210 > pairs 81\n
1211 1211 > 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1212 1212 > readline
1213 1213 > readline
1214 1214 > EOF
1215 1215 using raw connection to peer
1216 1216 i> write(51) -> 51:
1217 1217 i> upgrade this-is-some-token proto=unknown1,unknown2\n
1218 1218 o> readline() -> 2:
1219 1219 o> 0\n
1220 1220 i> write(6) -> 6:
1221 1221 i> hello\n
1222 1222 o> readline() -> 4:
1223 1223 o> 427\n
1224 1224 o> readline() -> 427:
1225 1225 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
1226 1226 i> write(98) -> 98:
1227 1227 i> between\n
1228 1228 i> pairs 81\n
1229 1229 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1230 1230 o> readline() -> 2:
1231 1231 o> 1\n
1232 1232 o> readline() -> 1:
1233 1233 o> \n
1234 1234
1235 1235 Upgrade request must be followed by hello + between
1236 1236
1237 1237 $ hg debugwireproto --localssh --peer raw << EOF
1238 1238 > raw
1239 > upgrade token proto=exp-ssh-v2-0001\n
1239 > upgrade token proto=exp-ssh-v2-0002\n
1240 1240 > invalid\n
1241 1241 > readline
1242 1242 > readavailable
1243 1243 > EOF
1244 1244 using raw connection to peer
1245 1245 i> write(44) -> 44:
1246 i> upgrade token proto=exp-ssh-v2-0001\n
1246 i> upgrade token proto=exp-ssh-v2-0002\n
1247 1247 i> invalid\n
1248 1248 o> readline() -> 1:
1249 1249 o> \n
1250 1250 e> read(-1) -> 46:
1251 1251 e> malformed handshake protocol: missing hello\n
1252 1252 e> -\n
1253 1253
1254 1254 $ hg debugwireproto --localssh --peer raw << EOF
1255 1255 > raw
1256 > upgrade token proto=exp-ssh-v2-0001\n
1256 > upgrade token proto=exp-ssh-v2-0002\n
1257 1257 > hello\n
1258 1258 > invalid\n
1259 1259 > readline
1260 1260 > readavailable
1261 1261 > EOF
1262 1262 using raw connection to peer
1263 1263 i> write(50) -> 50:
1264 i> upgrade token proto=exp-ssh-v2-0001\n
1264 i> upgrade token proto=exp-ssh-v2-0002\n
1265 1265 i> hello\n
1266 1266 i> invalid\n
1267 1267 o> readline() -> 1:
1268 1268 o> \n
1269 1269 e> read(-1) -> 48:
1270 1270 e> malformed handshake protocol: missing between\n
1271 1271 e> -\n
1272 1272
1273 1273 $ hg debugwireproto --localssh --peer raw << EOF
1274 1274 > raw
1275 > upgrade token proto=exp-ssh-v2-0001\n
1275 > upgrade token proto=exp-ssh-v2-0002\n
1276 1276 > hello\n
1277 1277 > between\n
1278 1278 > invalid\n
1279 1279 > readline
1280 1280 > readavailable
1281 1281 > EOF
1282 1282 using raw connection to peer
1283 1283 i> write(58) -> 58:
1284 i> upgrade token proto=exp-ssh-v2-0001\n
1284 i> upgrade token proto=exp-ssh-v2-0002\n
1285 1285 i> hello\n
1286 1286 i> between\n
1287 1287 i> invalid\n
1288 1288 o> readline() -> 1:
1289 1289 o> \n
1290 1290 e> read(-1) -> 49:
1291 1291 e> malformed handshake protocol: missing pairs 81\n
1292 1292 e> -\n
1293 1293
1294 1294 Legacy commands are not exposed to version 2 of protocol
1295 1295
1296 1296 TODO re-enable these once we're back to actually using v2 commands
1297 1297
1298 1298 $ hg --config experimental.sshpeer.advertise-v2=true debugwireproto --localssh << EOF
1299 1299 > command branches
1300 1300 > nodes 0000000000000000000000000000000000000000
1301 1301 > EOF
1302 1302 creating ssh peer from handshake results
1303 1303 sending branches command
1304 1304 response:
1305 1305
1306 1306 $ hg --config experimental.sshpeer.advertise-v2=true debugwireproto --localssh << EOF
1307 1307 > command changegroup
1308 1308 > roots 0000000000000000000000000000000000000000
1309 1309 > EOF
1310 1310 creating ssh peer from handshake results
1311 1311 sending changegroup command
1312 1312 response:
1313 1313
1314 1314 $ hg --config experimental.sshpeer.advertise-v2=true debugwireproto --localssh << EOF
1315 1315 > command changegroupsubset
1316 1316 > bases 0000000000000000000000000000000000000000
1317 1317 > heads 0000000000000000000000000000000000000000
1318 1318 > EOF
1319 1319 creating ssh peer from handshake results
1320 1320 sending changegroupsubset command
1321 1321 response:
1322 1322
1323 1323 $ cd ..
1324 1324
1325 1325 Test listkeys for listing namespaces
1326 1326
1327 1327 $ hg init empty
1328 1328 $ cd empty
1329 1329 $ debugwireproto << EOF
1330 1330 > command listkeys
1331 1331 > namespace namespaces
1332 1332 > EOF
1333 1333 testing ssh1
1334 1334 creating ssh peer from handshake results
1335 1335 i> write(104) -> 104:
1336 1336 i> hello\n
1337 1337 i> between\n
1338 1338 i> pairs 81\n
1339 1339 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1340 1340 i> flush() -> None
1341 1341 o> readline() -> 4:
1342 1342 o> 427\n
1343 1343 o> readline() -> 427:
1344 1344 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
1345 1345 o> readline() -> 2:
1346 1346 o> 1\n
1347 1347 o> readline() -> 1:
1348 1348 o> \n
1349 1349 sending listkeys command
1350 1350 i> write(9) -> 9:
1351 1351 i> listkeys\n
1352 1352 i> write(13) -> 13:
1353 1353 i> namespace 10\n
1354 1354 i> write(10) -> 10: namespaces
1355 1355 i> flush() -> None
1356 1356 o> bufferedreadline() -> 3:
1357 1357 o> 30\n
1358 1358 o> bufferedread(30) -> 30:
1359 1359 o> bookmarks\t\n
1360 1360 o> namespaces\t\n
1361 1361 o> phases\t
1362 1362 response: {
1363 1363 b'bookmarks': b'',
1364 1364 b'namespaces': b'',
1365 1365 b'phases': b''
1366 1366 }
1367 1367
1368 1368 testing ssh2
1369 1369 creating ssh peer from handshake results
1370 1370 i> write(171) -> 171:
1371 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1371 i> upgrade * proto=exp-ssh-v2-0002\n (glob)
1372 1372 i> hello\n
1373 1373 i> between\n
1374 1374 i> pairs 81\n
1375 1375 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1376 1376 i> flush() -> None
1377 1377 o> readline() -> 62:
1378 o> upgraded * exp-ssh-v2-0001\n (glob)
1378 o> upgraded * exp-ssh-v2-0002\n (glob)
1379 1379 o> readline() -> 4:
1380 1380 o> 426\n
1381 1381 o> read(426) -> 426: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
1382 1382 o> read(1) -> 1:
1383 1383 o> \n
1384 1384 sending listkeys command
1385 1385 i> write(9) -> 9:
1386 1386 i> listkeys\n
1387 1387 i> write(13) -> 13:
1388 1388 i> namespace 10\n
1389 1389 i> write(10) -> 10: namespaces
1390 1390 i> flush() -> None
1391 1391 o> bufferedreadline() -> 3:
1392 1392 o> 30\n
1393 1393 o> bufferedread(30) -> 30:
1394 1394 o> bookmarks\t\n
1395 1395 o> namespaces\t\n
1396 1396 o> phases\t
1397 1397 response: {
1398 1398 b'bookmarks': b'',
1399 1399 b'namespaces': b'',
1400 1400 b'phases': b''
1401 1401 }
1402 1402
1403 1403 $ cd ..
1404 1404
1405 1405 Test listkeys for bookmarks
1406 1406
1407 1407 $ hg init bookmarkrepo
1408 1408 $ cd bookmarkrepo
1409 1409 $ echo 0 > foo
1410 1410 $ hg add foo
1411 1411 $ hg -q commit -m initial
1412 1412 $ echo 1 > foo
1413 1413 $ hg commit -m second
1414 1414
1415 1415 With no bookmarks set
1416 1416
1417 1417 $ debugwireproto << EOF
1418 1418 > command listkeys
1419 1419 > namespace bookmarks
1420 1420 > EOF
1421 1421 testing ssh1
1422 1422 creating ssh peer from handshake results
1423 1423 i> write(104) -> 104:
1424 1424 i> hello\n
1425 1425 i> between\n
1426 1426 i> pairs 81\n
1427 1427 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1428 1428 i> flush() -> None
1429 1429 o> readline() -> 4:
1430 1430 o> 427\n
1431 1431 o> readline() -> 427:
1432 1432 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
1433 1433 o> readline() -> 2:
1434 1434 o> 1\n
1435 1435 o> readline() -> 1:
1436 1436 o> \n
1437 1437 sending listkeys command
1438 1438 i> write(9) -> 9:
1439 1439 i> listkeys\n
1440 1440 i> write(12) -> 12:
1441 1441 i> namespace 9\n
1442 1442 i> write(9) -> 9: bookmarks
1443 1443 i> flush() -> None
1444 1444 o> bufferedreadline() -> 2:
1445 1445 o> 0\n
1446 1446 response: {}
1447 1447
1448 1448 testing ssh2
1449 1449 creating ssh peer from handshake results
1450 1450 i> write(171) -> 171:
1451 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1451 i> upgrade * proto=exp-ssh-v2-0002\n (glob)
1452 1452 i> hello\n
1453 1453 i> between\n
1454 1454 i> pairs 81\n
1455 1455 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1456 1456 i> flush() -> None
1457 1457 o> readline() -> 62:
1458 o> upgraded * exp-ssh-v2-0001\n (glob)
1458 o> upgraded * exp-ssh-v2-0002\n (glob)
1459 1459 o> readline() -> 4:
1460 1460 o> 426\n
1461 1461 o> read(426) -> 426: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
1462 1462 o> read(1) -> 1:
1463 1463 o> \n
1464 1464 sending listkeys command
1465 1465 i> write(9) -> 9:
1466 1466 i> listkeys\n
1467 1467 i> write(12) -> 12:
1468 1468 i> namespace 9\n
1469 1469 i> write(9) -> 9: bookmarks
1470 1470 i> flush() -> None
1471 1471 o> bufferedreadline() -> 2:
1472 1472 o> 0\n
1473 1473 response: {}
1474 1474
1475 1475 With a single bookmark set
1476 1476
1477 1477 $ hg book -r 0 bookA
1478 1478 $ debugwireproto << EOF
1479 1479 > command listkeys
1480 1480 > namespace bookmarks
1481 1481 > EOF
1482 1482 testing ssh1
1483 1483 creating ssh peer from handshake results
1484 1484 i> write(104) -> 104:
1485 1485 i> hello\n
1486 1486 i> between\n
1487 1487 i> pairs 81\n
1488 1488 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1489 1489 i> flush() -> None
1490 1490 o> readline() -> 4:
1491 1491 o> 427\n
1492 1492 o> readline() -> 427:
1493 1493 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
1494 1494 o> readline() -> 2:
1495 1495 o> 1\n
1496 1496 o> readline() -> 1:
1497 1497 o> \n
1498 1498 sending listkeys command
1499 1499 i> write(9) -> 9:
1500 1500 i> listkeys\n
1501 1501 i> write(12) -> 12:
1502 1502 i> namespace 9\n
1503 1503 i> write(9) -> 9: bookmarks
1504 1504 i> flush() -> None
1505 1505 o> bufferedreadline() -> 3:
1506 1506 o> 46\n
1507 1507 o> bufferedread(46) -> 46: bookA\t68986213bd4485ea51533535e3fc9e78007a711f
1508 1508 response: {
1509 1509 b'bookA': b'68986213bd4485ea51533535e3fc9e78007a711f'
1510 1510 }
1511 1511
1512 1512 testing ssh2
1513 1513 creating ssh peer from handshake results
1514 1514 i> write(171) -> 171:
1515 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1515 i> upgrade * proto=exp-ssh-v2-0002\n (glob)
1516 1516 i> hello\n
1517 1517 i> between\n
1518 1518 i> pairs 81\n
1519 1519 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1520 1520 i> flush() -> None
1521 1521 o> readline() -> 62:
1522 o> upgraded * exp-ssh-v2-0001\n (glob)
1522 o> upgraded * exp-ssh-v2-0002\n (glob)
1523 1523 o> readline() -> 4:
1524 1524 o> 426\n
1525 1525 o> read(426) -> 426: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
1526 1526 o> read(1) -> 1:
1527 1527 o> \n
1528 1528 sending listkeys command
1529 1529 i> write(9) -> 9:
1530 1530 i> listkeys\n
1531 1531 i> write(12) -> 12:
1532 1532 i> namespace 9\n
1533 1533 i> write(9) -> 9: bookmarks
1534 1534 i> flush() -> None
1535 1535 o> bufferedreadline() -> 3:
1536 1536 o> 46\n
1537 1537 o> bufferedread(46) -> 46: bookA\t68986213bd4485ea51533535e3fc9e78007a711f
1538 1538 response: {
1539 1539 b'bookA': b'68986213bd4485ea51533535e3fc9e78007a711f'
1540 1540 }
1541 1541
1542 1542 With multiple bookmarks set
1543 1543
1544 1544 $ hg book -r 1 bookB
1545 1545 $ debugwireproto << EOF
1546 1546 > command listkeys
1547 1547 > namespace bookmarks
1548 1548 > EOF
1549 1549 testing ssh1
1550 1550 creating ssh peer from handshake results
1551 1551 i> write(104) -> 104:
1552 1552 i> hello\n
1553 1553 i> between\n
1554 1554 i> pairs 81\n
1555 1555 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1556 1556 i> flush() -> None
1557 1557 o> readline() -> 4:
1558 1558 o> 427\n
1559 1559 o> readline() -> 427:
1560 1560 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
1561 1561 o> readline() -> 2:
1562 1562 o> 1\n
1563 1563 o> readline() -> 1:
1564 1564 o> \n
1565 1565 sending listkeys command
1566 1566 i> write(9) -> 9:
1567 1567 i> listkeys\n
1568 1568 i> write(12) -> 12:
1569 1569 i> namespace 9\n
1570 1570 i> write(9) -> 9: bookmarks
1571 1571 i> flush() -> None
1572 1572 o> bufferedreadline() -> 3:
1573 1573 o> 93\n
1574 1574 o> bufferedread(93) -> 93:
1575 1575 o> bookA\t68986213bd4485ea51533535e3fc9e78007a711f\n
1576 1576 o> bookB\t1880f3755e2e52e3199e0ee5638128b08642f34d
1577 1577 response: {
1578 1578 b'bookA': b'68986213bd4485ea51533535e3fc9e78007a711f',
1579 1579 b'bookB': b'1880f3755e2e52e3199e0ee5638128b08642f34d'
1580 1580 }
1581 1581
1582 1582 testing ssh2
1583 1583 creating ssh peer from handshake results
1584 1584 i> write(171) -> 171:
1585 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1585 i> upgrade * proto=exp-ssh-v2-0002\n (glob)
1586 1586 i> hello\n
1587 1587 i> between\n
1588 1588 i> pairs 81\n
1589 1589 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1590 1590 i> flush() -> None
1591 1591 o> readline() -> 62:
1592 o> upgraded * exp-ssh-v2-0001\n (glob)
1592 o> upgraded * exp-ssh-v2-0002\n (glob)
1593 1593 o> readline() -> 4:
1594 1594 o> 426\n
1595 1595 o> read(426) -> 426: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
1596 1596 o> read(1) -> 1:
1597 1597 o> \n
1598 1598 sending listkeys command
1599 1599 i> write(9) -> 9:
1600 1600 i> listkeys\n
1601 1601 i> write(12) -> 12:
1602 1602 i> namespace 9\n
1603 1603 i> write(9) -> 9: bookmarks
1604 1604 i> flush() -> None
1605 1605 o> bufferedreadline() -> 3:
1606 1606 o> 93\n
1607 1607 o> bufferedread(93) -> 93:
1608 1608 o> bookA\t68986213bd4485ea51533535e3fc9e78007a711f\n
1609 1609 o> bookB\t1880f3755e2e52e3199e0ee5638128b08642f34d
1610 1610 response: {
1611 1611 b'bookA': b'68986213bd4485ea51533535e3fc9e78007a711f',
1612 1612 b'bookB': b'1880f3755e2e52e3199e0ee5638128b08642f34d'
1613 1613 }
1614 1614
1615 1615 Test pushkey for bookmarks
1616 1616
1617 1617 $ debugwireproto << EOF
1618 1618 > command pushkey
1619 1619 > namespace bookmarks
1620 1620 > key remote
1621 1621 > old
1622 1622 > new 68986213bd4485ea51533535e3fc9e78007a711f
1623 1623 > EOF
1624 1624 testing ssh1
1625 1625 creating ssh peer from handshake results
1626 1626 i> write(104) -> 104:
1627 1627 i> hello\n
1628 1628 i> between\n
1629 1629 i> pairs 81\n
1630 1630 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1631 1631 i> flush() -> None
1632 1632 o> readline() -> 4:
1633 1633 o> 427\n
1634 1634 o> readline() -> 427:
1635 1635 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
1636 1636 o> readline() -> 2:
1637 1637 o> 1\n
1638 1638 o> readline() -> 1:
1639 1639 o> \n
1640 1640 sending pushkey command
1641 1641 i> write(8) -> 8:
1642 1642 i> pushkey\n
1643 1643 i> write(6) -> 6:
1644 1644 i> key 6\n
1645 1645 i> write(6) -> 6: remote
1646 1646 i> write(12) -> 12:
1647 1647 i> namespace 9\n
1648 1648 i> write(9) -> 9: bookmarks
1649 1649 i> write(7) -> 7:
1650 1650 i> new 40\n
1651 1651 i> write(40) -> 40: 68986213bd4485ea51533535e3fc9e78007a711f
1652 1652 i> write(6) -> 6:
1653 1653 i> old 0\n
1654 1654 i> flush() -> None
1655 1655 o> bufferedreadline() -> 2:
1656 1656 o> 2\n
1657 1657 o> bufferedread(2) -> 2:
1658 1658 o> 1\n
1659 1659 response: True
1660 1660
1661 1661 testing ssh2
1662 1662 creating ssh peer from handshake results
1663 1663 i> write(171) -> 171:
1664 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1664 i> upgrade * proto=exp-ssh-v2-0002\n (glob)
1665 1665 i> hello\n
1666 1666 i> between\n
1667 1667 i> pairs 81\n
1668 1668 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1669 1669 i> flush() -> None
1670 1670 o> readline() -> 62:
1671 o> upgraded * exp-ssh-v2-0001\n (glob)
1671 o> upgraded * exp-ssh-v2-0002\n (glob)
1672 1672 o> readline() -> 4:
1673 1673 o> 426\n
1674 1674 o> read(426) -> 426: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
1675 1675 o> read(1) -> 1:
1676 1676 o> \n
1677 1677 sending pushkey command
1678 1678 i> write(8) -> 8:
1679 1679 i> pushkey\n
1680 1680 i> write(6) -> 6:
1681 1681 i> key 6\n
1682 1682 i> write(6) -> 6: remote
1683 1683 i> write(12) -> 12:
1684 1684 i> namespace 9\n
1685 1685 i> write(9) -> 9: bookmarks
1686 1686 i> write(7) -> 7:
1687 1687 i> new 40\n
1688 1688 i> write(40) -> 40: 68986213bd4485ea51533535e3fc9e78007a711f
1689 1689 i> write(6) -> 6:
1690 1690 i> old 0\n
1691 1691 i> flush() -> None
1692 1692 o> bufferedreadline() -> 2:
1693 1693 o> 2\n
1694 1694 o> bufferedread(2) -> 2:
1695 1695 o> 1\n
1696 1696 response: True
1697 1697
1698 1698 $ hg bookmarks
1699 1699 bookA 0:68986213bd44
1700 1700 bookB 1:1880f3755e2e
1701 1701 remote 0:68986213bd44
1702 1702
1703 1703 $ cd ..
1704 1704
1705 1705 Test listkeys for phases
1706 1706
1707 1707 $ hg init phasesrepo
1708 1708 $ cd phasesrepo
1709 1709
1710 1710 Phases on empty repo
1711 1711
1712 1712 $ debugwireproto << EOF
1713 1713 > command listkeys
1714 1714 > namespace phases
1715 1715 > EOF
1716 1716 testing ssh1
1717 1717 creating ssh peer from handshake results
1718 1718 i> write(104) -> 104:
1719 1719 i> hello\n
1720 1720 i> between\n
1721 1721 i> pairs 81\n
1722 1722 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1723 1723 i> flush() -> None
1724 1724 o> readline() -> 4:
1725 1725 o> 427\n
1726 1726 o> readline() -> 427:
1727 1727 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
1728 1728 o> readline() -> 2:
1729 1729 o> 1\n
1730 1730 o> readline() -> 1:
1731 1731 o> \n
1732 1732 sending listkeys command
1733 1733 i> write(9) -> 9:
1734 1734 i> listkeys\n
1735 1735 i> write(12) -> 12:
1736 1736 i> namespace 6\n
1737 1737 i> write(6) -> 6: phases
1738 1738 i> flush() -> None
1739 1739 o> bufferedreadline() -> 3:
1740 1740 o> 15\n
1741 1741 o> bufferedread(15) -> 15: publishing\tTrue
1742 1742 response: {
1743 1743 b'publishing': b'True'
1744 1744 }
1745 1745
1746 1746 testing ssh2
1747 1747 creating ssh peer from handshake results
1748 1748 i> write(171) -> 171:
1749 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1749 i> upgrade * proto=exp-ssh-v2-0002\n (glob)
1750 1750 i> hello\n
1751 1751 i> between\n
1752 1752 i> pairs 81\n
1753 1753 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1754 1754 i> flush() -> None
1755 1755 o> readline() -> 62:
1756 o> upgraded * exp-ssh-v2-0001\n (glob)
1756 o> upgraded * exp-ssh-v2-0002\n (glob)
1757 1757 o> readline() -> 4:
1758 1758 o> 426\n
1759 1759 o> read(426) -> 426: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
1760 1760 o> read(1) -> 1:
1761 1761 o> \n
1762 1762 sending listkeys command
1763 1763 i> write(9) -> 9:
1764 1764 i> listkeys\n
1765 1765 i> write(12) -> 12:
1766 1766 i> namespace 6\n
1767 1767 i> write(6) -> 6: phases
1768 1768 i> flush() -> None
1769 1769 o> bufferedreadline() -> 3:
1770 1770 o> 15\n
1771 1771 o> bufferedread(15) -> 15: publishing\tTrue
1772 1772 response: {
1773 1773 b'publishing': b'True'
1774 1774 }
1775 1775
1776 1776 Create some commits
1777 1777
1778 1778 $ echo 0 > foo
1779 1779 $ hg add foo
1780 1780 $ hg -q commit -m initial
1781 1781 $ hg phase --public
1782 1782 $ echo 1 > foo
1783 1783 $ hg commit -m 'head 1 commit 1'
1784 1784 $ echo 2 > foo
1785 1785 $ hg commit -m 'head 1 commit 2'
1786 1786 $ hg -q up 0
1787 1787 $ echo 1a > foo
1788 1788 $ hg commit -m 'head 2 commit 1'
1789 1789 created new head
1790 1790 $ echo 2a > foo
1791 1791 $ hg commit -m 'head 2 commit 2'
1792 1792
1793 1793 Two draft heads
1794 1794
1795 1795 $ debugwireproto << EOF
1796 1796 > command listkeys
1797 1797 > namespace phases
1798 1798 > EOF
1799 1799 testing ssh1
1800 1800 creating ssh peer from handshake results
1801 1801 i> write(104) -> 104:
1802 1802 i> hello\n
1803 1803 i> between\n
1804 1804 i> pairs 81\n
1805 1805 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1806 1806 i> flush() -> None
1807 1807 o> readline() -> 4:
1808 1808 o> 427\n
1809 1809 o> readline() -> 427:
1810 1810 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
1811 1811 o> readline() -> 2:
1812 1812 o> 1\n
1813 1813 o> readline() -> 1:
1814 1814 o> \n
1815 1815 sending listkeys command
1816 1816 i> write(9) -> 9:
1817 1817 i> listkeys\n
1818 1818 i> write(12) -> 12:
1819 1819 i> namespace 6\n
1820 1820 i> write(6) -> 6: phases
1821 1821 i> flush() -> None
1822 1822 o> bufferedreadline() -> 4:
1823 1823 o> 101\n
1824 1824 o> bufferedread(101) -> 101:
1825 1825 o> 20b8a89289d80036e6c4e87c2083e3bea1586637\t1\n
1826 1826 o> c4750011d906c18ea2f0527419cbc1a544435150\t1\n
1827 1827 o> publishing\tTrue
1828 1828 response: {
1829 1829 b'20b8a89289d80036e6c4e87c2083e3bea1586637': b'1',
1830 1830 b'c4750011d906c18ea2f0527419cbc1a544435150': b'1',
1831 1831 b'publishing': b'True'
1832 1832 }
1833 1833
1834 1834 testing ssh2
1835 1835 creating ssh peer from handshake results
1836 1836 i> write(171) -> 171:
1837 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1837 i> upgrade * proto=exp-ssh-v2-0002\n (glob)
1838 1838 i> hello\n
1839 1839 i> between\n
1840 1840 i> pairs 81\n
1841 1841 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1842 1842 i> flush() -> None
1843 1843 o> readline() -> 62:
1844 o> upgraded * exp-ssh-v2-0001\n (glob)
1844 o> upgraded * exp-ssh-v2-0002\n (glob)
1845 1845 o> readline() -> 4:
1846 1846 o> 426\n
1847 1847 o> read(426) -> 426: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
1848 1848 o> read(1) -> 1:
1849 1849 o> \n
1850 1850 sending listkeys command
1851 1851 i> write(9) -> 9:
1852 1852 i> listkeys\n
1853 1853 i> write(12) -> 12:
1854 1854 i> namespace 6\n
1855 1855 i> write(6) -> 6: phases
1856 1856 i> flush() -> None
1857 1857 o> bufferedreadline() -> 4:
1858 1858 o> 101\n
1859 1859 o> bufferedread(101) -> 101:
1860 1860 o> 20b8a89289d80036e6c4e87c2083e3bea1586637\t1\n
1861 1861 o> c4750011d906c18ea2f0527419cbc1a544435150\t1\n
1862 1862 o> publishing\tTrue
1863 1863 response: {
1864 1864 b'20b8a89289d80036e6c4e87c2083e3bea1586637': b'1',
1865 1865 b'c4750011d906c18ea2f0527419cbc1a544435150': b'1',
1866 1866 b'publishing': b'True'
1867 1867 }
1868 1868
1869 1869 Single draft head
1870 1870
1871 1871 $ hg phase --public -r 2
1872 1872 $ debugwireproto << EOF
1873 1873 > command listkeys
1874 1874 > namespace phases
1875 1875 > EOF
1876 1876 testing ssh1
1877 1877 creating ssh peer from handshake results
1878 1878 i> write(104) -> 104:
1879 1879 i> hello\n
1880 1880 i> between\n
1881 1881 i> pairs 81\n
1882 1882 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1883 1883 i> flush() -> None
1884 1884 o> readline() -> 4:
1885 1885 o> 427\n
1886 1886 o> readline() -> 427:
1887 1887 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
1888 1888 o> readline() -> 2:
1889 1889 o> 1\n
1890 1890 o> readline() -> 1:
1891 1891 o> \n
1892 1892 sending listkeys command
1893 1893 i> write(9) -> 9:
1894 1894 i> listkeys\n
1895 1895 i> write(12) -> 12:
1896 1896 i> namespace 6\n
1897 1897 i> write(6) -> 6: phases
1898 1898 i> flush() -> None
1899 1899 o> bufferedreadline() -> 3:
1900 1900 o> 58\n
1901 1901 o> bufferedread(58) -> 58:
1902 1902 o> c4750011d906c18ea2f0527419cbc1a544435150\t1\n
1903 1903 o> publishing\tTrue
1904 1904 response: {
1905 1905 b'c4750011d906c18ea2f0527419cbc1a544435150': b'1',
1906 1906 b'publishing': b'True'
1907 1907 }
1908 1908
1909 1909 testing ssh2
1910 1910 creating ssh peer from handshake results
1911 1911 i> write(171) -> 171:
1912 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1912 i> upgrade * proto=exp-ssh-v2-0002\n (glob)
1913 1913 i> hello\n
1914 1914 i> between\n
1915 1915 i> pairs 81\n
1916 1916 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1917 1917 i> flush() -> None
1918 1918 o> readline() -> 62:
1919 o> upgraded * exp-ssh-v2-0001\n (glob)
1919 o> upgraded * exp-ssh-v2-0002\n (glob)
1920 1920 o> readline() -> 4:
1921 1921 o> 426\n
1922 1922 o> read(426) -> 426: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
1923 1923 o> read(1) -> 1:
1924 1924 o> \n
1925 1925 sending listkeys command
1926 1926 i> write(9) -> 9:
1927 1927 i> listkeys\n
1928 1928 i> write(12) -> 12:
1929 1929 i> namespace 6\n
1930 1930 i> write(6) -> 6: phases
1931 1931 i> flush() -> None
1932 1932 o> bufferedreadline() -> 3:
1933 1933 o> 58\n
1934 1934 o> bufferedread(58) -> 58:
1935 1935 o> c4750011d906c18ea2f0527419cbc1a544435150\t1\n
1936 1936 o> publishing\tTrue
1937 1937 response: {
1938 1938 b'c4750011d906c18ea2f0527419cbc1a544435150': b'1',
1939 1939 b'publishing': b'True'
1940 1940 }
1941 1941
1942 1942 All public heads
1943 1943
1944 1944 $ hg phase --public -r 4
1945 1945 $ debugwireproto << EOF
1946 1946 > command listkeys
1947 1947 > namespace phases
1948 1948 > EOF
1949 1949 testing ssh1
1950 1950 creating ssh peer from handshake results
1951 1951 i> write(104) -> 104:
1952 1952 i> hello\n
1953 1953 i> between\n
1954 1954 i> pairs 81\n
1955 1955 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1956 1956 i> flush() -> None
1957 1957 o> readline() -> 4:
1958 1958 o> 427\n
1959 1959 o> readline() -> 427:
1960 1960 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
1961 1961 o> readline() -> 2:
1962 1962 o> 1\n
1963 1963 o> readline() -> 1:
1964 1964 o> \n
1965 1965 sending listkeys command
1966 1966 i> write(9) -> 9:
1967 1967 i> listkeys\n
1968 1968 i> write(12) -> 12:
1969 1969 i> namespace 6\n
1970 1970 i> write(6) -> 6: phases
1971 1971 i> flush() -> None
1972 1972 o> bufferedreadline() -> 3:
1973 1973 o> 15\n
1974 1974 o> bufferedread(15) -> 15: publishing\tTrue
1975 1975 response: {
1976 1976 b'publishing': b'True'
1977 1977 }
1978 1978
1979 1979 testing ssh2
1980 1980 creating ssh peer from handshake results
1981 1981 i> write(171) -> 171:
1982 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
1982 i> upgrade * proto=exp-ssh-v2-0002\n (glob)
1983 1983 i> hello\n
1984 1984 i> between\n
1985 1985 i> pairs 81\n
1986 1986 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
1987 1987 i> flush() -> None
1988 1988 o> readline() -> 62:
1989 o> upgraded * exp-ssh-v2-0001\n (glob)
1989 o> upgraded * exp-ssh-v2-0002\n (glob)
1990 1990 o> readline() -> 4:
1991 1991 o> 426\n
1992 1992 o> read(426) -> 426: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
1993 1993 o> read(1) -> 1:
1994 1994 o> \n
1995 1995 sending listkeys command
1996 1996 i> write(9) -> 9:
1997 1997 i> listkeys\n
1998 1998 i> write(12) -> 12:
1999 1999 i> namespace 6\n
2000 2000 i> write(6) -> 6: phases
2001 2001 i> flush() -> None
2002 2002 o> bufferedreadline() -> 3:
2003 2003 o> 15\n
2004 2004 o> bufferedread(15) -> 15: publishing\tTrue
2005 2005 response: {
2006 2006 b'publishing': b'True'
2007 2007 }
2008 2008
2009 2009 Setting public phase via pushkey
2010 2010
2011 2011 $ hg phase --draft --force -r .
2012 2012
2013 2013 $ debugwireproto << EOF
2014 2014 > command pushkey
2015 2015 > namespace phases
2016 2016 > key 7127240a084fd9dc86fe8d1f98e26229161ec82b
2017 2017 > old 1
2018 2018 > new 0
2019 2019 > EOF
2020 2020 testing ssh1
2021 2021 creating ssh peer from handshake results
2022 2022 i> write(104) -> 104:
2023 2023 i> hello\n
2024 2024 i> between\n
2025 2025 i> pairs 81\n
2026 2026 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
2027 2027 i> flush() -> None
2028 2028 o> readline() -> 4:
2029 2029 o> 427\n
2030 2030 o> readline() -> 427:
2031 2031 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
2032 2032 o> readline() -> 2:
2033 2033 o> 1\n
2034 2034 o> readline() -> 1:
2035 2035 o> \n
2036 2036 sending pushkey command
2037 2037 i> write(8) -> 8:
2038 2038 i> pushkey\n
2039 2039 i> write(7) -> 7:
2040 2040 i> key 40\n
2041 2041 i> write(40) -> 40: 7127240a084fd9dc86fe8d1f98e26229161ec82b
2042 2042 i> write(12) -> 12:
2043 2043 i> namespace 6\n
2044 2044 i> write(6) -> 6: phases
2045 2045 i> write(6) -> 6:
2046 2046 i> new 1\n
2047 2047 i> write(1) -> 1: 0
2048 2048 i> write(6) -> 6:
2049 2049 i> old 1\n
2050 2050 i> write(1) -> 1: 1
2051 2051 i> flush() -> None
2052 2052 o> bufferedreadline() -> 2:
2053 2053 o> 2\n
2054 2054 o> bufferedread(2) -> 2:
2055 2055 o> 1\n
2056 2056 response: True
2057 2057
2058 2058 testing ssh2
2059 2059 creating ssh peer from handshake results
2060 2060 i> write(171) -> 171:
2061 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
2061 i> upgrade * proto=exp-ssh-v2-0002\n (glob)
2062 2062 i> hello\n
2063 2063 i> between\n
2064 2064 i> pairs 81\n
2065 2065 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
2066 2066 i> flush() -> None
2067 2067 o> readline() -> 62:
2068 o> upgraded * exp-ssh-v2-0001\n (glob)
2068 o> upgraded * exp-ssh-v2-0002\n (glob)
2069 2069 o> readline() -> 4:
2070 2070 o> 426\n
2071 2071 o> read(426) -> 426: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
2072 2072 o> read(1) -> 1:
2073 2073 o> \n
2074 2074 sending pushkey command
2075 2075 i> write(8) -> 8:
2076 2076 i> pushkey\n
2077 2077 i> write(7) -> 7:
2078 2078 i> key 40\n
2079 2079 i> write(40) -> 40: 7127240a084fd9dc86fe8d1f98e26229161ec82b
2080 2080 i> write(12) -> 12:
2081 2081 i> namespace 6\n
2082 2082 i> write(6) -> 6: phases
2083 2083 i> write(6) -> 6:
2084 2084 i> new 1\n
2085 2085 i> write(1) -> 1: 0
2086 2086 i> write(6) -> 6:
2087 2087 i> old 1\n
2088 2088 i> write(1) -> 1: 1
2089 2089 i> flush() -> None
2090 2090 o> bufferedreadline() -> 2:
2091 2091 o> 2\n
2092 2092 o> bufferedread(2) -> 2:
2093 2093 o> 1\n
2094 2094 response: True
2095 2095
2096 2096 $ hg phase .
2097 2097 4: public
2098 2098
2099 2099 $ cd ..
2100 2100
2101 2101 Test batching of requests
2102 2102
2103 2103 $ hg init batching
2104 2104 $ cd batching
2105 2105 $ echo 0 > foo
2106 2106 $ hg add foo
2107 2107 $ hg -q commit -m initial
2108 2108 $ hg phase --public
2109 2109 $ echo 1 > foo
2110 2110 $ hg commit -m 'commit 1'
2111 2111 $ hg -q up 0
2112 2112 $ echo 2 > foo
2113 2113 $ hg commit -m 'commit 2'
2114 2114 created new head
2115 2115 $ hg book -r 1 bookA
2116 2116 $ hg book -r 2 bookB
2117 2117
2118 2118 $ debugwireproto << EOF
2119 2119 > batchbegin
2120 2120 > command heads
2121 2121 > command listkeys
2122 2122 > namespace bookmarks
2123 2123 > command listkeys
2124 2124 > namespace phases
2125 2125 > batchsubmit
2126 2126 > EOF
2127 2127 testing ssh1
2128 2128 creating ssh peer from handshake results
2129 2129 i> write(104) -> 104:
2130 2130 i> hello\n
2131 2131 i> between\n
2132 2132 i> pairs 81\n
2133 2133 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
2134 2134 i> flush() -> None
2135 2135 o> readline() -> 4:
2136 2136 o> 427\n
2137 2137 o> readline() -> 427:
2138 2138 o> capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash\n
2139 2139 o> readline() -> 2:
2140 2140 o> 1\n
2141 2141 o> readline() -> 1:
2142 2142 o> \n
2143 2143 sending batch with 3 sub-commands
2144 2144 i> write(6) -> 6:
2145 2145 i> batch\n
2146 2146 i> write(4) -> 4:
2147 2147 i> * 0\n
2148 2148 i> write(8) -> 8:
2149 2149 i> cmds 61\n
2150 2150 i> write(61) -> 61: heads ;listkeys namespace=bookmarks;listkeys namespace=phases
2151 2151 i> flush() -> None
2152 2152 o> bufferedreadline() -> 4:
2153 2153 o> 278\n
2154 2154 o> bufferedread(278) -> 278:
2155 2155 o> bfebe6bd38eebc6f8202e419c1171268987ea6a6 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
2156 2156 o> ;bookA\t4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
2157 2157 o> bookB\tbfebe6bd38eebc6f8202e419c1171268987ea6a6;4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\t1\n
2158 2158 o> bfebe6bd38eebc6f8202e419c1171268987ea6a6\t1\n
2159 2159 o> publishing\tTrue
2160 2160 response #0: bfebe6bd38eebc6f8202e419c1171268987ea6a6 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
2161 2161 response #1: bookA\t4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\nbookB\tbfebe6bd38eebc6f8202e419c1171268987ea6a6
2162 2162 response #2: 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\t1\nbfebe6bd38eebc6f8202e419c1171268987ea6a6\t1\npublishing\tTrue
2163 2163
2164 2164 testing ssh2
2165 2165 creating ssh peer from handshake results
2166 2166 i> write(171) -> 171:
2167 i> upgrade * proto=exp-ssh-v2-0001\n (glob)
2167 i> upgrade * proto=exp-ssh-v2-0002\n (glob)
2168 2168 i> hello\n
2169 2169 i> between\n
2170 2170 i> pairs 81\n
2171 2171 i> 0000000000000000000000000000000000000000-0000000000000000000000000000000000000000
2172 2172 i> flush() -> None
2173 2173 o> readline() -> 62:
2174 o> upgraded * exp-ssh-v2-0001\n (glob)
2174 o> upgraded * exp-ssh-v2-0002\n (glob)
2175 2175 o> readline() -> 4:
2176 2176 o> 426\n
2177 2177 o> read(426) -> 426: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
2178 2178 o> read(1) -> 1:
2179 2179 o> \n
2180 2180 sending batch with 3 sub-commands
2181 2181 i> write(6) -> 6:
2182 2182 i> batch\n
2183 2183 i> write(4) -> 4:
2184 2184 i> * 0\n
2185 2185 i> write(8) -> 8:
2186 2186 i> cmds 61\n
2187 2187 i> write(61) -> 61: heads ;listkeys namespace=bookmarks;listkeys namespace=phases
2188 2188 i> flush() -> None
2189 2189 o> bufferedreadline() -> 4:
2190 2190 o> 278\n
2191 2191 o> bufferedread(278) -> 278:
2192 2192 o> bfebe6bd38eebc6f8202e419c1171268987ea6a6 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
2193 2193 o> ;bookA\t4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
2194 2194 o> bookB\tbfebe6bd38eebc6f8202e419c1171268987ea6a6;4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\t1\n
2195 2195 o> bfebe6bd38eebc6f8202e419c1171268987ea6a6\t1\n
2196 2196 o> publishing\tTrue
2197 2197 response #0: bfebe6bd38eebc6f8202e419c1171268987ea6a6 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\n
2198 2198 response #1: bookA\t4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\nbookB\tbfebe6bd38eebc6f8202e419c1171268987ea6a6
2199 2199 response #2: 4ee3fcef1c800fa2bf23e20af7c83ff111d9c7ab\t1\nbfebe6bd38eebc6f8202e419c1171268987ea6a6\t1\npublishing\tTrue
@@ -1,643 +1,643 b''
1 1 #testcases sshv1 sshv2
2 2
3 3 #if sshv2
4 4 $ cat >> $HGRCPATH << EOF
5 5 > [experimental]
6 6 > sshpeer.advertise-v2 = true
7 7 > sshserver.support-v2 = true
8 8 > EOF
9 9 #endif
10 10
11 11 This test tries to exercise the ssh functionality with a dummy script
12 12
13 13 creating 'remote' repo
14 14
15 15 $ hg init remote
16 16 $ cd remote
17 17 $ echo this > foo
18 18 $ echo this > fooO
19 19 $ hg ci -A -m "init" foo fooO
20 20
21 21 insert a closed branch (issue4428)
22 22
23 23 $ hg up null
24 24 0 files updated, 0 files merged, 2 files removed, 0 files unresolved
25 25 $ hg branch closed
26 26 marked working directory as branch closed
27 27 (branches are permanent and global, did you want a bookmark?)
28 28 $ hg ci -mc0
29 29 $ hg ci --close-branch -mc1
30 30 $ hg up -q default
31 31
32 32 configure for serving
33 33
34 34 $ cat <<EOF > .hg/hgrc
35 35 > [server]
36 36 > uncompressed = True
37 37 >
38 38 > [hooks]
39 39 > changegroup = sh -c "printenv.py changegroup-in-remote 0 ../dummylog"
40 40 > EOF
41 41 $ cd ..
42 42
43 43 repo not found error
44 44
45 45 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/nonexistent local
46 46 remote: abort: repository nonexistent not found!
47 47 abort: no suitable response from remote hg!
48 48 [255]
49 49
50 50 non-existent absolute path
51 51
52 52 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/`pwd`/nonexistent local
53 53 remote: abort: repository $TESTTMP/nonexistent not found!
54 54 abort: no suitable response from remote hg!
55 55 [255]
56 56
57 57 clone remote via stream
58 58
59 59 #if no-reposimplestore
60 60
61 61 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" --stream ssh://user@dummy/remote local-stream
62 62 streaming all changes
63 63 8 files to transfer, 827 bytes of data
64 64 transferred 827 bytes in * seconds (*) (glob)
65 65 updating to branch default
66 66 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
67 67 $ cd local-stream
68 68 $ hg verify
69 69 checking changesets
70 70 checking manifests
71 71 crosschecking files in changesets and manifests
72 72 checking files
73 73 checked 3 changesets with 2 changes to 2 files
74 74 $ hg branches
75 75 default 0:1160648e36ce
76 76 $ cd ..
77 77
78 78 clone bookmarks via stream
79 79
80 80 $ hg -R local-stream book mybook
81 81 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" --stream ssh://user@dummy/local-stream stream2
82 82 streaming all changes
83 83 9 files to transfer, 870 bytes of data
84 84 transferred 870 bytes in * seconds (*) (glob)
85 85 updating to branch default
86 86 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
87 87 $ cd stream2
88 88 $ hg book
89 89 mybook 0:1160648e36ce
90 90 $ cd ..
91 91 $ rm -rf local-stream stream2
92 92
93 93 #endif
94 94
95 95 clone remote via pull
96 96
97 97 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local
98 98 requesting all changes
99 99 adding changesets
100 100 adding manifests
101 101 adding file changes
102 102 added 3 changesets with 2 changes to 2 files
103 103 new changesets 1160648e36ce:ad076bfb429d
104 104 updating to branch default
105 105 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
106 106
107 107 verify
108 108
109 109 $ cd local
110 110 $ hg verify
111 111 checking changesets
112 112 checking manifests
113 113 crosschecking files in changesets and manifests
114 114 checking files
115 115 checked 3 changesets with 2 changes to 2 files
116 116 $ cat >> .hg/hgrc <<EOF
117 117 > [hooks]
118 118 > changegroup = sh -c "printenv.py changegroup-in-local 0 ../dummylog"
119 119 > EOF
120 120
121 121 empty default pull
122 122
123 123 $ hg paths
124 124 default = ssh://user@dummy/remote
125 125 $ hg pull -e "\"$PYTHON\" \"$TESTDIR/dummyssh\""
126 126 pulling from ssh://user@dummy/remote
127 127 searching for changes
128 128 no changes found
129 129
130 130 pull from wrong ssh URL
131 131
132 132 $ hg pull -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/doesnotexist
133 133 pulling from ssh://user@dummy/doesnotexist
134 134 remote: abort: repository doesnotexist not found!
135 135 abort: no suitable response from remote hg!
136 136 [255]
137 137
138 138 local change
139 139
140 140 $ echo bleah > foo
141 141 $ hg ci -m "add"
142 142
143 143 updating rc
144 144
145 145 $ echo "default-push = ssh://user@dummy/remote" >> .hg/hgrc
146 146 $ echo "[ui]" >> .hg/hgrc
147 147 $ echo "ssh = \"$PYTHON\" \"$TESTDIR/dummyssh\"" >> .hg/hgrc
148 148
149 149 find outgoing
150 150
151 151 $ hg out ssh://user@dummy/remote
152 152 comparing with ssh://user@dummy/remote
153 153 searching for changes
154 154 changeset: 3:a28a9d1a809c
155 155 tag: tip
156 156 parent: 0:1160648e36ce
157 157 user: test
158 158 date: Thu Jan 01 00:00:00 1970 +0000
159 159 summary: add
160 160
161 161
162 162 find incoming on the remote side
163 163
164 164 $ hg incoming -R ../remote -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/local
165 165 comparing with ssh://user@dummy/local
166 166 searching for changes
167 167 changeset: 3:a28a9d1a809c
168 168 tag: tip
169 169 parent: 0:1160648e36ce
170 170 user: test
171 171 date: Thu Jan 01 00:00:00 1970 +0000
172 172 summary: add
173 173
174 174
175 175 find incoming on the remote side (using absolute path)
176 176
177 177 $ hg incoming -R ../remote -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" "ssh://user@dummy/`pwd`"
178 178 comparing with ssh://user@dummy/$TESTTMP/local
179 179 searching for changes
180 180 changeset: 3:a28a9d1a809c
181 181 tag: tip
182 182 parent: 0:1160648e36ce
183 183 user: test
184 184 date: Thu Jan 01 00:00:00 1970 +0000
185 185 summary: add
186 186
187 187
188 188 push
189 189
190 190 $ hg push
191 191 pushing to ssh://user@dummy/remote
192 192 searching for changes
193 193 remote: adding changesets
194 194 remote: adding manifests
195 195 remote: adding file changes
196 196 remote: added 1 changesets with 1 changes to 1 files
197 197 $ cd ../remote
198 198
199 199 check remote tip
200 200
201 201 $ hg tip
202 202 changeset: 3:a28a9d1a809c
203 203 tag: tip
204 204 parent: 0:1160648e36ce
205 205 user: test
206 206 date: Thu Jan 01 00:00:00 1970 +0000
207 207 summary: add
208 208
209 209 $ hg verify
210 210 checking changesets
211 211 checking manifests
212 212 crosschecking files in changesets and manifests
213 213 checking files
214 214 checked 4 changesets with 3 changes to 2 files
215 215 $ hg cat -r tip foo
216 216 bleah
217 217 $ echo z > z
218 218 $ hg ci -A -m z z
219 219 created new head
220 220
221 221 test pushkeys and bookmarks
222 222
223 223 $ cd ../local
224 224 $ hg debugpushkey --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote namespaces
225 225 bookmarks
226 226 namespaces
227 227 phases
228 228 $ hg book foo -r 0
229 229 $ hg out -B --config paths.default=bogus://invalid --config paths.default:pushurl=`hg paths default`
230 230 comparing with ssh://user@dummy/remote
231 231 searching for changed bookmarks
232 232 foo 1160648e36ce
233 233 $ hg push -B foo
234 234 pushing to ssh://user@dummy/remote
235 235 searching for changes
236 236 no changes found
237 237 exporting bookmark foo
238 238 [1]
239 239 $ hg debugpushkey --config ui.ssh="\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote bookmarks
240 240 foo 1160648e36cec0054048a7edc4110c6f84fde594
241 241 $ hg book -f foo
242 242 $ hg push --traceback
243 243 pushing to ssh://user@dummy/remote
244 244 searching for changes
245 245 no changes found
246 246 updating bookmark foo
247 247 [1]
248 248 $ hg book -d foo
249 249 $ hg in -B
250 250 comparing with ssh://user@dummy/remote
251 251 searching for changed bookmarks
252 252 foo a28a9d1a809c
253 253 $ hg book -f -r 0 foo
254 254 $ hg pull -B foo
255 255 pulling from ssh://user@dummy/remote
256 256 no changes found
257 257 updating bookmark foo
258 258 $ hg book -d foo
259 259 $ hg push -B foo
260 260 pushing to ssh://user@dummy/remote
261 261 searching for changes
262 262 no changes found
263 263 deleting remote bookmark foo
264 264 [1]
265 265
266 266 a bad, evil hook that prints to stdout
267 267
268 268 $ cat <<EOF > $TESTTMP/badhook
269 269 > import sys
270 270 > sys.stdout.write("KABOOM\n")
271 271 > sys.stdout.flush()
272 272 > EOF
273 273
274 274 $ cat <<EOF > $TESTTMP/badpyhook.py
275 275 > import sys
276 276 > def hook(ui, repo, hooktype, **kwargs):
277 277 > sys.stdout.write("KABOOM IN PROCESS\n")
278 278 > sys.stdout.flush()
279 279 > EOF
280 280
281 281 $ cat <<EOF >> ../remote/.hg/hgrc
282 282 > [hooks]
283 283 > changegroup.stdout = "$PYTHON" $TESTTMP/badhook
284 284 > changegroup.pystdout = python:$TESTTMP/badpyhook.py:hook
285 285 > EOF
286 286 $ echo r > r
287 287 $ hg ci -A -m z r
288 288
289 289 push should succeed even though it has an unexpected response
290 290
291 291 $ hg push
292 292 pushing to ssh://user@dummy/remote
293 293 searching for changes
294 294 remote has heads on branch 'default' that are not known locally: 6c0482d977a3
295 295 remote: adding changesets
296 296 remote: adding manifests
297 297 remote: adding file changes
298 298 remote: added 1 changesets with 1 changes to 1 files
299 299 remote: KABOOM
300 300 remote: KABOOM IN PROCESS
301 301 $ hg -R ../remote heads
302 302 changeset: 5:1383141674ec
303 303 tag: tip
304 304 parent: 3:a28a9d1a809c
305 305 user: test
306 306 date: Thu Jan 01 00:00:00 1970 +0000
307 307 summary: z
308 308
309 309 changeset: 4:6c0482d977a3
310 310 parent: 0:1160648e36ce
311 311 user: test
312 312 date: Thu Jan 01 00:00:00 1970 +0000
313 313 summary: z
314 314
315 315
316 316 clone bookmarks
317 317
318 318 $ hg -R ../remote bookmark test
319 319 $ hg -R ../remote bookmarks
320 320 * test 4:6c0482d977a3
321 321 $ hg clone -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" ssh://user@dummy/remote local-bookmarks
322 322 requesting all changes
323 323 adding changesets
324 324 adding manifests
325 325 adding file changes
326 326 added 6 changesets with 5 changes to 4 files (+1 heads)
327 327 new changesets 1160648e36ce:1383141674ec
328 328 updating to branch default
329 329 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
330 330 $ hg -R local-bookmarks bookmarks
331 331 test 4:6c0482d977a3
332 332
333 333 passwords in ssh urls are not supported
334 334 (we use a glob here because different Python versions give different
335 335 results here)
336 336
337 337 $ hg push ssh://user:erroneouspwd@dummy/remote
338 338 pushing to ssh://user:*@dummy/remote (glob)
339 339 abort: password in URL not supported!
340 340 [255]
341 341
342 342 $ cd ..
343 343
344 344 hide outer repo
345 345 $ hg init
346 346
347 347 Test remote paths with spaces (issue2983):
348 348
349 349 $ hg init --ssh "\"$PYTHON\" \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
350 350 $ touch "$TESTTMP/a repo/test"
351 351 $ hg -R 'a repo' commit -A -m "test"
352 352 adding test
353 353 $ hg -R 'a repo' tag tag
354 354 $ hg id --ssh "\"$PYTHON\" \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
355 355 73649e48688a
356 356
357 357 $ hg id --ssh "\"$PYTHON\" \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo#noNoNO"
358 358 abort: unknown revision 'noNoNO'!
359 359 [255]
360 360
361 361 Test (non-)escaping of remote paths with spaces when cloning (issue3145):
362 362
363 363 $ hg clone --ssh "\"$PYTHON\" \"$TESTDIR/dummyssh\"" "ssh://user@dummy/a repo"
364 364 destination directory: a repo
365 365 abort: destination 'a repo' is not empty
366 366 [255]
367 367
368 368 Make sure hg is really paranoid in serve --stdio mode. It used to be
369 369 possible to get a debugger REPL by specifying a repo named --debugger.
370 370 $ hg -R --debugger serve --stdio
371 371 abort: potentially unsafe serve --stdio invocation: ['-R', '--debugger', 'serve', '--stdio']
372 372 [255]
373 373 $ hg -R --config=ui.debugger=yes serve --stdio
374 374 abort: potentially unsafe serve --stdio invocation: ['-R', '--config=ui.debugger=yes', 'serve', '--stdio']
375 375 [255]
376 376 Abbreviations of 'serve' also don't work, to avoid shenanigans.
377 377 $ hg -R narf serv --stdio
378 378 abort: potentially unsafe serve --stdio invocation: ['-R', 'narf', 'serv', '--stdio']
379 379 [255]
380 380
381 381 Test hg-ssh using a helper script that will restore PYTHONPATH (which might
382 382 have been cleared by a hg.exe wrapper) and invoke hg-ssh with the right
383 383 parameters:
384 384
385 385 $ cat > ssh.sh << EOF
386 386 > userhost="\$1"
387 387 > SSH_ORIGINAL_COMMAND="\$2"
388 388 > export SSH_ORIGINAL_COMMAND
389 389 > PYTHONPATH="$PYTHONPATH"
390 390 > export PYTHONPATH
391 391 > "$PYTHON" "$TESTDIR/../contrib/hg-ssh" "$TESTTMP/a repo"
392 392 > EOF
393 393
394 394 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a repo"
395 395 73649e48688a
396 396
397 397 $ hg id --ssh "sh ssh.sh" "ssh://user@dummy/a'repo"
398 398 remote: Illegal repository "$TESTTMP/a'repo"
399 399 abort: no suitable response from remote hg!
400 400 [255]
401 401
402 402 $ hg id --ssh "sh ssh.sh" --remotecmd hacking "ssh://user@dummy/a'repo"
403 403 remote: Illegal command "hacking -R 'a'\''repo' serve --stdio"
404 404 abort: no suitable response from remote hg!
405 405 [255]
406 406
407 407 $ SSH_ORIGINAL_COMMAND="'hg' -R 'a'repo' serve --stdio" "$PYTHON" "$TESTDIR/../contrib/hg-ssh"
408 408 Illegal command "'hg' -R 'a'repo' serve --stdio": No closing quotation
409 409 [255]
410 410
411 411 Test hg-ssh in read-only mode:
412 412
413 413 $ cat > ssh.sh << EOF
414 414 > userhost="\$1"
415 415 > SSH_ORIGINAL_COMMAND="\$2"
416 416 > export SSH_ORIGINAL_COMMAND
417 417 > PYTHONPATH="$PYTHONPATH"
418 418 > export PYTHONPATH
419 419 > "$PYTHON" "$TESTDIR/../contrib/hg-ssh" --read-only "$TESTTMP/remote"
420 420 > EOF
421 421
422 422 $ hg clone --ssh "sh ssh.sh" "ssh://user@dummy/$TESTTMP/remote" read-only-local
423 423 requesting all changes
424 424 adding changesets
425 425 adding manifests
426 426 adding file changes
427 427 added 6 changesets with 5 changes to 4 files (+1 heads)
428 428 new changesets 1160648e36ce:1383141674ec
429 429 updating to branch default
430 430 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
431 431
432 432 $ cd read-only-local
433 433 $ echo "baz" > bar
434 434 $ hg ci -A -m "unpushable commit" bar
435 435 $ hg push --ssh "sh ../ssh.sh"
436 436 pushing to ssh://user@dummy/*/remote (glob)
437 437 searching for changes
438 438 remote: Permission denied
439 439 remote: pretxnopen.hg-ssh hook failed
440 440 abort: push failed on remote
441 441 [255]
442 442
443 443 $ cd ..
444 444
445 445 stderr from remote commands should be printed before stdout from local code (issue4336)
446 446
447 447 $ hg clone remote stderr-ordering
448 448 updating to branch default
449 449 3 files updated, 0 files merged, 0 files removed, 0 files unresolved
450 450 $ cd stderr-ordering
451 451 $ cat >> localwrite.py << EOF
452 452 > from mercurial import exchange, extensions
453 453 >
454 454 > def wrappedpush(orig, repo, *args, **kwargs):
455 455 > res = orig(repo, *args, **kwargs)
456 456 > repo.ui.write(b'local stdout\n')
457 457 > repo.ui.flush()
458 458 > return res
459 459 >
460 460 > def extsetup(ui):
461 461 > extensions.wrapfunction(exchange, b'push', wrappedpush)
462 462 > EOF
463 463
464 464 $ cat >> .hg/hgrc << EOF
465 465 > [paths]
466 466 > default-push = ssh://user@dummy/remote
467 467 > [ui]
468 468 > ssh = "$PYTHON" "$TESTDIR/dummyssh"
469 469 > [extensions]
470 470 > localwrite = localwrite.py
471 471 > EOF
472 472
473 473 $ echo localwrite > foo
474 474 $ hg commit -m 'testing localwrite'
475 475 $ hg push
476 476 pushing to ssh://user@dummy/remote
477 477 searching for changes
478 478 remote: adding changesets
479 479 remote: adding manifests
480 480 remote: adding file changes
481 481 remote: added 1 changesets with 1 changes to 1 files
482 482 remote: KABOOM
483 483 remote: KABOOM IN PROCESS
484 484 local stdout
485 485
486 486 debug output
487 487
488 488 $ hg pull --debug ssh://user@dummy/remote --config devel.debug.peer-request=yes
489 489 pulling from ssh://user@dummy/remote
490 490 running .* ".*/dummyssh" ['"]user@dummy['"] ('|")hg -R remote serve --stdio('|") (re)
491 sending upgrade request: * proto=exp-ssh-v2-0001 (glob) (sshv2 !)
491 sending upgrade request: * proto=exp-ssh-v2-0002 (glob) (sshv2 !)
492 492 devel-peer-request: hello+between
493 493 devel-peer-request: pairs: 81 bytes
494 494 sending hello command
495 495 sending between command
496 496 remote: 427 (sshv1 !)
497 protocol upgraded to exp-ssh-v2-0001 (sshv2 !)
497 protocol upgraded to exp-ssh-v2-0002 (sshv2 !)
498 498 remote: capabilities: batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset getbundle known lookup protocaps pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
499 499 remote: 1 (sshv1 !)
500 500 devel-peer-request: protocaps
501 501 devel-peer-request: caps: * bytes (glob)
502 502 sending protocaps command
503 503 query 1; heads
504 504 devel-peer-request: batched-content
505 505 devel-peer-request: - heads (0 arguments)
506 506 devel-peer-request: - known (1 arguments)
507 507 devel-peer-request: batch
508 508 devel-peer-request: cmds: 141 bytes
509 509 sending batch command
510 510 searching for changes
511 511 all remote heads known locally
512 512 no changes found
513 513 devel-peer-request: getbundle
514 514 devel-peer-request: bookmarks: 1 bytes
515 515 devel-peer-request: bundlecaps: 266 bytes
516 516 devel-peer-request: cg: 1 bytes
517 517 devel-peer-request: common: 122 bytes
518 518 devel-peer-request: heads: 122 bytes
519 519 devel-peer-request: listkeys: 9 bytes
520 520 devel-peer-request: phases: 1 bytes
521 521 sending getbundle command
522 522 bundle2-input-bundle: with-transaction
523 523 bundle2-input-part: "bookmarks" supported
524 524 bundle2-input-part: total payload size 26
525 525 bundle2-input-part: "listkeys" (params: 1 mandatory) supported
526 526 bundle2-input-part: total payload size 45
527 527 bundle2-input-part: "phase-heads" supported
528 528 bundle2-input-part: total payload size 72
529 529 bundle2-input-bundle: 2 parts total
530 530 checking for updated bookmarks
531 531
532 532 $ cd ..
533 533
534 534 $ cat dummylog
535 535 Got arguments 1:user@dummy 2:hg -R nonexistent serve --stdio
536 536 Got arguments 1:user@dummy 2:hg -R $TESTTMP/nonexistent serve --stdio
537 537 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
538 538 Got arguments 1:user@dummy 2:hg -R local-stream serve --stdio (no-reposimplestore !)
539 539 Got arguments 1:user@dummy 2:hg -R remote serve --stdio (no-reposimplestore !)
540 540 Got arguments 1:user@dummy 2:hg -R remote serve --stdio (no-reposimplestore !)
541 541 Got arguments 1:user@dummy 2:hg -R doesnotexist serve --stdio
542 542 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
543 543 Got arguments 1:user@dummy 2:hg -R local serve --stdio
544 544 Got arguments 1:user@dummy 2:hg -R $TESTTMP/local serve --stdio
545 545 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
546 546 changegroup-in-remote hook: HG_BUNDLE2=1 HG_HOOKNAME=changegroup HG_HOOKTYPE=changegroup HG_NODE=a28a9d1a809cab7d4e2fde4bee738a9ede948b60 HG_NODE_LAST=a28a9d1a809cab7d4e2fde4bee738a9ede948b60 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:ssh:$LOCALIP
547 547 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
548 548 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
549 549 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
550 550 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
551 551 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
552 552 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
553 553 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
554 554 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
555 555 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
556 556 changegroup-in-remote hook: HG_BUNDLE2=1 HG_HOOKNAME=changegroup HG_HOOKTYPE=changegroup HG_NODE=1383141674ec756a6056f6a9097618482fe0f4a6 HG_NODE_LAST=1383141674ec756a6056f6a9097618482fe0f4a6 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:ssh:$LOCALIP
557 557 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
558 558 Got arguments 1:user@dummy 2:hg init 'a repo'
559 559 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
560 560 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
561 561 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
562 562 Got arguments 1:user@dummy 2:hg -R 'a repo' serve --stdio
563 563 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
564 564 changegroup-in-remote hook: HG_BUNDLE2=1 HG_HOOKNAME=changegroup HG_HOOKTYPE=changegroup HG_NODE=65c38f4125f9602c8db4af56530cc221d93b8ef8 HG_NODE_LAST=65c38f4125f9602c8db4af56530cc221d93b8ef8 HG_SOURCE=serve HG_TXNID=TXN:$ID$ HG_URL=remote:ssh:$LOCALIP
565 565 Got arguments 1:user@dummy 2:hg -R remote serve --stdio
566 566
567 567 remote hook failure is attributed to remote
568 568
569 569 $ cat > $TESTTMP/failhook << EOF
570 570 > def hook(ui, repo, **kwargs):
571 571 > ui.write(b'hook failure!\n')
572 572 > ui.flush()
573 573 > return 1
574 574 > EOF
575 575
576 576 $ echo "pretxnchangegroup.fail = python:$TESTTMP/failhook:hook" >> remote/.hg/hgrc
577 577
578 578 $ hg -q --config ui.ssh="\"$PYTHON\" $TESTDIR/dummyssh" clone ssh://user@dummy/remote hookout
579 579 $ cd hookout
580 580 $ touch hookfailure
581 581 $ hg -q commit -A -m 'remote hook failure'
582 582 $ hg --config ui.ssh="\"$PYTHON\" $TESTDIR/dummyssh" push
583 583 pushing to ssh://user@dummy/remote
584 584 searching for changes
585 585 remote: adding changesets
586 586 remote: adding manifests
587 587 remote: adding file changes
588 588 remote: added 1 changesets with 1 changes to 1 files
589 589 remote: hook failure!
590 590 remote: transaction abort!
591 591 remote: rollback completed
592 592 remote: pretxnchangegroup.fail hook failed
593 593 abort: push failed on remote
594 594 [255]
595 595
596 596 abort during pull is properly reported as such
597 597
598 598 $ echo morefoo >> ../remote/foo
599 599 $ hg -R ../remote commit --message "more foo to be pulled"
600 600 $ cat >> ../remote/.hg/hgrc << EOF
601 601 > [extensions]
602 602 > crash = ${TESTDIR}/crashgetbundler.py
603 603 > EOF
604 604 $ hg --config ui.ssh="\"$PYTHON\" $TESTDIR/dummyssh" pull
605 605 pulling from ssh://user@dummy/remote
606 606 searching for changes
607 607 remote: abort: this is an exercise
608 608 abort: pull failed on remote
609 609 [255]
610 610
611 611 abort with no error hint when there is a ssh problem when pulling
612 612
613 613 $ hg pull ssh://brokenrepository -e "\"$PYTHON\" \"$TESTDIR/dummyssh\""
614 614 pulling from ssh://brokenrepository/
615 615 abort: no suitable response from remote hg!
616 616 [255]
617 617
618 618 abort with configured error hint when there is a ssh problem when pulling
619 619
620 620 $ hg pull ssh://brokenrepository -e "\"$PYTHON\" \"$TESTDIR/dummyssh\"" \
621 621 > --config ui.ssherrorhint="Please see http://company/internalwiki/ssh.html"
622 622 pulling from ssh://brokenrepository/
623 623 abort: no suitable response from remote hg!
624 624 (Please see http://company/internalwiki/ssh.html)
625 625 [255]
626 626
627 627 test that custom environment is passed down to ssh executable
628 628 $ cat >>dumpenv <<EOF
629 629 > #! /bin/sh
630 630 > echo \$VAR >&2
631 631 > EOF
632 632 $ chmod +x dumpenv
633 633 $ hg pull ssh://something --config ui.ssh="sh dumpenv"
634 634 pulling from ssh://something/
635 635 remote:
636 636 abort: no suitable response from remote hg!
637 637 [255]
638 638 $ hg pull ssh://something --config ui.ssh="sh dumpenv" --config sshenv.VAR=17
639 639 pulling from ssh://something/
640 640 remote: 17
641 641 abort: no suitable response from remote hg!
642 642 [255]
643 643
@@ -1,92 +1,92 b''
1 1 $ . $TESTDIR/wireprotohelpers.sh
2 2
3 3 $ hg init server
4 4 $ enablehttpv2 server
5 5 $ cd server
6 6 $ hg debugdrawdag << EOF
7 7 > C D
8 8 > |/
9 9 > B
10 10 > |
11 11 > A
12 12 > EOF
13 13
14 14 $ hg up B
15 15 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
16 16 $ hg branch branch1
17 17 marked working directory as branch branch1
18 18 (branches are permanent and global, did you want a bookmark?)
19 19 $ echo b1 > foo
20 20 $ hg -q commit -A -m 'branch 1'
21 21 $ hg up B
22 22 0 files updated, 0 files merged, 1 files removed, 0 files unresolved
23 23 $ hg branch branch2
24 24 marked working directory as branch branch2
25 25 $ echo b2 > foo
26 26 $ hg -q commit -A -m 'branch 2'
27 27
28 28 $ hg log -T '{rev}:{node} {branch} {desc}\n'
29 29 5:224161c7589aa48fa83a48feff5e95b56ae327fc branch2 branch 2
30 30 4:b5faacdfd2633768cb3152336cc0953381266688 branch1 branch 1
31 31 3:be0ef73c17ade3fc89dc41701eb9fc3a91b58282 default D
32 32 2:26805aba1e600a82e93661149f2313866a221a7b default C
33 33 1:112478962961147124edd43549aedd1a335e44bf default B
34 34 0:426bada5c67598ca65036d57d9e4b64b0c1ce7a0 default A
35 35
36 36 $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
37 37 $ cat hg.pid > $DAEMON_PIDS
38 38
39 39 No arguments returns something reasonable
40 40
41 41 $ sendhttpv2peer << EOF
42 42 > command branchmap
43 43 > EOF
44 44 creating http peer for wire protocol version 2
45 45 sending branchmap command
46 s> POST /api/exp-http-v2-0001/ro/branchmap HTTP/1.1\r\n
46 s> POST /api/exp-http-v2-0002/ro/branchmap HTTP/1.1\r\n
47 47 s> Accept-Encoding: identity\r\n
48 48 s> accept: application/mercurial-exp-framing-0005\r\n
49 49 s> content-type: application/mercurial-exp-framing-0005\r\n
50 50 s> content-length: 24\r\n
51 51 s> host: $LOCALIP:$HGPORT\r\n (glob)
52 52 s> user-agent: Mercurial debugwireproto\r\n
53 53 s> \r\n
54 54 s> \x10\x00\x00\x01\x00\x01\x01\x11\xa1DnameIbranchmap
55 55 s> makefile('rb', None)
56 56 s> HTTP/1.1 200 OK\r\n
57 57 s> Server: testing stub value\r\n
58 58 s> Date: $HTTP_DATE$\r\n
59 59 s> Content-Type: application/mercurial-exp-framing-0005\r\n
60 60 s> Transfer-Encoding: chunked\r\n
61 61 s> \r\n
62 62 s> 13\r\n
63 63 s> \x0b\x00\x00\x01\x00\x02\x011
64 64 s> \xa1FstatusBok
65 65 s> \r\n
66 66 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
67 67 s> 78\r\n
68 68 s> p\x00\x00\x01\x00\x02\x001
69 69 s> \xa3Gbranch1\x81T\xb5\xfa\xac\xdf\xd2c7h\xcb1R3l\xc0\x953\x81&f\x88Gbranch2\x81T"Aa\xc7X\x9a\xa4\x8f\xa8:H\xfe\xff^\x95\xb5j\xe3\'\xfcGdefault\x82T&\x80Z\xba\x1e`\n
70 70 s> \x82\xe96a\x14\x9f#\x13\x86j"\x1a{T\xbe\x0e\xf7<\x17\xad\xe3\xfc\x89\xdcAp\x1e\xb9\xfc:\x91\xb5\x82\x82
71 71 s> \r\n
72 72 received frame(size=112; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
73 73 s> 8\r\n
74 74 s> \x00\x00\x00\x01\x00\x02\x002
75 75 s> \r\n
76 76 s> 0\r\n
77 77 s> \r\n
78 78 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
79 79 response: {
80 80 b'branch1': [
81 81 b'\xb5\xfa\xac\xdf\xd2c7h\xcb1R3l\xc0\x953\x81&f\x88'
82 82 ],
83 83 b'branch2': [
84 84 b'"Aa\xc7X\x9a\xa4\x8f\xa8:H\xfe\xff^\x95\xb5j\xe3\'\xfc'
85 85 ],
86 86 b'default': [
87 87 b'&\x80Z\xba\x1e`\n\x82\xe96a\x14\x9f#\x13\x86j"\x1a{',
88 88 b'\xbe\x0e\xf7<\x17\xad\xe3\xfc\x89\xdcAp\x1e\xb9\xfc:\x91\xb5\x82\x82'
89 89 ]
90 90 }
91 91
92 92 $ cat error.log
@@ -1,656 +1,656 b''
1 1 #require no-chg
2 2
3 3 $ . $TESTDIR/wireprotohelpers.sh
4 4
5 5 $ hg init server
6 6
7 7 zstd isn't present in plain builds. Make tests easier by removing
8 8 zstd from the equation.
9 9
10 10 $ cat >> server/.hg/hgrc << EOF
11 11 > [server]
12 12 > compressionengines = zlib
13 13 > EOF
14 14
15 15 $ hg -R server serve -p $HGPORT -d --pid-file hg.pid -E error.log
16 16 $ cat hg.pid > $DAEMON_PIDS
17 17
18 18 A normal capabilities request is serviced for version 1
19 19
20 20 $ sendhttpraw << EOF
21 21 > httprequest GET ?cmd=capabilities
22 22 > user-agent: test
23 23 > EOF
24 24 using raw connection to peer
25 25 s> GET /?cmd=capabilities HTTP/1.1\r\n
26 26 s> Accept-Encoding: identity\r\n
27 27 s> user-agent: test\r\n
28 28 s> host: $LOCALIP:$HGPORT\r\n (glob)
29 29 s> \r\n
30 30 s> makefile('rb', None)
31 31 s> HTTP/1.1 200 Script output follows\r\n
32 32 s> Server: testing stub value\r\n
33 33 s> Date: $HTTP_DATE$\r\n
34 34 s> Content-Type: application/mercurial-0.1\r\n
35 35 s> Content-Length: *\r\n (glob)
36 36 s> \r\n
37 37 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
38 38
39 39 A proper request without the API server enabled returns the legacy response
40 40
41 41 $ sendhttpraw << EOF
42 42 > httprequest GET ?cmd=capabilities
43 43 > user-agent: test
44 44 > x-hgupgrade-1: foo
45 45 > x-hgproto-1: cbor
46 46 > EOF
47 47 using raw connection to peer
48 48 s> GET /?cmd=capabilities HTTP/1.1\r\n
49 49 s> Accept-Encoding: identity\r\n
50 50 s> user-agent: test\r\n
51 51 s> x-hgproto-1: cbor\r\n
52 52 s> x-hgupgrade-1: foo\r\n
53 53 s> host: $LOCALIP:$HGPORT\r\n (glob)
54 54 s> \r\n
55 55 s> makefile('rb', None)
56 56 s> HTTP/1.1 200 Script output follows\r\n
57 57 s> Server: testing stub value\r\n
58 58 s> Date: $HTTP_DATE$\r\n
59 59 s> Content-Type: application/mercurial-0.1\r\n
60 60 s> Content-Length: *\r\n (glob)
61 61 s> \r\n
62 62 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
63 63
64 64 Restart with just API server enabled. This enables serving the new format.
65 65
66 66 $ killdaemons.py
67 67 $ cat error.log
68 68
69 69 $ cat >> server/.hg/hgrc << EOF
70 70 > [experimental]
71 71 > web.apiserver = true
72 72 > EOF
73 73
74 74 $ hg -R server serve -p $HGPORT -d --pid-file hg.pid -E error.log
75 75 $ cat hg.pid > $DAEMON_PIDS
76 76
77 77 X-HgUpgrade-<N> without CBOR advertisement uses legacy response
78 78
79 79 $ sendhttpraw << EOF
80 80 > httprequest GET ?cmd=capabilities
81 81 > user-agent: test
82 82 > x-hgupgrade-1: foo bar
83 83 > EOF
84 84 using raw connection to peer
85 85 s> GET /?cmd=capabilities HTTP/1.1\r\n
86 86 s> Accept-Encoding: identity\r\n
87 87 s> user-agent: test\r\n
88 88 s> x-hgupgrade-1: foo bar\r\n
89 89 s> host: $LOCALIP:$HGPORT\r\n (glob)
90 90 s> \r\n
91 91 s> makefile('rb', None)
92 92 s> HTTP/1.1 200 Script output follows\r\n
93 93 s> Server: testing stub value\r\n
94 94 s> Date: $HTTP_DATE$\r\n
95 95 s> Content-Type: application/mercurial-0.1\r\n
96 96 s> Content-Length: *\r\n (glob)
97 97 s> \r\n
98 98 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
99 99
100 100 X-HgUpgrade-<N> without known serialization in X-HgProto-<N> uses legacy response
101 101
102 102 $ sendhttpraw << EOF
103 103 > httprequest GET ?cmd=capabilities
104 104 > user-agent: test
105 105 > x-hgupgrade-1: foo bar
106 106 > x-hgproto-1: some value
107 107 > EOF
108 108 using raw connection to peer
109 109 s> GET /?cmd=capabilities HTTP/1.1\r\n
110 110 s> Accept-Encoding: identity\r\n
111 111 s> user-agent: test\r\n
112 112 s> x-hgproto-1: some value\r\n
113 113 s> x-hgupgrade-1: foo bar\r\n
114 114 s> host: $LOCALIP:$HGPORT\r\n (glob)
115 115 s> \r\n
116 116 s> makefile('rb', None)
117 117 s> HTTP/1.1 200 Script output follows\r\n
118 118 s> Server: testing stub value\r\n
119 119 s> Date: $HTTP_DATE$\r\n
120 120 s> Content-Type: application/mercurial-0.1\r\n
121 121 s> Content-Length: *\r\n (glob)
122 122 s> \r\n
123 123 s> batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
124 124
125 125 X-HgUpgrade-<N> + X-HgProto-<N> headers trigger new response format
126 126
127 127 $ sendhttpraw << EOF
128 128 > httprequest GET ?cmd=capabilities
129 129 > user-agent: test
130 130 > x-hgupgrade-1: foo bar
131 131 > x-hgproto-1: cbor
132 132 > EOF
133 133 using raw connection to peer
134 134 s> GET /?cmd=capabilities HTTP/1.1\r\n
135 135 s> Accept-Encoding: identity\r\n
136 136 s> user-agent: test\r\n
137 137 s> x-hgproto-1: cbor\r\n
138 138 s> x-hgupgrade-1: foo bar\r\n
139 139 s> host: $LOCALIP:$HGPORT\r\n (glob)
140 140 s> \r\n
141 141 s> makefile('rb', None)
142 142 s> HTTP/1.1 200 OK\r\n
143 143 s> Server: testing stub value\r\n
144 144 s> Date: $HTTP_DATE$\r\n
145 145 s> Content-Type: application/mercurial-cbor\r\n
146 146 s> Content-Length: *\r\n (glob)
147 147 s> \r\n
148 148 s> \xa3GapibaseDapi/Dapis\xa0Nv1capabilitiesY\x01\xd3batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
149 149 cbor> {
150 150 b'apibase': b'api/',
151 151 b'apis': {},
152 152 b'v1capabilities': b'batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash'
153 153 }
154 154
155 155 Restart server to enable HTTPv2
156 156
157 157 $ killdaemons.py
158 158 $ enablehttpv2 server
159 159 $ hg -R server serve -p $HGPORT -d --pid-file hg.pid -E error.log
160 160 $ cat hg.pid > $DAEMON_PIDS
161 161
162 162 Only requested API services are returned
163 163
164 164 $ sendhttpraw << EOF
165 165 > httprequest GET ?cmd=capabilities
166 166 > user-agent: test
167 167 > x-hgupgrade-1: foo bar
168 168 > x-hgproto-1: cbor
169 169 > EOF
170 170 using raw connection to peer
171 171 s> GET /?cmd=capabilities HTTP/1.1\r\n
172 172 s> Accept-Encoding: identity\r\n
173 173 s> user-agent: test\r\n
174 174 s> x-hgproto-1: cbor\r\n
175 175 s> x-hgupgrade-1: foo bar\r\n
176 176 s> host: $LOCALIP:$HGPORT\r\n (glob)
177 177 s> \r\n
178 178 s> makefile('rb', None)
179 179 s> HTTP/1.1 200 OK\r\n
180 180 s> Server: testing stub value\r\n
181 181 s> Date: $HTTP_DATE$\r\n
182 182 s> Content-Type: application/mercurial-cbor\r\n
183 183 s> Content-Length: *\r\n (glob)
184 184 s> \r\n
185 185 s> \xa3GapibaseDapi/Dapis\xa0Nv1capabilitiesY\x01\xd3batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
186 186 cbor> {
187 187 b'apibase': b'api/',
188 188 b'apis': {},
189 189 b'v1capabilities': b'batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash'
190 190 }
191 191
192 192 Request for HTTPv2 service returns information about it
193 193
194 194 $ sendhttpraw << EOF
195 195 > httprequest GET ?cmd=capabilities
196 196 > user-agent: test
197 > x-hgupgrade-1: exp-http-v2-0001 foo bar
197 > x-hgupgrade-1: exp-http-v2-0002 foo bar
198 198 > x-hgproto-1: cbor
199 199 > EOF
200 200 using raw connection to peer
201 201 s> GET /?cmd=capabilities HTTP/1.1\r\n
202 202 s> Accept-Encoding: identity\r\n
203 203 s> user-agent: test\r\n
204 204 s> x-hgproto-1: cbor\r\n
205 s> x-hgupgrade-1: exp-http-v2-0001 foo bar\r\n
205 s> x-hgupgrade-1: exp-http-v2-0002 foo bar\r\n
206 206 s> host: $LOCALIP:$HGPORT\r\n (glob)
207 207 s> \r\n
208 208 s> makefile('rb', None)
209 209 s> HTTP/1.1 200 OK\r\n
210 210 s> Server: testing stub value\r\n
211 211 s> Date: $HTTP_DATE$\r\n
212 212 s> Content-Type: application/mercurial-cbor\r\n
213 213 s> Content-Length: *\r\n (glob)
214 214 s> \r\n
215 s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0001\xa5Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa3Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionInoderange\xa3Gdefault\xf6Hrequired\xf4DtypeDlistEnodes\xa3Gdefault\xf6Hrequired\xf4DtypeDlistKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullGpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushKcompression\x81\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x82LgeneraldeltaHrevlogv1Nv1capabilitiesY\x01\xd3batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
215 s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0002\xa5Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa3Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionInoderange\xa3Gdefault\xf6Hrequired\xf4DtypeDlistEnodes\xa3Gdefault\xf6Hrequired\xf4DtypeDlistKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullGpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushKcompression\x81\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x82LgeneraldeltaHrevlogv1Nv1capabilitiesY\x01\xd3batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
216 216 cbor> {
217 217 b'apibase': b'api/',
218 218 b'apis': {
219 b'exp-http-v2-0001': {
219 b'exp-http-v2-0002': {
220 220 b'commands': {
221 221 b'branchmap': {
222 222 b'args': {},
223 223 b'permissions': [
224 224 b'pull'
225 225 ]
226 226 },
227 227 b'capabilities': {
228 228 b'args': {},
229 229 b'permissions': [
230 230 b'pull'
231 231 ]
232 232 },
233 233 b'changesetdata': {
234 234 b'args': {
235 235 b'fields': {
236 236 b'default': set([]),
237 237 b'required': False,
238 238 b'type': b'set',
239 239 b'validvalues': set([
240 240 b'bookmarks',
241 241 b'parents',
242 242 b'phase',
243 243 b'revision'
244 244 ])
245 245 },
246 246 b'noderange': {
247 247 b'default': None,
248 248 b'required': False,
249 249 b'type': b'list'
250 250 },
251 251 b'nodes': {
252 252 b'default': None,
253 253 b'required': False,
254 254 b'type': b'list'
255 255 }
256 256 },
257 257 b'permissions': [
258 258 b'pull'
259 259 ]
260 260 },
261 261 b'filedata': {
262 262 b'args': {
263 263 b'fields': {
264 264 b'default': set([]),
265 265 b'required': False,
266 266 b'type': b'set',
267 267 b'validvalues': set([
268 268 b'parents',
269 269 b'revision'
270 270 ])
271 271 },
272 272 b'haveparents': {
273 273 b'default': False,
274 274 b'required': False,
275 275 b'type': b'bool'
276 276 },
277 277 b'nodes': {
278 278 b'required': True,
279 279 b'type': b'list'
280 280 },
281 281 b'path': {
282 282 b'required': True,
283 283 b'type': b'bytes'
284 284 }
285 285 },
286 286 b'permissions': [
287 287 b'pull'
288 288 ]
289 289 },
290 290 b'heads': {
291 291 b'args': {
292 292 b'publiconly': {
293 293 b'default': False,
294 294 b'required': False,
295 295 b'type': b'bool'
296 296 }
297 297 },
298 298 b'permissions': [
299 299 b'pull'
300 300 ]
301 301 },
302 302 b'known': {
303 303 b'args': {
304 304 b'nodes': {
305 305 b'default': [],
306 306 b'required': False,
307 307 b'type': b'list'
308 308 }
309 309 },
310 310 b'permissions': [
311 311 b'pull'
312 312 ]
313 313 },
314 314 b'listkeys': {
315 315 b'args': {
316 316 b'namespace': {
317 317 b'required': True,
318 318 b'type': b'bytes'
319 319 }
320 320 },
321 321 b'permissions': [
322 322 b'pull'
323 323 ]
324 324 },
325 325 b'lookup': {
326 326 b'args': {
327 327 b'key': {
328 328 b'required': True,
329 329 b'type': b'bytes'
330 330 }
331 331 },
332 332 b'permissions': [
333 333 b'pull'
334 334 ]
335 335 },
336 336 b'manifestdata': {
337 337 b'args': {
338 338 b'fields': {
339 339 b'default': set([]),
340 340 b'required': False,
341 341 b'type': b'set',
342 342 b'validvalues': set([
343 343 b'parents',
344 344 b'revision'
345 345 ])
346 346 },
347 347 b'haveparents': {
348 348 b'default': False,
349 349 b'required': False,
350 350 b'type': b'bool'
351 351 },
352 352 b'nodes': {
353 353 b'required': True,
354 354 b'type': b'list'
355 355 },
356 356 b'tree': {
357 357 b'required': True,
358 358 b'type': b'bytes'
359 359 }
360 360 },
361 361 b'permissions': [
362 362 b'pull'
363 363 ]
364 364 },
365 365 b'pushkey': {
366 366 b'args': {
367 367 b'key': {
368 368 b'required': True,
369 369 b'type': b'bytes'
370 370 },
371 371 b'namespace': {
372 372 b'required': True,
373 373 b'type': b'bytes'
374 374 },
375 375 b'new': {
376 376 b'required': True,
377 377 b'type': b'bytes'
378 378 },
379 379 b'old': {
380 380 b'required': True,
381 381 b'type': b'bytes'
382 382 }
383 383 },
384 384 b'permissions': [
385 385 b'push'
386 386 ]
387 387 }
388 388 },
389 389 b'compression': [
390 390 {
391 391 b'name': b'zlib'
392 392 }
393 393 ],
394 394 b'framingmediatypes': [
395 395 b'application/mercurial-exp-framing-0005'
396 396 ],
397 397 b'pathfilterprefixes': set([
398 398 b'path:',
399 399 b'rootfilesin:'
400 400 ]),
401 401 b'rawrepoformats': [
402 402 b'generaldelta',
403 403 b'revlogv1'
404 404 ]
405 405 }
406 406 },
407 407 b'v1capabilities': b'batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash'
408 408 }
409 409
410 410 capabilities command returns expected info
411 411
412 412 $ sendhttpv2peerhandshake << EOF
413 413 > command capabilities
414 414 > EOF
415 415 creating http peer for wire protocol version 2
416 416 s> GET /?cmd=capabilities HTTP/1.1\r\n
417 417 s> Accept-Encoding: identity\r\n
418 418 s> vary: X-HgProto-1,X-HgUpgrade-1\r\n
419 419 s> x-hgproto-1: cbor\r\n
420 s> x-hgupgrade-1: exp-http-v2-0001\r\n
420 s> x-hgupgrade-1: exp-http-v2-0002\r\n
421 421 s> accept: application/mercurial-0.1\r\n
422 422 s> host: $LOCALIP:$HGPORT\r\n (glob)
423 423 s> user-agent: Mercurial debugwireproto\r\n
424 424 s> \r\n
425 425 s> makefile('rb', None)
426 426 s> HTTP/1.1 200 OK\r\n
427 427 s> Server: testing stub value\r\n
428 428 s> Date: $HTTP_DATE$\r\n
429 429 s> Content-Type: application/mercurial-cbor\r\n
430 430 s> Content-Length: *\r\n (glob)
431 431 s> \r\n
432 s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0001\xa5Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa3Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionInoderange\xa3Gdefault\xf6Hrequired\xf4DtypeDlistEnodes\xa3Gdefault\xf6Hrequired\xf4DtypeDlistKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullGpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushKcompression\x81\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x82LgeneraldeltaHrevlogv1Nv1capabilitiesY\x01\xd3batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
432 s> \xa3GapibaseDapi/Dapis\xa1Pexp-http-v2-0002\xa5Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa3Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionInoderange\xa3Gdefault\xf6Hrequired\xf4DtypeDlistEnodes\xa3Gdefault\xf6Hrequired\xf4DtypeDlistKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullGpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushKcompression\x81\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x82LgeneraldeltaHrevlogv1Nv1capabilitiesY\x01\xd3batch branchmap $USUAL_BUNDLE2_CAPS$ changegroupsubset compression=$BUNDLE2_COMPRESSIONS$ getbundle httpheader=1024 httpmediatype=0.1rx,0.1tx,0.2tx known lookup pushkey streamreqs=generaldelta,revlogv1 unbundle=HG10GZ,HG10BZ,HG10UN unbundlehash
433 433 sending capabilities command
434 s> POST /api/exp-http-v2-0001/ro/capabilities HTTP/1.1\r\n
434 s> POST /api/exp-http-v2-0002/ro/capabilities HTTP/1.1\r\n
435 435 s> Accept-Encoding: identity\r\n
436 436 s> accept: application/mercurial-exp-framing-0005\r\n
437 437 s> content-type: application/mercurial-exp-framing-0005\r\n
438 438 s> content-length: 27\r\n
439 439 s> host: $LOCALIP:$HGPORT\r\n (glob)
440 440 s> user-agent: Mercurial debugwireproto\r\n
441 441 s> \r\n
442 442 s> \x13\x00\x00\x01\x00\x01\x01\x11\xa1DnameLcapabilities
443 443 s> makefile('rb', None)
444 444 s> HTTP/1.1 200 OK\r\n
445 445 s> Server: testing stub value\r\n
446 446 s> Date: $HTTP_DATE$\r\n
447 447 s> Content-Type: application/mercurial-exp-framing-0005\r\n
448 448 s> Transfer-Encoding: chunked\r\n
449 449 s> \r\n
450 450 s> 13\r\n
451 451 s> \x0b\x00\x00\x01\x00\x02\x011
452 452 s> \xa1FstatusBok
453 453 s> \r\n
454 454 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
455 455 s> 4f8\r\n
456 456 s> \xf0\x04\x00\x01\x00\x02\x001
457 457 s> \xa5Hcommands\xaaIbranchmap\xa2Dargs\xa0Kpermissions\x81DpullLcapabilities\xa2Dargs\xa0Kpermissions\x81DpullMchangesetdata\xa2Dargs\xa3Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x84IbookmarksGparentsEphaseHrevisionInoderange\xa3Gdefault\xf6Hrequired\xf4DtypeDlistEnodes\xa3Gdefault\xf6Hrequired\xf4DtypeDlistKpermissions\x81DpullHfiledata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDpath\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullEheads\xa2Dargs\xa1Jpubliconly\xa3Gdefault\xf4Hrequired\xf4DtypeDboolKpermissions\x81DpullEknown\xa2Dargs\xa1Enodes\xa3Gdefault\x80Hrequired\xf4DtypeDlistKpermissions\x81DpullHlistkeys\xa2Dargs\xa1Inamespace\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullFlookup\xa2Dargs\xa1Ckey\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullLmanifestdata\xa2Dargs\xa4Ffields\xa4Gdefault\xd9\x01\x02\x80Hrequired\xf4DtypeCsetKvalidvalues\xd9\x01\x02\x82GparentsHrevisionKhaveparents\xa3Gdefault\xf4Hrequired\xf4DtypeDboolEnodes\xa2Hrequired\xf5DtypeDlistDtree\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpullGpushkey\xa2Dargs\xa4Ckey\xa2Hrequired\xf5DtypeEbytesInamespace\xa2Hrequired\xf5DtypeEbytesCnew\xa2Hrequired\xf5DtypeEbytesCold\xa2Hrequired\xf5DtypeEbytesKpermissions\x81DpushKcompression\x81\xa1DnameDzlibQframingmediatypes\x81X&application/mercurial-exp-framing-0005Rpathfilterprefixes\xd9\x01\x02\x82Epath:Lrootfilesin:Nrawrepoformats\x82LgeneraldeltaHrevlogv1
458 458 s> \r\n
459 459 received frame(size=1264; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
460 460 s> 8\r\n
461 461 s> \x00\x00\x00\x01\x00\x02\x002
462 462 s> \r\n
463 463 s> 0\r\n
464 464 s> \r\n
465 465 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
466 466 response: gen[
467 467 {
468 468 b'commands': {
469 469 b'branchmap': {
470 470 b'args': {},
471 471 b'permissions': [
472 472 b'pull'
473 473 ]
474 474 },
475 475 b'capabilities': {
476 476 b'args': {},
477 477 b'permissions': [
478 478 b'pull'
479 479 ]
480 480 },
481 481 b'changesetdata': {
482 482 b'args': {
483 483 b'fields': {
484 484 b'default': set([]),
485 485 b'required': False,
486 486 b'type': b'set',
487 487 b'validvalues': set([
488 488 b'bookmarks',
489 489 b'parents',
490 490 b'phase',
491 491 b'revision'
492 492 ])
493 493 },
494 494 b'noderange': {
495 495 b'default': None,
496 496 b'required': False,
497 497 b'type': b'list'
498 498 },
499 499 b'nodes': {
500 500 b'default': None,
501 501 b'required': False,
502 502 b'type': b'list'
503 503 }
504 504 },
505 505 b'permissions': [
506 506 b'pull'
507 507 ]
508 508 },
509 509 b'filedata': {
510 510 b'args': {
511 511 b'fields': {
512 512 b'default': set([]),
513 513 b'required': False,
514 514 b'type': b'set',
515 515 b'validvalues': set([
516 516 b'parents',
517 517 b'revision'
518 518 ])
519 519 },
520 520 b'haveparents': {
521 521 b'default': False,
522 522 b'required': False,
523 523 b'type': b'bool'
524 524 },
525 525 b'nodes': {
526 526 b'required': True,
527 527 b'type': b'list'
528 528 },
529 529 b'path': {
530 530 b'required': True,
531 531 b'type': b'bytes'
532 532 }
533 533 },
534 534 b'permissions': [
535 535 b'pull'
536 536 ]
537 537 },
538 538 b'heads': {
539 539 b'args': {
540 540 b'publiconly': {
541 541 b'default': False,
542 542 b'required': False,
543 543 b'type': b'bool'
544 544 }
545 545 },
546 546 b'permissions': [
547 547 b'pull'
548 548 ]
549 549 },
550 550 b'known': {
551 551 b'args': {
552 552 b'nodes': {
553 553 b'default': [],
554 554 b'required': False,
555 555 b'type': b'list'
556 556 }
557 557 },
558 558 b'permissions': [
559 559 b'pull'
560 560 ]
561 561 },
562 562 b'listkeys': {
563 563 b'args': {
564 564 b'namespace': {
565 565 b'required': True,
566 566 b'type': b'bytes'
567 567 }
568 568 },
569 569 b'permissions': [
570 570 b'pull'
571 571 ]
572 572 },
573 573 b'lookup': {
574 574 b'args': {
575 575 b'key': {
576 576 b'required': True,
577 577 b'type': b'bytes'
578 578 }
579 579 },
580 580 b'permissions': [
581 581 b'pull'
582 582 ]
583 583 },
584 584 b'manifestdata': {
585 585 b'args': {
586 586 b'fields': {
587 587 b'default': set([]),
588 588 b'required': False,
589 589 b'type': b'set',
590 590 b'validvalues': set([
591 591 b'parents',
592 592 b'revision'
593 593 ])
594 594 },
595 595 b'haveparents': {
596 596 b'default': False,
597 597 b'required': False,
598 598 b'type': b'bool'
599 599 },
600 600 b'nodes': {
601 601 b'required': True,
602 602 b'type': b'list'
603 603 },
604 604 b'tree': {
605 605 b'required': True,
606 606 b'type': b'bytes'
607 607 }
608 608 },
609 609 b'permissions': [
610 610 b'pull'
611 611 ]
612 612 },
613 613 b'pushkey': {
614 614 b'args': {
615 615 b'key': {
616 616 b'required': True,
617 617 b'type': b'bytes'
618 618 },
619 619 b'namespace': {
620 620 b'required': True,
621 621 b'type': b'bytes'
622 622 },
623 623 b'new': {
624 624 b'required': True,
625 625 b'type': b'bytes'
626 626 },
627 627 b'old': {
628 628 b'required': True,
629 629 b'type': b'bytes'
630 630 }
631 631 },
632 632 b'permissions': [
633 633 b'push'
634 634 ]
635 635 }
636 636 },
637 637 b'compression': [
638 638 {
639 639 b'name': b'zlib'
640 640 }
641 641 ],
642 642 b'framingmediatypes': [
643 643 b'application/mercurial-exp-framing-0005'
644 644 ],
645 645 b'pathfilterprefixes': set([
646 646 b'path:',
647 647 b'rootfilesin:'
648 648 ]),
649 649 b'rawrepoformats': [
650 650 b'generaldelta',
651 651 b'revlogv1'
652 652 ]
653 653 }
654 654 ]
655 655
656 656 $ cat error.log
@@ -1,846 +1,881 b''
1 1 $ . $TESTDIR/wireprotohelpers.sh
2 2
3 3 $ hg init server
4 4 $ enablehttpv2 server
5 5 $ cd server
6 6 $ cat >> .hg/hgrc << EOF
7 7 > [phases]
8 8 > publish = false
9 9 > EOF
10 10 $ echo a0 > a
11 11 $ echo b0 > b
12 12
13 13 $ hg -q commit -A -m 'commit 0'
14 14
15 15 $ echo a1 > a
16 16 $ echo b1 > b
17 17 $ hg commit -m 'commit 1'
18 18 $ echo b2 > b
19 19 $ hg commit -m 'commit 2'
20 20 $ hg phase --public -r .
21 21
22 22 $ hg -q up -r 0
23 23 $ echo a2 > a
24 24 $ hg commit -m 'commit 3'
25 25 created new head
26 26
27 27 $ hg log -G -T '{rev}:{node} {desc}\n'
28 28 @ 3:eae5f82c2e622368d27daecb76b7e393d0f24211 commit 3
29 29 |
30 30 | o 2:0bb8ad894a15b15380b2a2a5b183e20f2a4b28dd commit 2
31 31 | |
32 32 | o 1:7592917e1c3e82677cb0a4bc715ca25dd12d28c1 commit 1
33 33 |/
34 34 o 0:3390ef850073fbc2f0dfff2244342c8e9229013a commit 0
35 35
36 36
37 37 $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
38 38 $ cat hg.pid > $DAEMON_PIDS
39 39
40 40 No arguments is an invalid request
41 41
42 42 $ sendhttpv2peer << EOF
43 43 > command changesetdata
44 44 > EOF
45 45 creating http peer for wire protocol version 2
46 46 sending changesetdata command
47 s> POST /api/exp-http-v2-0001/ro/changesetdata HTTP/1.1\r\n
47 s> POST /api/exp-http-v2-0002/ro/changesetdata HTTP/1.1\r\n
48 48 s> Accept-Encoding: identity\r\n
49 49 s> accept: application/mercurial-exp-framing-0005\r\n
50 50 s> content-type: application/mercurial-exp-framing-0005\r\n
51 51 s> content-length: 28\r\n
52 52 s> host: $LOCALIP:$HGPORT\r\n (glob)
53 53 s> user-agent: Mercurial debugwireproto\r\n
54 54 s> \r\n
55 55 s> \x14\x00\x00\x01\x00\x01\x01\x11\xa1DnameMchangesetdata
56 56 s> makefile('rb', None)
57 57 s> HTTP/1.1 200 OK\r\n
58 58 s> Server: testing stub value\r\n
59 59 s> Date: $HTTP_DATE$\r\n
60 60 s> Content-Type: application/mercurial-exp-framing-0005\r\n
61 61 s> Transfer-Encoding: chunked\r\n
62 62 s> \r\n
63 63 s> 49\r\n
64 64 s> A\x00\x00\x01\x00\x02\x012
65 65 s> \xa2Eerror\xa1GmessageX"noderange or nodes must be definedFstatusEerror
66 66 s> \r\n
67 67 received frame(size=65; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos)
68 68 s> 0\r\n
69 69 s> \r\n
70 70 abort: noderange or nodes must be defined!
71 71 [255]
72 72
73 73 Empty noderange heads results in an error
74 74
75 75 $ sendhttpv2peer << EOF
76 76 > command changesetdata
77 77 > noderange eval:[[],[]]
78 78 > EOF
79 79 creating http peer for wire protocol version 2
80 80 sending changesetdata command
81 s> POST /api/exp-http-v2-0001/ro/changesetdata HTTP/1.1\r\n
81 s> POST /api/exp-http-v2-0002/ro/changesetdata HTTP/1.1\r\n
82 82 s> Accept-Encoding: identity\r\n
83 83 s> accept: application/mercurial-exp-framing-0005\r\n
84 84 s> content-type: application/mercurial-exp-framing-0005\r\n
85 85 s> content-length: 47\r\n
86 86 s> host: $LOCALIP:$HGPORT\r\n (glob)
87 87 s> user-agent: Mercurial debugwireproto\r\n
88 88 s> \r\n
89 89 s> \'\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa1Inoderange\x82\x80\x80DnameMchangesetdata
90 90 s> makefile('rb', None)
91 91 s> HTTP/1.1 200 OK\r\n
92 92 s> Server: testing stub value\r\n
93 93 s> Date: $HTTP_DATE$\r\n
94 94 s> Content-Type: application/mercurial-exp-framing-0005\r\n
95 95 s> Transfer-Encoding: chunked\r\n
96 96 s> \r\n
97 97 s> 51\r\n
98 98 s> I\x00\x00\x01\x00\x02\x012
99 99 s> \xa2Eerror\xa1GmessageX*heads in noderange request cannot be emptyFstatusEerror
100 100 s> \r\n
101 101 received frame(size=73; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos)
102 102 s> 0\r\n
103 103 s> \r\n
104 104 abort: heads in noderange request cannot be empty!
105 105 [255]
106 106
107 107 Sending just noderange heads sends all revisions
108 108
109 109 $ sendhttpv2peer << EOF
110 110 > command changesetdata
111 111 > noderange eval:[[], [b'\x0b\xb8\xad\x89\x4a\x15\xb1\x53\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f\x2a\x4b\x28\xdd', b'\xea\xe5\xf8\x2c\x2e\x62\x23\x68\xd2\x7d\xae\xcb\x76\xb7\xe3\x93\xd0\xf2\x42\x11']]
112 112 > EOF
113 113 creating http peer for wire protocol version 2
114 114 sending changesetdata command
115 s> POST /api/exp-http-v2-0001/ro/changesetdata HTTP/1.1\r\n
115 s> POST /api/exp-http-v2-0002/ro/changesetdata HTTP/1.1\r\n
116 116 s> Accept-Encoding: identity\r\n
117 117 s> accept: application/mercurial-exp-framing-0005\r\n
118 118 s> content-type: application/mercurial-exp-framing-0005\r\n
119 119 s> content-length: 89\r\n
120 120 s> host: $LOCALIP:$HGPORT\r\n (glob)
121 121 s> user-agent: Mercurial debugwireproto\r\n
122 122 s> \r\n
123 123 s> Q\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa1Inoderange\x82\x80\x82T\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xddT\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11DnameMchangesetdata
124 124 s> makefile('rb', None)
125 125 s> HTTP/1.1 200 OK\r\n
126 126 s> Server: testing stub value\r\n
127 127 s> Date: $HTTP_DATE$\r\n
128 128 s> Content-Type: application/mercurial-exp-framing-0005\r\n
129 129 s> Transfer-Encoding: chunked\r\n
130 130 s> \r\n
131 131 s> 13\r\n
132 132 s> \x0b\x00\x00\x01\x00\x02\x011
133 133 s> \xa1FstatusBok
134 134 s> \r\n
135 135 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
136 136 s> 81\r\n
137 137 s> y\x00\x00\x01\x00\x02\x001
138 138 s> \xa1Jtotalitems\x04\xa1DnodeT3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:\xa1DnodeTu\x92\x91~\x1c>\x82g|\xb0\xa4\xbcq\\\xa2]\xd1-(\xc1\xa1DnodeT\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xdd\xa1DnodeT\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11
139 139 s> \r\n
140 140 received frame(size=121; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
141 141 s> 8\r\n
142 142 s> \x00\x00\x00\x01\x00\x02\x002
143 143 s> \r\n
144 144 s> 0\r\n
145 145 s> \r\n
146 146 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
147 147 response: gen[
148 148 {
149 149 b'totalitems': 4
150 150 },
151 151 {
152 152 b'node': b'3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:'
153 153 },
154 154 {
155 155 b'node': b'u\x92\x91~\x1c>\x82g|\xb0\xa4\xbcq\\\xa2]\xd1-(\xc1'
156 156 },
157 157 {
158 158 b'node': b'\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xdd'
159 159 },
160 160 {
161 161 b'node': b'\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11'
162 162 }
163 163 ]
164 164
165 165 Sending root nodes limits what data is sent
166 166
167 167 $ sendhttpv2peer << EOF
168 168 > command changesetdata
169 169 > noderange eval:[[b'\x33\x90\xef\x85\x00\x73\xfb\xc2\xf0\xdf\xff\x22\x44\x34\x2c\x8e\x92\x29\x01\x3a'], [b'\x0b\xb8\xad\x89\x4a\x15\xb1\x53\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f\x2a\x4b\x28\xdd']]
170 170 > EOF
171 171 creating http peer for wire protocol version 2
172 172 sending changesetdata command
173 s> POST /api/exp-http-v2-0001/ro/changesetdata HTTP/1.1\r\n
173 s> POST /api/exp-http-v2-0002/ro/changesetdata HTTP/1.1\r\n
174 174 s> Accept-Encoding: identity\r\n
175 175 s> accept: application/mercurial-exp-framing-0005\r\n
176 176 s> content-type: application/mercurial-exp-framing-0005\r\n
177 177 s> content-length: 89\r\n
178 178 s> host: $LOCALIP:$HGPORT\r\n (glob)
179 179 s> user-agent: Mercurial debugwireproto\r\n
180 180 s> \r\n
181 181 s> Q\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa1Inoderange\x82\x81T3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:\x81T\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xddDnameMchangesetdata
182 182 s> makefile('rb', None)
183 183 s> HTTP/1.1 200 OK\r\n
184 184 s> Server: testing stub value\r\n
185 185 s> Date: $HTTP_DATE$\r\n
186 186 s> Content-Type: application/mercurial-exp-framing-0005\r\n
187 187 s> Transfer-Encoding: chunked\r\n
188 188 s> \r\n
189 189 s> 13\r\n
190 190 s> \x0b\x00\x00\x01\x00\x02\x011
191 191 s> \xa1FstatusBok
192 192 s> \r\n
193 193 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
194 194 s> 4b\r\n
195 195 s> C\x00\x00\x01\x00\x02\x001
196 196 s> \xa1Jtotalitems\x02\xa1DnodeTu\x92\x91~\x1c>\x82g|\xb0\xa4\xbcq\\\xa2]\xd1-(\xc1\xa1DnodeT\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xdd
197 197 s> \r\n
198 198 received frame(size=67; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
199 199 s> 8\r\n
200 200 s> \x00\x00\x00\x01\x00\x02\x002
201 201 s> \r\n
202 202 s> 0\r\n
203 203 s> \r\n
204 204 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
205 205 response: gen[
206 206 {
207 207 b'totalitems': 2
208 208 },
209 209 {
210 210 b'node': b'u\x92\x91~\x1c>\x82g|\xb0\xa4\xbcq\\\xa2]\xd1-(\xc1'
211 211 },
212 212 {
213 213 b'node': b'\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xdd'
214 214 }
215 215 ]
216 216
217 217 Requesting data on a single node by node works
218 218
219 219 $ sendhttpv2peer << EOF
220 220 > command changesetdata
221 221 > nodes eval:[b'\x33\x90\xef\x85\x00\x73\xfb\xc2\xf0\xdf\xff\x22\x44\x34\x2c\x8e\x92\x29\x01\x3a']
222 222 > EOF
223 223 creating http peer for wire protocol version 2
224 224 sending changesetdata command
225 s> POST /api/exp-http-v2-0001/ro/changesetdata HTTP/1.1\r\n
225 s> POST /api/exp-http-v2-0002/ro/changesetdata HTTP/1.1\r\n
226 226 s> Accept-Encoding: identity\r\n
227 227 s> accept: application/mercurial-exp-framing-0005\r\n
228 228 s> content-type: application/mercurial-exp-framing-0005\r\n
229 229 s> content-length: 62\r\n
230 230 s> host: $LOCALIP:$HGPORT\r\n (glob)
231 231 s> user-agent: Mercurial debugwireproto\r\n
232 232 s> \r\n
233 233 s> 6\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa1Enodes\x81T3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:DnameMchangesetdata
234 234 s> makefile('rb', None)
235 235 s> HTTP/1.1 200 OK\r\n
236 236 s> Server: testing stub value\r\n
237 237 s> Date: $HTTP_DATE$\r\n
238 238 s> Content-Type: application/mercurial-exp-framing-0005\r\n
239 239 s> Transfer-Encoding: chunked\r\n
240 240 s> \r\n
241 241 s> 13\r\n
242 242 s> \x0b\x00\x00\x01\x00\x02\x011
243 243 s> \xa1FstatusBok
244 244 s> \r\n
245 245 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
246 246 s> 30\r\n
247 247 s> (\x00\x00\x01\x00\x02\x001
248 248 s> \xa1Jtotalitems\x01\xa1DnodeT3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:
249 249 s> \r\n
250 250 received frame(size=40; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
251 251 s> 8\r\n
252 252 s> \x00\x00\x00\x01\x00\x02\x002
253 253 s> \r\n
254 254 s> 0\r\n
255 255 s> \r\n
256 256 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
257 257 response: gen[
258 258 {
259 259 b'totalitems': 1
260 260 },
261 261 {
262 262 b'node': b'3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:'
263 263 }
264 264 ]
265 265
266 266 Specifying a noderange and nodes takes union
267 267
268 268 $ sendhttpv2peer << EOF
269 269 > command changesetdata
270 270 > noderange eval:[[b'\x75\x92\x91\x7e\x1c\x3e\x82\x67\x7c\xb0\xa4\xbc\x71\x5c\xa2\x5d\xd1\x2d\x28\xc1'], [b'\x0b\xb8\xad\x89\x4a\x15\xb1\x53\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f\x2a\x4b\x28\xdd']]
271 271 > nodes eval:[b'\xea\xe5\xf8\x2c\x2e\x62\x23\x68\xd2\x7d\xae\xcb\x76\xb7\xe3\x93\xd0\xf2\x42\x11']
272 272 > EOF
273 273 creating http peer for wire protocol version 2
274 274 sending changesetdata command
275 s> POST /api/exp-http-v2-0001/ro/changesetdata HTTP/1.1\r\n
275 s> POST /api/exp-http-v2-0002/ro/changesetdata HTTP/1.1\r\n
276 276 s> Accept-Encoding: identity\r\n
277 277 s> accept: application/mercurial-exp-framing-0005\r\n
278 278 s> content-type: application/mercurial-exp-framing-0005\r\n
279 279 s> content-length: 117\r\n
280 280 s> host: $LOCALIP:$HGPORT\r\n (glob)
281 281 s> user-agent: Mercurial debugwireproto\r\n
282 282 s> \r\n
283 283 s> m\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa2Inoderange\x82\x81Tu\x92\x91~\x1c>\x82g|\xb0\xa4\xbcq\\\xa2]\xd1-(\xc1\x81T\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xddEnodes\x81T\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11DnameMchangesetdata
284 284 s> makefile('rb', None)
285 285 s> HTTP/1.1 200 OK\r\n
286 286 s> Server: testing stub value\r\n
287 287 s> Date: $HTTP_DATE$\r\n
288 288 s> Content-Type: application/mercurial-exp-framing-0005\r\n
289 289 s> Transfer-Encoding: chunked\r\n
290 290 s> \r\n
291 291 s> 13\r\n
292 292 s> \x0b\x00\x00\x01\x00\x02\x011
293 293 s> \xa1FstatusBok
294 294 s> \r\n
295 295 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
296 296 s> 4b\r\n
297 297 s> C\x00\x00\x01\x00\x02\x001
298 298 s> \xa1Jtotalitems\x02\xa1DnodeT\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11\xa1DnodeT\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xdd
299 299 s> \r\n
300 300 received frame(size=67; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
301 301 s> 8\r\n
302 302 s> \x00\x00\x00\x01\x00\x02\x002
303 303 s> \r\n
304 304 s> 0\r\n
305 305 s> \r\n
306 306 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
307 307 response: gen[
308 308 {
309 309 b'totalitems': 2
310 310 },
311 311 {
312 312 b'node': b'\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11'
313 313 },
314 314 {
315 315 b'node': b'\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xdd'
316 316 }
317 317 ]
318 318
319 319 Parents data is transferred upon request
320 320
321 321 $ sendhttpv2peer << EOF
322 322 > command changesetdata
323 323 > fields eval:[b'parents']
324 324 > nodes eval:[b'\xea\xe5\xf8\x2c\x2e\x62\x23\x68\xd2\x7d\xae\xcb\x76\xb7\xe3\x93\xd0\xf2\x42\x11']
325 325 > EOF
326 326 creating http peer for wire protocol version 2
327 327 sending changesetdata command
328 s> POST /api/exp-http-v2-0001/ro/changesetdata HTTP/1.1\r\n
328 s> POST /api/exp-http-v2-0002/ro/changesetdata HTTP/1.1\r\n
329 329 s> Accept-Encoding: identity\r\n
330 330 s> accept: application/mercurial-exp-framing-0005\r\n
331 331 s> content-type: application/mercurial-exp-framing-0005\r\n
332 332 s> content-length: 78\r\n
333 333 s> host: $LOCALIP:$HGPORT\r\n (glob)
334 334 s> user-agent: Mercurial debugwireproto\r\n
335 335 s> \r\n
336 336 s> F\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa2Ffields\x81GparentsEnodes\x81T\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11DnameMchangesetdata
337 337 s> makefile('rb', None)
338 338 s> HTTP/1.1 200 OK\r\n
339 339 s> Server: testing stub value\r\n
340 340 s> Date: $HTTP_DATE$\r\n
341 341 s> Content-Type: application/mercurial-exp-framing-0005\r\n
342 342 s> Transfer-Encoding: chunked\r\n
343 343 s> \r\n
344 344 s> 13\r\n
345 345 s> \x0b\x00\x00\x01\x00\x02\x011
346 346 s> \xa1FstatusBok
347 347 s> \r\n
348 348 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
349 349 s> 63\r\n
350 350 s> [\x00\x00\x01\x00\x02\x001
351 351 s> \xa1Jtotalitems\x01\xa2DnodeT\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11Gparents\x82T3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
352 352 s> \r\n
353 353 received frame(size=91; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
354 354 s> 8\r\n
355 355 s> \x00\x00\x00\x01\x00\x02\x002
356 356 s> \r\n
357 357 s> 0\r\n
358 358 s> \r\n
359 359 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
360 360 response: gen[
361 361 {
362 362 b'totalitems': 1
363 363 },
364 364 {
365 365 b'node': b'\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11',
366 366 b'parents': [
367 367 b'3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:',
368 368 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
369 369 ]
370 370 }
371 371 ]
372 372
373 373 Phase data is transferred upon request
374 374
375 375 $ sendhttpv2peer << EOF
376 376 > command changesetdata
377 377 > fields eval:[b'phase']
378 378 > nodes eval:[b'\x0b\xb8\xad\x89\x4a\x15\xb1\x53\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f\x2a\x4b\x28\xdd']
379 379 > EOF
380 380 creating http peer for wire protocol version 2
381 381 sending changesetdata command
382 s> POST /api/exp-http-v2-0001/ro/changesetdata HTTP/1.1\r\n
382 s> POST /api/exp-http-v2-0002/ro/changesetdata HTTP/1.1\r\n
383 383 s> Accept-Encoding: identity\r\n
384 384 s> accept: application/mercurial-exp-framing-0005\r\n
385 385 s> content-type: application/mercurial-exp-framing-0005\r\n
386 386 s> content-length: 76\r\n
387 387 s> host: $LOCALIP:$HGPORT\r\n (glob)
388 388 s> user-agent: Mercurial debugwireproto\r\n
389 389 s> \r\n
390 390 s> D\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa2Ffields\x81EphaseEnodes\x81T\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xddDnameMchangesetdata
391 391 s> makefile('rb', None)
392 392 s> HTTP/1.1 200 OK\r\n
393 393 s> Server: testing stub value\r\n
394 394 s> Date: $HTTP_DATE$\r\n
395 395 s> Content-Type: application/mercurial-exp-framing-0005\r\n
396 396 s> Transfer-Encoding: chunked\r\n
397 397 s> \r\n
398 398 s> 13\r\n
399 399 s> \x0b\x00\x00\x01\x00\x02\x011
400 400 s> \xa1FstatusBok
401 401 s> \r\n
402 402 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
403 403 s> 3d\r\n
404 404 s> 5\x00\x00\x01\x00\x02\x001
405 405 s> \xa1Jtotalitems\x01\xa2DnodeT\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xddEphaseFpublic
406 406 s> \r\n
407 407 received frame(size=53; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
408 408 s> 8\r\n
409 409 s> \x00\x00\x00\x01\x00\x02\x002
410 410 s> \r\n
411 411 s> 0\r\n
412 412 s> \r\n
413 413 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
414 414 response: gen[
415 415 {
416 416 b'totalitems': 1
417 417 },
418 418 {
419 419 b'node': b'\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xdd',
420 420 b'phase': b'public'
421 421 }
422 422 ]
423 423
424 424 Revision data is transferred upon request
425 425
426 426 $ sendhttpv2peer << EOF
427 427 > command changesetdata
428 428 > fields eval:[b'revision']
429 429 > nodes eval:[b'\xea\xe5\xf8\x2c\x2e\x62\x23\x68\xd2\x7d\xae\xcb\x76\xb7\xe3\x93\xd0\xf2\x42\x11']
430 430 > EOF
431 431 creating http peer for wire protocol version 2
432 432 sending changesetdata command
433 s> POST /api/exp-http-v2-0001/ro/changesetdata HTTP/1.1\r\n
433 s> POST /api/exp-http-v2-0002/ro/changesetdata HTTP/1.1\r\n
434 434 s> Accept-Encoding: identity\r\n
435 435 s> accept: application/mercurial-exp-framing-0005\r\n
436 436 s> content-type: application/mercurial-exp-framing-0005\r\n
437 437 s> content-length: 79\r\n
438 438 s> host: $LOCALIP:$HGPORT\r\n (glob)
439 439 s> user-agent: Mercurial debugwireproto\r\n
440 440 s> \r\n
441 441 s> G\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa2Ffields\x81HrevisionEnodes\x81T\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11DnameMchangesetdata
442 442 s> makefile('rb', None)
443 443 s> HTTP/1.1 200 OK\r\n
444 444 s> Server: testing stub value\r\n
445 445 s> Date: $HTTP_DATE$\r\n
446 446 s> Content-Type: application/mercurial-exp-framing-0005\r\n
447 447 s> Transfer-Encoding: chunked\r\n
448 448 s> \r\n
449 449 s> 13\r\n
450 450 s> \x0b\x00\x00\x01\x00\x02\x011
451 451 s> \xa1FstatusBok
452 452 s> \r\n
453 453 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
454 s> 7e\r\n
455 s> v\x00\x00\x01\x00\x02\x001
456 s> \xa1Jtotalitems\x01\xa2DnodeT\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11Lrevisionsize\x18=X=1b74476799ec8318045db759b1b4bcc9b839d0aa\n
454 s> 8c\r\n
455 s> \x84\x00\x00\x01\x00\x02\x001
456 s> \xa1Jtotalitems\x01\xa2Ofieldsfollowing\x81\x82Hrevision\x18=DnodeT\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11X=1b74476799ec8318045db759b1b4bcc9b839d0aa\n
457 457 s> test\n
458 458 s> 0 0\n
459 459 s> a\n
460 460 s> \n
461 461 s> commit 3
462 462 s> \r\n
463 received frame(size=118; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
463 received frame(size=132; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
464 464 s> 8\r\n
465 465 s> \x00\x00\x00\x01\x00\x02\x002
466 466 s> \r\n
467 467 s> 0\r\n
468 468 s> \r\n
469 469 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
470 470 response: gen[
471 471 {
472 472 b'totalitems': 1
473 473 },
474 474 {
475 b'node': b'\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11',
476 b'revisionsize': 61
475 b'fieldsfollowing': [
476 [
477 b'revision',
478 61
479 ]
480 ],
481 b'node': b'\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11'
477 482 },
478 483 b'1b74476799ec8318045db759b1b4bcc9b839d0aa\ntest\n0 0\na\n\ncommit 3'
479 484 ]
480 485
481 486 Bookmarks key isn't present if no bookmarks data
482 487
483 488 $ sendhttpv2peer << EOF
484 489 > command changesetdata
485 490 > fields eval:[b'bookmarks']
486 491 > noderange eval:[[], [b'\x0b\xb8\xad\x89\x4a\x15\xb1\x53\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f\x2a\x4b\x28\xdd', b'\xea\xe5\xf8\x2c\x2e\x62\x23\x68\xd2\x7d\xae\xcb\x76\xb7\xe3\x93\xd0\xf2\x42\x11']]
487 492 > EOF
488 493 creating http peer for wire protocol version 2
489 494 sending changesetdata command
490 s> POST /api/exp-http-v2-0001/ro/changesetdata HTTP/1.1\r\n
495 s> POST /api/exp-http-v2-0002/ro/changesetdata HTTP/1.1\r\n
491 496 s> Accept-Encoding: identity\r\n
492 497 s> accept: application/mercurial-exp-framing-0005\r\n
493 498 s> content-type: application/mercurial-exp-framing-0005\r\n
494 499 s> content-length: 107\r\n
495 500 s> host: $LOCALIP:$HGPORT\r\n (glob)
496 501 s> user-agent: Mercurial debugwireproto\r\n
497 502 s> \r\n
498 503 s> c\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa2Ffields\x81IbookmarksInoderange\x82\x80\x82T\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xddT\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11DnameMchangesetdata
499 504 s> makefile('rb', None)
500 505 s> HTTP/1.1 200 OK\r\n
501 506 s> Server: testing stub value\r\n
502 507 s> Date: $HTTP_DATE$\r\n
503 508 s> Content-Type: application/mercurial-exp-framing-0005\r\n
504 509 s> Transfer-Encoding: chunked\r\n
505 510 s> \r\n
506 511 s> 13\r\n
507 512 s> \x0b\x00\x00\x01\x00\x02\x011
508 513 s> \xa1FstatusBok
509 514 s> \r\n
510 515 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
511 516 s> 81\r\n
512 517 s> y\x00\x00\x01\x00\x02\x001
513 518 s> \xa1Jtotalitems\x04\xa1DnodeT3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:\xa1DnodeTu\x92\x91~\x1c>\x82g|\xb0\xa4\xbcq\\\xa2]\xd1-(\xc1\xa1DnodeT\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xdd\xa1DnodeT\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11
514 519 s> \r\n
515 520 received frame(size=121; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
516 521 s> 8\r\n
517 522 s> \x00\x00\x00\x01\x00\x02\x002
518 523 s> \r\n
519 524 s> 0\r\n
520 525 s> \r\n
521 526 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
522 527 response: gen[
523 528 {
524 529 b'totalitems': 4
525 530 },
526 531 {
527 532 b'node': b'3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:'
528 533 },
529 534 {
530 535 b'node': b'u\x92\x91~\x1c>\x82g|\xb0\xa4\xbcq\\\xa2]\xd1-(\xc1'
531 536 },
532 537 {
533 538 b'node': b'\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xdd'
534 539 },
535 540 {
536 541 b'node': b'\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11'
537 542 }
538 543 ]
539 544
540 545 Bookmarks are sent when requested
541 546
542 547 $ hg -R ../server bookmark -r 0bb8ad894a15b15380b2a2a5b183e20f2a4b28dd book-1
543 548 $ hg -R ../server bookmark -r eae5f82c2e622368d27daecb76b7e393d0f24211 book-2
544 549 $ hg -R ../server bookmark -r eae5f82c2e622368d27daecb76b7e393d0f24211 book-3
545 550
546 551 $ sendhttpv2peer << EOF
547 552 > command changesetdata
548 553 > fields eval:[b'bookmarks']
549 554 > noderange eval:[[], [b'\x0b\xb8\xad\x89\x4a\x15\xb1\x53\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f\x2a\x4b\x28\xdd', b'\xea\xe5\xf8\x2c\x2e\x62\x23\x68\xd2\x7d\xae\xcb\x76\xb7\xe3\x93\xd0\xf2\x42\x11']]
550 555 > EOF
551 556 creating http peer for wire protocol version 2
552 557 sending changesetdata command
553 s> POST /api/exp-http-v2-0001/ro/changesetdata HTTP/1.1\r\n
558 s> POST /api/exp-http-v2-0002/ro/changesetdata HTTP/1.1\r\n
554 559 s> Accept-Encoding: identity\r\n
555 560 s> accept: application/mercurial-exp-framing-0005\r\n
556 561 s> content-type: application/mercurial-exp-framing-0005\r\n
557 562 s> content-length: 107\r\n
558 563 s> host: $LOCALIP:$HGPORT\r\n (glob)
559 564 s> user-agent: Mercurial debugwireproto\r\n
560 565 s> \r\n
561 566 s> c\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa2Ffields\x81IbookmarksInoderange\x82\x80\x82T\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xddT\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11DnameMchangesetdata
562 567 s> makefile('rb', None)
563 568 s> HTTP/1.1 200 OK\r\n
564 569 s> Server: testing stub value\r\n
565 570 s> Date: $HTTP_DATE$\r\n
566 571 s> Content-Type: application/mercurial-exp-framing-0005\r\n
567 572 s> Transfer-Encoding: chunked\r\n
568 573 s> \r\n
569 574 s> 13\r\n
570 575 s> \x0b\x00\x00\x01\x00\x02\x011
571 576 s> \xa1FstatusBok
572 577 s> \r\n
573 578 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
574 579 s> ac\r\n
575 580 s> \xa4\x00\x00\x01\x00\x02\x001
576 581 s> \xa1Jtotalitems\x04\xa1DnodeT3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:\xa1DnodeTu\x92\x91~\x1c>\x82g|\xb0\xa4\xbcq\\\xa2]\xd1-(\xc1\xa2Ibookmarks\x81Fbook-1DnodeT\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xdd\xa2Ibookmarks\x82Fbook-2Fbook-3DnodeT\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11
577 582 s> \r\n
578 583 received frame(size=164; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
579 584 s> 8\r\n
580 585 s> \x00\x00\x00\x01\x00\x02\x002
581 586 s> \r\n
582 587 s> 0\r\n
583 588 s> \r\n
584 589 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
585 590 response: gen[
586 591 {
587 592 b'totalitems': 4
588 593 },
589 594 {
590 595 b'node': b'3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:'
591 596 },
592 597 {
593 598 b'node': b'u\x92\x91~\x1c>\x82g|\xb0\xa4\xbcq\\\xa2]\xd1-(\xc1'
594 599 },
595 600 {
596 601 b'bookmarks': [
597 602 b'book-1'
598 603 ],
599 604 b'node': b'\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xdd'
600 605 },
601 606 {
602 607 b'bookmarks': [
603 608 b'book-2',
604 609 b'book-3'
605 610 ],
606 611 b'node': b'\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11'
607 612 }
608 613 ]
609 614
610 615 Bookmarks are sent when we make a no-new-revisions request
611 616
612 617 $ sendhttpv2peer << EOF
613 618 > command changesetdata
614 619 > fields eval:[b'bookmarks', b'revision']
615 620 > noderange eval:[[b'\xea\xe5\xf8\x2c\x2e\x62\x23\x68\xd2\x7d\xae\xcb\x76\xb7\xe3\x93\xd0\xf2\x42\x11'], [b'\x0b\xb8\xad\x89\x4a\x15\xb1\x53\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f\x2a\x4b\x28\xdd', b'\xea\xe5\xf8\x2c\x2e\x62\x23\x68\xd2\x7d\xae\xcb\x76\xb7\xe3\x93\xd0\xf2\x42\x11']]
616 621 > EOF
617 622 creating http peer for wire protocol version 2
618 623 sending changesetdata command
619 s> POST /api/exp-http-v2-0001/ro/changesetdata HTTP/1.1\r\n
624 s> POST /api/exp-http-v2-0002/ro/changesetdata HTTP/1.1\r\n
620 625 s> Accept-Encoding: identity\r\n
621 626 s> accept: application/mercurial-exp-framing-0005\r\n
622 627 s> content-type: application/mercurial-exp-framing-0005\r\n
623 628 s> content-length: 137\r\n
624 629 s> host: $LOCALIP:$HGPORT\r\n (glob)
625 630 s> user-agent: Mercurial debugwireproto\r\n
626 631 s> \r\n
627 632 s> \x81\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa2Ffields\x82IbookmarksHrevisionInoderange\x82\x81T\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11\x82T\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xddT\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11DnameMchangesetdata
628 633 s> makefile('rb', None)
629 634 s> HTTP/1.1 200 OK\r\n
630 635 s> Server: testing stub value\r\n
631 636 s> Date: $HTTP_DATE$\r\n
632 637 s> Content-Type: application/mercurial-exp-framing-0005\r\n
633 638 s> Transfer-Encoding: chunked\r\n
634 639 s> \r\n
635 640 s> 13\r\n
636 641 s> \x0b\x00\x00\x01\x00\x02\x011
637 642 s> \xa1FstatusBok
638 643 s> \r\n
639 644 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
640 s> 12f\r\n
641 s> \'\x01\x00\x01\x00\x02\x001
642 s> \xa1Jtotalitems\x02\xa2DnodeTu\x92\x91~\x1c>\x82g|\xb0\xa4\xbcq\\\xa2]\xd1-(\xc1Lrevisionsize\x18?X?7f144aea0ba742713887b564d57e9d12f12ff382\n
645 s> 14b\r\n
646 s> C\x01\x00\x01\x00\x02\x001
647 s> \xa1Jtotalitems\x02\xa2Ofieldsfollowing\x81\x82Hrevision\x18?DnodeTu\x92\x91~\x1c>\x82g|\xb0\xa4\xbcq\\\xa2]\xd1-(\xc1X?7f144aea0ba742713887b564d57e9d12f12ff382\n
643 648 s> test\n
644 649 s> 0 0\n
645 650 s> a\n
646 651 s> b\n
647 652 s> \n
648 s> commit 1\xa3Ibookmarks\x81Fbook-1DnodeT\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xddLrevisionsize\x18=X=37f0a2d1c28ffe4b879109a7d1bbf8f07b3c763b\n
653 s> commit 1\xa3Ibookmarks\x81Fbook-1Ofieldsfollowing\x81\x82Hrevision\x18=DnodeT\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xddX=37f0a2d1c28ffe4b879109a7d1bbf8f07b3c763b\n
649 654 s> test\n
650 655 s> 0 0\n
651 656 s> b\n
652 657 s> \n
653 658 s> commit 2\xa2Ibookmarks\x82Fbook-2Fbook-3DnodeT\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11
654 659 s> \r\n
655 received frame(size=295; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
660 received frame(size=323; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
656 661 s> 8\r\n
657 662 s> \x00\x00\x00\x01\x00\x02\x002
658 663 s> \r\n
659 664 s> 0\r\n
660 665 s> \r\n
661 666 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
662 667 response: gen[
663 668 {
664 669 b'totalitems': 2
665 670 },
666 671 {
667 b'node': b'u\x92\x91~\x1c>\x82g|\xb0\xa4\xbcq\\\xa2]\xd1-(\xc1',
668 b'revisionsize': 63
672 b'fieldsfollowing': [
673 [
674 b'revision',
675 63
676 ]
677 ],
678 b'node': b'u\x92\x91~\x1c>\x82g|\xb0\xa4\xbcq\\\xa2]\xd1-(\xc1'
669 679 },
670 680 b'7f144aea0ba742713887b564d57e9d12f12ff382\ntest\n0 0\na\nb\n\ncommit 1',
671 681 {
672 682 b'bookmarks': [
673 683 b'book-1'
674 684 ],
675 b'node': b'\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xdd',
676 b'revisionsize': 61
685 b'fieldsfollowing': [
686 [
687 b'revision',
688 61
689 ]
690 ],
691 b'node': b'\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xdd'
677 692 },
678 693 b'37f0a2d1c28ffe4b879109a7d1bbf8f07b3c763b\ntest\n0 0\nb\n\ncommit 2',
679 694 {
680 695 b'bookmarks': [
681 696 b'book-2',
682 697 b'book-3'
683 698 ],
684 699 b'node': b'\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11'
685 700 }
686 701 ]
687 702
688 703 Multiple fields can be transferred
689 704
690 705 $ sendhttpv2peer << EOF
691 706 > command changesetdata
692 707 > fields eval:[b'parents', b'revision']
693 708 > nodes eval:[b'\xea\xe5\xf8\x2c\x2e\x62\x23\x68\xd2\x7d\xae\xcb\x76\xb7\xe3\x93\xd0\xf2\x42\x11']
694 709 > EOF
695 710 creating http peer for wire protocol version 2
696 711 sending changesetdata command
697 s> POST /api/exp-http-v2-0001/ro/changesetdata HTTP/1.1\r\n
712 s> POST /api/exp-http-v2-0002/ro/changesetdata HTTP/1.1\r\n
698 713 s> Accept-Encoding: identity\r\n
699 714 s> accept: application/mercurial-exp-framing-0005\r\n
700 715 s> content-type: application/mercurial-exp-framing-0005\r\n
701 716 s> content-length: 87\r\n
702 717 s> host: $LOCALIP:$HGPORT\r\n (glob)
703 718 s> user-agent: Mercurial debugwireproto\r\n
704 719 s> \r\n
705 720 s> O\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa2Ffields\x82GparentsHrevisionEnodes\x81T\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11DnameMchangesetdata
706 721 s> makefile('rb', None)
707 722 s> HTTP/1.1 200 OK\r\n
708 723 s> Server: testing stub value\r\n
709 724 s> Date: $HTTP_DATE$\r\n
710 725 s> Content-Type: application/mercurial-exp-framing-0005\r\n
711 726 s> Transfer-Encoding: chunked\r\n
712 727 s> \r\n
713 728 s> 13\r\n
714 729 s> \x0b\x00\x00\x01\x00\x02\x011
715 730 s> \xa1FstatusBok
716 731 s> \r\n
717 732 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
718 s> b1\r\n
719 s> \xa9\x00\x00\x01\x00\x02\x001
720 s> \xa1Jtotalitems\x01\xa3DnodeT\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11Gparents\x82T3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Lrevisionsize\x18=X=1b74476799ec8318045db759b1b4bcc9b839d0aa\n
733 s> bf\r\n
734 s> \xb7\x00\x00\x01\x00\x02\x001
735 s> \xa1Jtotalitems\x01\xa3Ofieldsfollowing\x81\x82Hrevision\x18=DnodeT\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11Gparents\x82T3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00X=1b74476799ec8318045db759b1b4bcc9b839d0aa\n
721 736 s> test\n
722 737 s> 0 0\n
723 738 s> a\n
724 739 s> \n
725 740 s> commit 3
726 741 s> \r\n
727 received frame(size=169; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
742 received frame(size=183; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
728 743 s> 8\r\n
729 744 s> \x00\x00\x00\x01\x00\x02\x002
730 745 s> \r\n
731 746 s> 0\r\n
732 747 s> \r\n
733 748 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
734 749 response: gen[
735 750 {
736 751 b'totalitems': 1
737 752 },
738 753 {
754 b'fieldsfollowing': [
755 [
756 b'revision',
757 61
758 ]
759 ],
739 760 b'node': b'\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11',
740 761 b'parents': [
741 762 b'3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:',
742 763 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
743 ],
744 b'revisionsize': 61
764 ]
745 765 },
746 766 b'1b74476799ec8318045db759b1b4bcc9b839d0aa\ntest\n0 0\na\n\ncommit 3'
747 767 ]
748 768
749 769 Base nodes have just their metadata (e.g. phase) transferred
750 770
751 771 $ sendhttpv2peer << EOF
752 772 > command changesetdata
753 773 > fields eval:[b'phase', b'parents', b'revision']
754 774 > noderange eval:[[b'\x33\x90\xef\x85\x00\x73\xfb\xc2\xf0\xdf\xff\x22\x44\x34\x2c\x8e\x92\x29\x01\x3a'], [b'\x0b\xb8\xad\x89\x4a\x15\xb1\x53\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f\x2a\x4b\x28\xdd', b'\xea\xe5\xf8\x2c\x2e\x62\x23\x68\xd2\x7d\xae\xcb\x76\xb7\xe3\x93\xd0\xf2\x42\x11']]
755 775 > EOF
756 776 creating http peer for wire protocol version 2
757 777 sending changesetdata command
758 s> POST /api/exp-http-v2-0001/ro/changesetdata HTTP/1.1\r\n
778 s> POST /api/exp-http-v2-0002/ro/changesetdata HTTP/1.1\r\n
759 779 s> Accept-Encoding: identity\r\n
760 780 s> accept: application/mercurial-exp-framing-0005\r\n
761 781 s> content-type: application/mercurial-exp-framing-0005\r\n
762 782 s> content-length: 141\r\n
763 783 s> host: $LOCALIP:$HGPORT\r\n (glob)
764 784 s> user-agent: Mercurial debugwireproto\r\n
765 785 s> \r\n
766 786 s> \x85\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa2Ffields\x83EphaseGparentsHrevisionInoderange\x82\x81T3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:\x82T\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xddT\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11DnameMchangesetdata
767 787 s> makefile('rb', None)
768 788 s> HTTP/1.1 200 OK\r\n
769 789 s> Server: testing stub value\r\n
770 790 s> Date: $HTTP_DATE$\r\n
771 791 s> Content-Type: application/mercurial-exp-framing-0005\r\n
772 792 s> Transfer-Encoding: chunked\r\n
773 793 s> \r\n
774 794 s> 13\r\n
775 795 s> \x0b\x00\x00\x01\x00\x02\x011
776 796 s> \xa1FstatusBok
777 797 s> \r\n
778 798 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
779 s> 239\r\n
780 s> 1\x02\x00\x01\x00\x02\x001
781 s> \xa1Jtotalitems\x03\xa2DnodeT3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:EphaseFpublic\xa4DnodeTu\x92\x91~\x1c>\x82g|\xb0\xa4\xbcq\\\xa2]\xd1-(\xc1Gparents\x82T3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00EphaseFpublicLrevisionsize\x18?X?7f144aea0ba742713887b564d57e9d12f12ff382\n
799 s> 263\r\n
800 s> [\x02\x00\x01\x00\x02\x001
801 s> \xa1Jtotalitems\x03\xa2DnodeT3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:EphaseFpublic\xa4Ofieldsfollowing\x81\x82Hrevision\x18?DnodeTu\x92\x91~\x1c>\x82g|\xb0\xa4\xbcq\\\xa2]\xd1-(\xc1Gparents\x82T3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00EphaseFpublicX?7f144aea0ba742713887b564d57e9d12f12ff382\n
782 802 s> test\n
783 803 s> 0 0\n
784 804 s> a\n
785 805 s> b\n
786 806 s> \n
787 s> commit 1\xa4DnodeT\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xddGparents\x82Tu\x92\x91~\x1c>\x82g|\xb0\xa4\xbcq\\\xa2]\xd1-(\xc1T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00EphaseFpublicLrevisionsize\x18=X=37f0a2d1c28ffe4b879109a7d1bbf8f07b3c763b\n
807 s> commit 1\xa4Ofieldsfollowing\x81\x82Hrevision\x18=DnodeT\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xddGparents\x82Tu\x92\x91~\x1c>\x82g|\xb0\xa4\xbcq\\\xa2]\xd1-(\xc1T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00EphaseFpublicX=37f0a2d1c28ffe4b879109a7d1bbf8f07b3c763b\n
788 808 s> test\n
789 809 s> 0 0\n
790 810 s> b\n
791 811 s> \n
792 s> commit 2\xa4DnodeT\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11Gparents\x82T3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00EphaseEdraftLrevisionsize\x18=X=1b74476799ec8318045db759b1b4bcc9b839d0aa\n
812 s> commit 2\xa4Ofieldsfollowing\x81\x82Hrevision\x18=DnodeT\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11Gparents\x82T3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:T\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00EphaseEdraftX=1b74476799ec8318045db759b1b4bcc9b839d0aa\n
793 813 s> test\n
794 814 s> 0 0\n
795 815 s> a\n
796 816 s> \n
797 817 s> commit 3
798 818 s> \r\n
799 received frame(size=561; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
819 received frame(size=603; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
800 820 s> 8\r\n
801 821 s> \x00\x00\x00\x01\x00\x02\x002
802 822 s> \r\n
803 823 s> 0\r\n
804 824 s> \r\n
805 825 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
806 826 response: gen[
807 827 {
808 828 b'totalitems': 3
809 829 },
810 830 {
811 831 b'node': b'3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:',
812 832 b'phase': b'public'
813 833 },
814 834 {
835 b'fieldsfollowing': [
836 [
837 b'revision',
838 63
839 ]
840 ],
815 841 b'node': b'u\x92\x91~\x1c>\x82g|\xb0\xa4\xbcq\\\xa2]\xd1-(\xc1',
816 842 b'parents': [
817 843 b'3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:',
818 844 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
819 845 ],
820 b'phase': b'public',
821 b'revisionsize': 63
846 b'phase': b'public'
822 847 },
823 848 b'7f144aea0ba742713887b564d57e9d12f12ff382\ntest\n0 0\na\nb\n\ncommit 1',
824 849 {
850 b'fieldsfollowing': [
851 [
852 b'revision',
853 61
854 ]
855 ],
825 856 b'node': b'\x0b\xb8\xad\x89J\x15\xb1S\x80\xb2\xa2\xa5\xb1\x83\xe2\x0f*K(\xdd',
826 857 b'parents': [
827 858 b'u\x92\x91~\x1c>\x82g|\xb0\xa4\xbcq\\\xa2]\xd1-(\xc1',
828 859 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
829 860 ],
830 b'phase': b'public',
831 b'revisionsize': 61
861 b'phase': b'public'
832 862 },
833 863 b'37f0a2d1c28ffe4b879109a7d1bbf8f07b3c763b\ntest\n0 0\nb\n\ncommit 2',
834 864 {
865 b'fieldsfollowing': [
866 [
867 b'revision',
868 61
869 ]
870 ],
835 871 b'node': b'\xea\xe5\xf8,.b#h\xd2}\xae\xcbv\xb7\xe3\x93\xd0\xf2B\x11',
836 872 b'parents': [
837 873 b'3\x90\xef\x85\x00s\xfb\xc2\xf0\xdf\xff"D4,\x8e\x92)\x01:',
838 874 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
839 875 ],
840 b'phase': b'draft',
841 b'revisionsize': 61
876 b'phase': b'draft'
842 877 },
843 878 b'1b74476799ec8318045db759b1b4bcc9b839d0aa\ntest\n0 0\na\n\ncommit 3'
844 879 ]
845 880
846 881 $ cat error.log
@@ -1,604 +1,644 b''
1 1 $ . $TESTDIR/wireprotohelpers.sh
2 2
3 3 $ hg init server
4 4 $ enablehttpv2 server
5 5 $ cd server
6 6 $ echo a0 > a
7 7 $ echo b0 > b
8 8 $ mkdir -p dir0/child0 dir0/child1 dir1
9 9 $ echo c0 > dir0/c
10 10 $ echo d0 > dir0/d
11 11 $ echo e0 > dir0/child0/e
12 12 $ echo f0 > dir0/child1/f
13 13 $ hg -q commit -A -m 'commit 0'
14 14
15 15 $ echo a1 > a
16 16 $ echo d1 > dir0/d
17 17 $ hg commit -m 'commit 1'
18 18 $ echo f0 > dir0/child1/f
19 19 $ hg commit -m 'commit 2'
20 20 nothing changed
21 21 [1]
22 22
23 23 $ hg -q up -r 0
24 24 $ echo a2 > a
25 25 $ hg commit -m 'commit 3'
26 26 created new head
27 27
28 28 $ hg log -G -T '{rev}:{node} {desc}\n'
29 29 @ 2:c8757a2ffe552850d1e0dfe60d295ebf64c196d9 commit 3
30 30 |
31 31 | o 1:650165e803375748a94df471e5b58d85763e0b29 commit 1
32 32 |/
33 33 o 0:6d85ca1270b377d320098556ba5bfad34a9ee12d commit 0
34 34
35 35
36 36 $ hg --debug debugindex a
37 37 rev linkrev nodeid p1 p2
38 38 0 0 2b4eb07319bfa077a40a2f04913659aef0da42da 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
39 39 1 1 9a38122997b3ac97be2a9aa2e556838341fdf2cc 2b4eb07319bfa077a40a2f04913659aef0da42da 0000000000000000000000000000000000000000
40 40 2 2 0879345e39377229634b420c639454156726c6b6 2b4eb07319bfa077a40a2f04913659aef0da42da 0000000000000000000000000000000000000000
41 41
42 42 $ hg --debug debugindex dir0/child0/e
43 43 rev linkrev nodeid p1 p2
44 44 0 0 bbba6c06b30f443d34ff841bc985c4d0827c6be4 0000000000000000000000000000000000000000 0000000000000000000000000000000000000000
45 45
46 46 $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
47 47 $ cat hg.pid > $DAEMON_PIDS
48 48
49 49 Missing arguments is an error
50 50
51 51 $ sendhttpv2peer << EOF
52 52 > command filedata
53 53 > EOF
54 54 creating http peer for wire protocol version 2
55 55 sending filedata command
56 56 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
57 57 s> Accept-Encoding: identity\r\n
58 58 s> accept: application/mercurial-exp-framing-0005\r\n
59 59 s> content-type: application/mercurial-exp-framing-0005\r\n
60 60 s> content-length: 23\r\n
61 61 s> host: $LOCALIP:$HGPORT\r\n (glob)
62 62 s> user-agent: Mercurial debugwireproto\r\n
63 63 s> \r\n
64 64 s> \x0f\x00\x00\x01\x00\x01\x01\x11\xa1DnameHfiledata
65 65 s> makefile('rb', None)
66 66 s> HTTP/1.1 200 OK\r\n
67 67 s> Server: testing stub value\r\n
68 68 s> Date: $HTTP_DATE$\r\n
69 69 s> Content-Type: application/mercurial-exp-framing-0005\r\n
70 70 s> Transfer-Encoding: chunked\r\n
71 71 s> \r\n
72 72 s> 4e\r\n
73 73 s> F\x00\x00\x01\x00\x02\x012
74 74 s> \xa2Eerror\xa1GmessageX\'missing required arguments: nodes, pathFstatusEerror
75 75 s> \r\n
76 76 received frame(size=70; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos)
77 77 s> 0\r\n
78 78 s> \r\n
79 79 abort: missing required arguments: nodes, path!
80 80 [255]
81 81
82 82 $ sendhttpv2peer << EOF
83 83 > command filedata
84 84 > nodes eval:[]
85 85 > EOF
86 86 creating http peer for wire protocol version 2
87 87 sending filedata command
88 88 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
89 89 s> Accept-Encoding: identity\r\n
90 90 s> accept: application/mercurial-exp-framing-0005\r\n
91 91 s> content-type: application/mercurial-exp-framing-0005\r\n
92 92 s> content-length: 36\r\n
93 93 s> host: $LOCALIP:$HGPORT\r\n (glob)
94 94 s> user-agent: Mercurial debugwireproto\r\n
95 95 s> \r\n
96 96 s> \x1c\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa1Enodes\x80DnameHfiledata
97 97 s> makefile('rb', None)
98 98 s> HTTP/1.1 200 OK\r\n
99 99 s> Server: testing stub value\r\n
100 100 s> Date: $HTTP_DATE$\r\n
101 101 s> Content-Type: application/mercurial-exp-framing-0005\r\n
102 102 s> Transfer-Encoding: chunked\r\n
103 103 s> \r\n
104 104 s> 47\r\n
105 105 s> ?\x00\x00\x01\x00\x02\x012
106 106 s> \xa2Eerror\xa1GmessageX missing required arguments: pathFstatusEerror
107 107 s> \r\n
108 108 received frame(size=63; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos)
109 109 s> 0\r\n
110 110 s> \r\n
111 111 abort: missing required arguments: path!
112 112 [255]
113 113
114 114 Unknown node is an error
115 115
116 116 $ sendhttpv2peer << EOF
117 117 > command filedata
118 118 > nodes eval:[b'\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa']
119 119 > path eval:b'a'
120 120 > EOF
121 121 creating http peer for wire protocol version 2
122 122 sending filedata command
123 123 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
124 124 s> Accept-Encoding: identity\r\n
125 125 s> accept: application/mercurial-exp-framing-0005\r\n
126 126 s> content-type: application/mercurial-exp-framing-0005\r\n
127 127 s> content-length: 64\r\n
128 128 s> host: $LOCALIP:$HGPORT\r\n (glob)
129 129 s> user-agent: Mercurial debugwireproto\r\n
130 130 s> \r\n
131 131 s> 8\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa2Enodes\x81T\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaaDpathAaDnameHfiledata
132 132 s> makefile('rb', None)
133 133 s> HTTP/1.1 200 OK\r\n
134 134 s> Server: testing stub value\r\n
135 135 s> Date: $HTTP_DATE$\r\n
136 136 s> Content-Type: application/mercurial-exp-framing-0005\r\n
137 137 s> Transfer-Encoding: chunked\r\n
138 138 s> \r\n
139 139 s> 6b\r\n
140 140 s> c\x00\x00\x01\x00\x02\x012
141 141 s> \xa2Eerror\xa2Dargs\x81X(aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaGmessageUunknown file node: %sFstatusEerror
142 142 s> \r\n
143 143 received frame(size=99; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=eos)
144 144 s> 0\r\n
145 145 s> \r\n
146 146 abort: unknown file node: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa!
147 147 [255]
148 148
149 149 Fetching a single revision returns just metadata by default
150 150
151 151 $ sendhttpv2peer << EOF
152 152 > command filedata
153 153 > nodes eval:[b'\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc']
154 154 > path eval:b'a'
155 155 > EOF
156 156 creating http peer for wire protocol version 2
157 157 sending filedata command
158 158 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
159 159 s> Accept-Encoding: identity\r\n
160 160 s> accept: application/mercurial-exp-framing-0005\r\n
161 161 s> content-type: application/mercurial-exp-framing-0005\r\n
162 162 s> content-length: 64\r\n
163 163 s> host: $LOCALIP:$HGPORT\r\n (glob)
164 164 s> user-agent: Mercurial debugwireproto\r\n
165 165 s> \r\n
166 166 s> 8\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa2Enodes\x81T\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccDpathAaDnameHfiledata
167 167 s> makefile('rb', None)
168 168 s> HTTP/1.1 200 OK\r\n
169 169 s> Server: testing stub value\r\n
170 170 s> Date: $HTTP_DATE$\r\n
171 171 s> Content-Type: application/mercurial-exp-framing-0005\r\n
172 172 s> Transfer-Encoding: chunked\r\n
173 173 s> \r\n
174 174 s> 13\r\n
175 175 s> \x0b\x00\x00\x01\x00\x02\x011
176 176 s> \xa1FstatusBok
177 177 s> \r\n
178 178 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
179 179 s> 30\r\n
180 180 s> (\x00\x00\x01\x00\x02\x001
181 181 s> \xa1Jtotalitems\x01\xa1DnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc
182 182 s> \r\n
183 183 received frame(size=40; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
184 184 s> 8\r\n
185 185 s> \x00\x00\x00\x01\x00\x02\x002
186 186 s> \r\n
187 187 s> 0\r\n
188 188 s> \r\n
189 189 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
190 190 response: gen[
191 191 {
192 192 b'totalitems': 1
193 193 },
194 194 {
195 195 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc'
196 196 }
197 197 ]
198 198
199 199 Requesting parents works
200 200
201 201 $ sendhttpv2peer << EOF
202 202 > command filedata
203 203 > nodes eval:[b'\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc']
204 204 > path eval:b'a'
205 205 > fields eval:[b'parents']
206 206 > EOF
207 207 creating http peer for wire protocol version 2
208 208 sending filedata command
209 209 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
210 210 s> Accept-Encoding: identity\r\n
211 211 s> accept: application/mercurial-exp-framing-0005\r\n
212 212 s> content-type: application/mercurial-exp-framing-0005\r\n
213 213 s> content-length: 80\r\n
214 214 s> host: $LOCALIP:$HGPORT\r\n (glob)
215 215 s> user-agent: Mercurial debugwireproto\r\n
216 216 s> \r\n
217 217 s> H\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81GparentsEnodes\x81T\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccDpathAaDnameHfiledata
218 218 s> makefile('rb', None)
219 219 s> HTTP/1.1 200 OK\r\n
220 220 s> Server: testing stub value\r\n
221 221 s> Date: $HTTP_DATE$\r\n
222 222 s> Content-Type: application/mercurial-exp-framing-0005\r\n
223 223 s> Transfer-Encoding: chunked\r\n
224 224 s> \r\n
225 225 s> 13\r\n
226 226 s> \x0b\x00\x00\x01\x00\x02\x011
227 227 s> \xa1FstatusBok
228 228 s> \r\n
229 229 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
230 230 s> 63\r\n
231 231 s> [\x00\x00\x01\x00\x02\x001
232 232 s> \xa1Jtotalitems\x01\xa2DnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccGparents\x82T+N\xb0s\x19\xbf\xa0w\xa4\n
233 233 s> /\x04\x916Y\xae\xf0\xdaB\xdaT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00
234 234 s> \r\n
235 235 received frame(size=91; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
236 236 s> 8\r\n
237 237 s> \x00\x00\x00\x01\x00\x02\x002
238 238 s> \r\n
239 239 s> 0\r\n
240 240 s> \r\n
241 241 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
242 242 response: gen[
243 243 {
244 244 b'totalitems': 1
245 245 },
246 246 {
247 247 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc',
248 248 b'parents': [
249 249 b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
250 250 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
251 251 ]
252 252 }
253 253 ]
254 254
255 255 Requesting revision data works
256 256 (haveparents defaults to False, so fulltext is emitted)
257 257
258 258 $ sendhttpv2peer << EOF
259 259 > command filedata
260 260 > nodes eval:[b'\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc']
261 261 > path eval:b'a'
262 262 > fields eval:[b'revision']
263 263 > EOF
264 264 creating http peer for wire protocol version 2
265 265 sending filedata command
266 266 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
267 267 s> Accept-Encoding: identity\r\n
268 268 s> accept: application/mercurial-exp-framing-0005\r\n
269 269 s> content-type: application/mercurial-exp-framing-0005\r\n
270 270 s> content-length: 81\r\n
271 271 s> host: $LOCALIP:$HGPORT\r\n (glob)
272 272 s> user-agent: Mercurial debugwireproto\r\n
273 273 s> \r\n
274 274 s> I\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81HrevisionEnodes\x81T\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccDpathAaDnameHfiledata
275 275 s> makefile('rb', None)
276 276 s> HTTP/1.1 200 OK\r\n
277 277 s> Server: testing stub value\r\n
278 278 s> Date: $HTTP_DATE$\r\n
279 279 s> Content-Type: application/mercurial-exp-framing-0005\r\n
280 280 s> Transfer-Encoding: chunked\r\n
281 281 s> \r\n
282 282 s> 13\r\n
283 283 s> \x0b\x00\x00\x01\x00\x02\x011
284 284 s> \xa1FstatusBok
285 285 s> \r\n
286 286 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
287 s> 42\r\n
288 s> :\x00\x00\x01\x00\x02\x001
289 s> \xa1Jtotalitems\x01\xa2DnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccLrevisionsize\x03Ca1\n
287 s> 50\r\n
288 s> H\x00\x00\x01\x00\x02\x001
289 s> \xa1Jtotalitems\x01\xa2Ofieldsfollowing\x81\x82Hrevision\x03DnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccCa1\n
290 290 s> \r\n
291 received frame(size=58; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
291 received frame(size=72; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
292 292 s> 8\r\n
293 293 s> \x00\x00\x00\x01\x00\x02\x002
294 294 s> \r\n
295 295 s> 0\r\n
296 296 s> \r\n
297 297 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
298 298 response: gen[
299 299 {
300 300 b'totalitems': 1
301 301 },
302 302 {
303 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc',
304 b'revisionsize': 3
303 b'fieldsfollowing': [
304 [
305 b'revision',
306 3
307 ]
308 ],
309 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc'
305 310 },
306 311 b'a1\n'
307 312 ]
308 313
309 314 haveparents=False should be same as above
310 315
311 316 $ sendhttpv2peer << EOF
312 317 > command filedata
313 318 > nodes eval:[b'\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc']
314 319 > path eval:b'a'
315 320 > fields eval:[b'revision']
316 321 > haveparents eval:False
317 322 > EOF
318 323 creating http peer for wire protocol version 2
319 324 sending filedata command
320 325 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
321 326 s> Accept-Encoding: identity\r\n
322 327 s> accept: application/mercurial-exp-framing-0005\r\n
323 328 s> content-type: application/mercurial-exp-framing-0005\r\n
324 329 s> content-length: 94\r\n
325 330 s> host: $LOCALIP:$HGPORT\r\n (glob)
326 331 s> user-agent: Mercurial debugwireproto\r\n
327 332 s> \r\n
328 333 s> V\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa4Ffields\x81HrevisionKhaveparents\xf4Enodes\x81T\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccDpathAaDnameHfiledata
329 334 s> makefile('rb', None)
330 335 s> HTTP/1.1 200 OK\r\n
331 336 s> Server: testing stub value\r\n
332 337 s> Date: $HTTP_DATE$\r\n
333 338 s> Content-Type: application/mercurial-exp-framing-0005\r\n
334 339 s> Transfer-Encoding: chunked\r\n
335 340 s> \r\n
336 341 s> 13\r\n
337 342 s> \x0b\x00\x00\x01\x00\x02\x011
338 343 s> \xa1FstatusBok
339 344 s> \r\n
340 345 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
341 s> 42\r\n
342 s> :\x00\x00\x01\x00\x02\x001
343 s> \xa1Jtotalitems\x01\xa2DnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccLrevisionsize\x03Ca1\n
346 s> 50\r\n
347 s> H\x00\x00\x01\x00\x02\x001
348 s> \xa1Jtotalitems\x01\xa2Ofieldsfollowing\x81\x82Hrevision\x03DnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccCa1\n
344 349 s> \r\n
345 received frame(size=58; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
350 received frame(size=72; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
346 351 s> 8\r\n
347 352 s> \x00\x00\x00\x01\x00\x02\x002
348 353 s> \r\n
349 354 s> 0\r\n
350 355 s> \r\n
351 356 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
352 357 response: gen[
353 358 {
354 359 b'totalitems': 1
355 360 },
356 361 {
357 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc',
358 b'revisionsize': 3
362 b'fieldsfollowing': [
363 [
364 b'revision',
365 3
366 ]
367 ],
368 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc'
359 369 },
360 370 b'a1\n'
361 371 ]
362 372
363 373 haveparents=True should emit a delta
364 374
365 375 $ sendhttpv2peer << EOF
366 376 > command filedata
367 377 > nodes eval:[b'\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc']
368 378 > path eval:b'a'
369 379 > fields eval:[b'revision']
370 380 > haveparents eval:True
371 381 > EOF
372 382 creating http peer for wire protocol version 2
373 383 sending filedata command
374 384 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
375 385 s> Accept-Encoding: identity\r\n
376 386 s> accept: application/mercurial-exp-framing-0005\r\n
377 387 s> content-type: application/mercurial-exp-framing-0005\r\n
378 388 s> content-length: 94\r\n
379 389 s> host: $LOCALIP:$HGPORT\r\n (glob)
380 390 s> user-agent: Mercurial debugwireproto\r\n
381 391 s> \r\n
382 392 s> V\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa4Ffields\x81HrevisionKhaveparents\xf5Enodes\x81T\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccDpathAaDnameHfiledata
383 393 s> makefile('rb', None)
384 394 s> HTTP/1.1 200 OK\r\n
385 395 s> Server: testing stub value\r\n
386 396 s> Date: $HTTP_DATE$\r\n
387 397 s> Content-Type: application/mercurial-exp-framing-0005\r\n
388 398 s> Transfer-Encoding: chunked\r\n
389 399 s> \r\n
390 400 s> 13\r\n
391 401 s> \x0b\x00\x00\x01\x00\x02\x011
392 402 s> \xa1FstatusBok
393 403 s> \r\n
394 404 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
395 s> 6e\r\n
396 s> f\x00\x00\x01\x00\x02\x001
405 s> 7c\r\n
406 s> t\x00\x00\x01\x00\x02\x001
397 407 s> \xa1Jtotalitems\x01\xa3MdeltabasenodeT+N\xb0s\x19\xbf\xa0w\xa4\n
398 s> /\x04\x916Y\xae\xf0\xdaB\xdaIdeltasize\x0fDnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccO\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03a1\n
408 s> /\x04\x916Y\xae\xf0\xdaB\xdaOfieldsfollowing\x81\x82Edelta\x0fDnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccO\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03a1\n
399 409 s> \r\n
400 received frame(size=102; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
410 received frame(size=116; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
401 411 s> 8\r\n
402 412 s> \x00\x00\x00\x01\x00\x02\x002
403 413 s> \r\n
404 414 s> 0\r\n
405 415 s> \r\n
406 416 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
407 417 response: gen[
408 418 {
409 419 b'totalitems': 1
410 420 },
411 421 {
412 422 b'deltabasenode': b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
413 b'deltasize': 15,
423 b'fieldsfollowing': [
424 [
425 b'delta',
426 15
427 ]
428 ],
414 429 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc'
415 430 },
416 431 b'\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03a1\n'
417 432 ]
418 433
419 434 Requesting multiple revisions works
420 435 (first revision is a fulltext since haveparents=False by default)
421 436
422 437 $ sendhttpv2peer << EOF
423 438 > command filedata
424 439 > nodes eval:['\x2b\x4e\xb0\x73\x19\xbf\xa0\x77\xa4\x0a\x2f\x04\x91\x36\x59\xae\xf0\xda\x42\xda', '\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc']
425 440 > path eval:b'a'
426 441 > fields eval:[b'revision']
427 442 > EOF
428 443 creating http peer for wire protocol version 2
429 444 sending filedata command
430 445 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
431 446 s> Accept-Encoding: identity\r\n
432 447 s> accept: application/mercurial-exp-framing-0005\r\n
433 448 s> content-type: application/mercurial-exp-framing-0005\r\n
434 449 s> content-length: 102\r\n
435 450 s> host: $LOCALIP:$HGPORT\r\n (glob)
436 451 s> user-agent: Mercurial debugwireproto\r\n
437 452 s> \r\n
438 453 s> ^\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81HrevisionEnodes\x82T+N\xb0s\x19\xbf\xa0w\xa4\n
439 454 s> /\x04\x916Y\xae\xf0\xdaB\xdaT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccDpathAaDnameHfiledata
440 455 s> makefile('rb', None)
441 456 s> HTTP/1.1 200 OK\r\n
442 457 s> Server: testing stub value\r\n
443 458 s> Date: $HTTP_DATE$\r\n
444 459 s> Content-Type: application/mercurial-exp-framing-0005\r\n
445 460 s> Transfer-Encoding: chunked\r\n
446 461 s> \r\n
447 462 s> 13\r\n
448 463 s> \x0b\x00\x00\x01\x00\x02\x011
449 464 s> \xa1FstatusBok
450 465 s> \r\n
451 466 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
452 s> 9b\r\n
453 s> \x93\x00\x00\x01\x00\x02\x001
454 s> \xa1Jtotalitems\x02\xa2DnodeT+N\xb0s\x19\xbf\xa0w\xa4\n
455 s> /\x04\x916Y\xae\xf0\xdaB\xdaLrevisionsize\x03Ca0\n
467 s> b7\r\n
468 s> \xaf\x00\x00\x01\x00\x02\x001
469 s> \xa1Jtotalitems\x02\xa2Ofieldsfollowing\x81\x82Hrevision\x03DnodeT+N\xb0s\x19\xbf\xa0w\xa4\n
470 s> /\x04\x916Y\xae\xf0\xdaB\xdaCa0\n
456 471 s> \xa3MdeltabasenodeT+N\xb0s\x19\xbf\xa0w\xa4\n
457 s> /\x04\x916Y\xae\xf0\xdaB\xdaIdeltasize\x0fDnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccO\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03a1\n
472 s> /\x04\x916Y\xae\xf0\xdaB\xdaOfieldsfollowing\x81\x82Edelta\x0fDnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccO\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03a1\n
458 473 s> \r\n
459 received frame(size=147; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
474 received frame(size=175; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
460 475 s> 8\r\n
461 476 s> \x00\x00\x00\x01\x00\x02\x002
462 477 s> \r\n
463 478 s> 0\r\n
464 479 s> \r\n
465 480 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
466 481 response: gen[
467 482 {
468 483 b'totalitems': 2
469 484 },
470 485 {
471 b'node': b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
472 b'revisionsize': 3
486 b'fieldsfollowing': [
487 [
488 b'revision',
489 3
490 ]
491 ],
492 b'node': b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda'
473 493 },
474 494 b'a0\n',
475 495 {
476 496 b'deltabasenode': b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
477 b'deltasize': 15,
497 b'fieldsfollowing': [
498 [
499 b'delta',
500 15
501 ]
502 ],
478 503 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc'
479 504 },
480 505 b'\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03a1\n'
481 506 ]
482 507
483 508 Revisions are sorted by DAG order, parents first
484 509
485 510 $ sendhttpv2peer << EOF
486 511 > command filedata
487 512 > nodes eval:['\x9a\x38\x12\x29\x97\xb3\xac\x97\xbe\x2a\x9a\xa2\xe5\x56\x83\x83\x41\xfd\xf2\xcc', '\x2b\x4e\xb0\x73\x19\xbf\xa0\x77\xa4\x0a\x2f\x04\x91\x36\x59\xae\xf0\xda\x42\xda']
488 513 > path eval:b'a'
489 514 > fields eval:[b'revision']
490 515 > EOF
491 516 creating http peer for wire protocol version 2
492 517 sending filedata command
493 518 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
494 519 s> Accept-Encoding: identity\r\n
495 520 s> accept: application/mercurial-exp-framing-0005\r\n
496 521 s> content-type: application/mercurial-exp-framing-0005\r\n
497 522 s> content-length: 102\r\n
498 523 s> host: $LOCALIP:$HGPORT\r\n (glob)
499 524 s> user-agent: Mercurial debugwireproto\r\n
500 525 s> \r\n
501 526 s> ^\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x81HrevisionEnodes\x82T\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccT+N\xb0s\x19\xbf\xa0w\xa4\n
502 527 s> /\x04\x916Y\xae\xf0\xdaB\xdaDpathAaDnameHfiledata
503 528 s> makefile('rb', None)
504 529 s> HTTP/1.1 200 OK\r\n
505 530 s> Server: testing stub value\r\n
506 531 s> Date: $HTTP_DATE$\r\n
507 532 s> Content-Type: application/mercurial-exp-framing-0005\r\n
508 533 s> Transfer-Encoding: chunked\r\n
509 534 s> \r\n
510 535 s> 13\r\n
511 536 s> \x0b\x00\x00\x01\x00\x02\x011
512 537 s> \xa1FstatusBok
513 538 s> \r\n
514 539 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
515 s> 9b\r\n
516 s> \x93\x00\x00\x01\x00\x02\x001
517 s> \xa1Jtotalitems\x02\xa2DnodeT+N\xb0s\x19\xbf\xa0w\xa4\n
518 s> /\x04\x916Y\xae\xf0\xdaB\xdaLrevisionsize\x03Ca0\n
540 s> b7\r\n
541 s> \xaf\x00\x00\x01\x00\x02\x001
542 s> \xa1Jtotalitems\x02\xa2Ofieldsfollowing\x81\x82Hrevision\x03DnodeT+N\xb0s\x19\xbf\xa0w\xa4\n
543 s> /\x04\x916Y\xae\xf0\xdaB\xdaCa0\n
519 544 s> \xa3MdeltabasenodeT+N\xb0s\x19\xbf\xa0w\xa4\n
520 s> /\x04\x916Y\xae\xf0\xdaB\xdaIdeltasize\x0fDnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccO\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03a1\n
545 s> /\x04\x916Y\xae\xf0\xdaB\xdaOfieldsfollowing\x81\x82Edelta\x0fDnodeT\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xccO\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03a1\n
521 546 s> \r\n
522 received frame(size=147; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
547 received frame(size=175; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
523 548 s> 8\r\n
524 549 s> \x00\x00\x00\x01\x00\x02\x002
525 550 s> \r\n
526 551 s> 0\r\n
527 552 s> \r\n
528 553 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
529 554 response: gen[
530 555 {
531 556 b'totalitems': 2
532 557 },
533 558 {
534 b'node': b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
535 b'revisionsize': 3
559 b'fieldsfollowing': [
560 [
561 b'revision',
562 3
563 ]
564 ],
565 b'node': b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda'
536 566 },
537 567 b'a0\n',
538 568 {
539 569 b'deltabasenode': b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
540 b'deltasize': 15,
570 b'fieldsfollowing': [
571 [
572 b'delta',
573 15
574 ]
575 ],
541 576 b'node': b'\x9a8\x12)\x97\xb3\xac\x97\xbe*\x9a\xa2\xe5V\x83\x83A\xfd\xf2\xcc'
542 577 },
543 578 b'\x00\x00\x00\x00\x00\x00\x00\x03\x00\x00\x00\x03a1\n'
544 579 ]
545 580
546 581 Requesting parents and revision data works
547 582
548 583 $ sendhttpv2peer << EOF
549 584 > command filedata
550 585 > nodes eval:['\x08\x79\x34\x5e\x39\x37\x72\x29\x63\x4b\x42\x0c\x63\x94\x54\x15\x67\x26\xc6\xb6']
551 586 > path eval:b'a'
552 587 > fields eval:[b'parents', b'revision']
553 588 > EOF
554 589 creating http peer for wire protocol version 2
555 590 sending filedata command
556 591 s> POST /api/exp-http-v2-0001/ro/filedata HTTP/1.1\r\n
557 592 s> Accept-Encoding: identity\r\n
558 593 s> accept: application/mercurial-exp-framing-0005\r\n
559 594 s> content-type: application/mercurial-exp-framing-0005\r\n
560 595 s> content-length: 89\r\n
561 596 s> host: $LOCALIP:$HGPORT\r\n (glob)
562 597 s> user-agent: Mercurial debugwireproto\r\n
563 598 s> \r\n
564 599 s> Q\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa3Ffields\x82GparentsHrevisionEnodes\x81T\x08y4^97r)cKB\x0cc\x94T\x15g&\xc6\xb6DpathAaDnameHfiledata
565 600 s> makefile('rb', None)
566 601 s> HTTP/1.1 200 OK\r\n
567 602 s> Server: testing stub value\r\n
568 603 s> Date: $HTTP_DATE$\r\n
569 604 s> Content-Type: application/mercurial-exp-framing-0005\r\n
570 605 s> Transfer-Encoding: chunked\r\n
571 606 s> \r\n
572 607 s> 13\r\n
573 608 s> \x0b\x00\x00\x01\x00\x02\x011
574 609 s> \xa1FstatusBok
575 610 s> \r\n
576 611 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
577 s> 75\r\n
578 s> m\x00\x00\x01\x00\x02\x001
579 s> \xa1Jtotalitems\x01\xa3DnodeT\x08y4^97r)cKB\x0cc\x94T\x15g&\xc6\xb6Gparents\x82T+N\xb0s\x19\xbf\xa0w\xa4\n
580 s> /\x04\x916Y\xae\xf0\xdaB\xdaT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Lrevisionsize\x03Ca2\n
612 s> 83\r\n
613 s> {\x00\x00\x01\x00\x02\x001
614 s> \xa1Jtotalitems\x01\xa3Ofieldsfollowing\x81\x82Hrevision\x03DnodeT\x08y4^97r)cKB\x0cc\x94T\x15g&\xc6\xb6Gparents\x82T+N\xb0s\x19\xbf\xa0w\xa4\n
615 s> /\x04\x916Y\xae\xf0\xdaB\xdaT\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00Ca2\n
581 616 s> \r\n
582 received frame(size=109; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
617 received frame(size=123; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
583 618 s> 8\r\n
584 619 s> \x00\x00\x00\x01\x00\x02\x002
585 620 s> \r\n
586 621 s> 0\r\n
587 622 s> \r\n
588 623 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
589 624 response: gen[
590 625 {
591 626 b'totalitems': 1
592 627 },
593 628 {
629 b'fieldsfollowing': [
630 [
631 b'revision',
632 3
633 ]
634 ],
594 635 b'node': b'\x08y4^97r)cKB\x0cc\x94T\x15g&\xc6\xb6',
595 636 b'parents': [
596 637 b'+N\xb0s\x19\xbf\xa0w\xa4\n/\x04\x916Y\xae\xf0\xdaB\xda',
597 638 b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'
598 ],
599 b'revisionsize': 3
639 ]
600 640 },
601 641 b'a2\n'
602 642 ]
603 643
604 644 $ cat error.log
@@ -1,120 +1,120 b''
1 1 $ . $TESTDIR/wireprotohelpers.sh
2 2
3 3 $ hg init server
4 4 $ enablehttpv2 server
5 5 $ cd server
6 6 $ hg debugdrawdag << EOF
7 7 > H I J
8 8 > | | |
9 9 > E F G
10 10 > | |/
11 11 > C D
12 12 > |/
13 13 > B
14 14 > |
15 15 > A
16 16 > EOF
17 17
18 18 $ hg phase --force --secret J
19 19 $ hg phase --public E
20 20
21 21 $ hg log -r 'E + H + I + G + J' -T '{rev}:{node} {desc} {phase}\n'
22 22 4:78d2dca436b2f5b188ac267e29b81e07266d38fc E public
23 23 7:ae492e36b0c8339ffaf328d00b85b4525de1165e H draft
24 24 8:1d6f6b91d44aaba6d5e580bc30a9948530dbe00b I draft
25 25 6:29446d2dc5419c5f97447a8bc062e4cc328bf241 G draft
26 26 9:dec04b246d7cbb670c6689806c05ad17c835284e J secret
27 27
28 28 $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
29 29 $ cat hg.pid > $DAEMON_PIDS
30 30
31 31 All non-secret heads returned by default
32 32
33 33 $ sendhttpv2peer << EOF
34 34 > command heads
35 35 > EOF
36 36 creating http peer for wire protocol version 2
37 37 sending heads command
38 s> POST /api/exp-http-v2-0001/ro/heads HTTP/1.1\r\n
38 s> POST /api/exp-http-v2-0002/ro/heads HTTP/1.1\r\n
39 39 s> Accept-Encoding: identity\r\n
40 40 s> accept: application/mercurial-exp-framing-0005\r\n
41 41 s> content-type: application/mercurial-exp-framing-0005\r\n
42 42 s> content-length: 20\r\n
43 43 s> host: $LOCALIP:$HGPORT\r\n (glob)
44 44 s> user-agent: Mercurial debugwireproto\r\n
45 45 s> \r\n
46 46 s> \x0c\x00\x00\x01\x00\x01\x01\x11\xa1DnameEheads
47 47 s> makefile('rb', None)
48 48 s> HTTP/1.1 200 OK\r\n
49 49 s> Server: testing stub value\r\n
50 50 s> Date: $HTTP_DATE$\r\n
51 51 s> Content-Type: application/mercurial-exp-framing-0005\r\n
52 52 s> Transfer-Encoding: chunked\r\n
53 53 s> \r\n
54 54 s> 13\r\n
55 55 s> \x0b\x00\x00\x01\x00\x02\x011
56 56 s> \xa1FstatusBok
57 57 s> \r\n
58 58 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
59 59 s> 48\r\n
60 60 s> @\x00\x00\x01\x00\x02\x001
61 61 s> \x83T\x1dok\x91\xd4J\xab\xa6\xd5\xe5\x80\xbc0\xa9\x94\x850\xdb\xe0\x0bT\xaeI.6\xb0\xc83\x9f\xfa\xf3(\xd0\x0b\x85\xb4R]\xe1\x16^T)Dm-\xc5A\x9c_\x97Dz\x8b\xc0b\xe4\xcc2\x8b\xf2A
62 62 s> \r\n
63 63 received frame(size=64; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
64 64 s> 8\r\n
65 65 s> \x00\x00\x00\x01\x00\x02\x002
66 66 s> \r\n
67 67 s> 0\r\n
68 68 s> \r\n
69 69 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
70 70 response: [
71 71 b'\x1dok\x91\xd4J\xab\xa6\xd5\xe5\x80\xbc0\xa9\x94\x850\xdb\xe0\x0b',
72 72 b'\xaeI.6\xb0\xc83\x9f\xfa\xf3(\xd0\x0b\x85\xb4R]\xe1\x16^',
73 73 b')Dm-\xc5A\x9c_\x97Dz\x8b\xc0b\xe4\xcc2\x8b\xf2A'
74 74 ]
75 75
76 76 Requesting just the public heads works
77 77
78 78 $ sendhttpv2peer << EOF
79 79 > command heads
80 80 > publiconly 1
81 81 > EOF
82 82 creating http peer for wire protocol version 2
83 83 sending heads command
84 s> POST /api/exp-http-v2-0001/ro/heads HTTP/1.1\r\n
84 s> POST /api/exp-http-v2-0002/ro/heads HTTP/1.1\r\n
85 85 s> Accept-Encoding: identity\r\n
86 86 s> accept: application/mercurial-exp-framing-0005\r\n
87 87 s> content-type: application/mercurial-exp-framing-0005\r\n
88 88 s> content-length: 39\r\n
89 89 s> host: $LOCALIP:$HGPORT\r\n (glob)
90 90 s> user-agent: Mercurial debugwireproto\r\n
91 91 s> \r\n
92 92 s> \x1f\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa1JpubliconlyA1DnameEheads
93 93 s> makefile('rb', None)
94 94 s> HTTP/1.1 200 OK\r\n
95 95 s> Server: testing stub value\r\n
96 96 s> Date: $HTTP_DATE$\r\n
97 97 s> Content-Type: application/mercurial-exp-framing-0005\r\n
98 98 s> Transfer-Encoding: chunked\r\n
99 99 s> \r\n
100 100 s> 13\r\n
101 101 s> \x0b\x00\x00\x01\x00\x02\x011
102 102 s> \xa1FstatusBok
103 103 s> \r\n
104 104 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
105 105 s> 1e\r\n
106 106 s> \x16\x00\x00\x01\x00\x02\x001
107 107 s> \x81Tx\xd2\xdc\xa46\xb2\xf5\xb1\x88\xac&~)\xb8\x1e\x07&m8\xfc
108 108 s> \r\n
109 109 received frame(size=22; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
110 110 s> 8\r\n
111 111 s> \x00\x00\x00\x01\x00\x02\x002
112 112 s> \r\n
113 113 s> 0\r\n
114 114 s> \r\n
115 115 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
116 116 response: [
117 117 b'x\xd2\xdc\xa46\xb2\xf5\xb1\x88\xac&~)\xb8\x1e\x07&m8\xfc'
118 118 ]
119 119
120 120 $ cat error.log
@@ -1,154 +1,154 b''
1 1 $ . $TESTDIR/wireprotohelpers.sh
2 2
3 3 $ hg init server
4 4 $ enablehttpv2 server
5 5 $ cd server
6 6 $ hg debugdrawdag << EOF
7 7 > C D
8 8 > |/
9 9 > B
10 10 > |
11 11 > A
12 12 > EOF
13 13
14 14 $ hg log -T '{rev}:{node} {desc}\n'
15 15 3:be0ef73c17ade3fc89dc41701eb9fc3a91b58282 D
16 16 2:26805aba1e600a82e93661149f2313866a221a7b C
17 17 1:112478962961147124edd43549aedd1a335e44bf B
18 18 0:426bada5c67598ca65036d57d9e4b64b0c1ce7a0 A
19 19
20 20 $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
21 21 $ cat hg.pid > $DAEMON_PIDS
22 22
23 23 No arguments returns something reasonable
24 24
25 25 $ sendhttpv2peer << EOF
26 26 > command known
27 27 > EOF
28 28 creating http peer for wire protocol version 2
29 29 sending known command
30 s> POST /api/exp-http-v2-0001/ro/known HTTP/1.1\r\n
30 s> POST /api/exp-http-v2-0002/ro/known HTTP/1.1\r\n
31 31 s> Accept-Encoding: identity\r\n
32 32 s> accept: application/mercurial-exp-framing-0005\r\n
33 33 s> content-type: application/mercurial-exp-framing-0005\r\n
34 34 s> content-length: 20\r\n
35 35 s> host: $LOCALIP:$HGPORT\r\n (glob)
36 36 s> user-agent: Mercurial debugwireproto\r\n
37 37 s> \r\n
38 38 s> \x0c\x00\x00\x01\x00\x01\x01\x11\xa1DnameEknown
39 39 s> makefile('rb', None)
40 40 s> HTTP/1.1 200 OK\r\n
41 41 s> Server: testing stub value\r\n
42 42 s> Date: $HTTP_DATE$\r\n
43 43 s> Content-Type: application/mercurial-exp-framing-0005\r\n
44 44 s> Transfer-Encoding: chunked\r\n
45 45 s> \r\n
46 46 s> 13\r\n
47 47 s> \x0b\x00\x00\x01\x00\x02\x011
48 48 s> \xa1FstatusBok
49 49 s> \r\n
50 50 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
51 51 s> 9\r\n
52 52 s> \x01\x00\x00\x01\x00\x02\x001
53 53 s> @
54 54 s> \r\n
55 55 received frame(size=1; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
56 56 s> 8\r\n
57 57 s> \x00\x00\x00\x01\x00\x02\x002
58 58 s> \r\n
59 59 s> 0\r\n
60 60 s> \r\n
61 61 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
62 62 response: []
63 63
64 64 Single known node works
65 65
66 66 $ sendhttpv2peer << EOF
67 67 > command known
68 68 > nodes eval:[b'\x42\x6b\xad\xa5\xc6\x75\x98\xca\x65\x03\x6d\x57\xd9\xe4\xb6\x4b\x0c\x1c\xe7\xa0']
69 69 > EOF
70 70 creating http peer for wire protocol version 2
71 71 sending known command
72 s> POST /api/exp-http-v2-0001/ro/known HTTP/1.1\r\n
72 s> POST /api/exp-http-v2-0002/ro/known HTTP/1.1\r\n
73 73 s> Accept-Encoding: identity\r\n
74 74 s> accept: application/mercurial-exp-framing-0005\r\n
75 75 s> content-type: application/mercurial-exp-framing-0005\r\n
76 76 s> content-length: 54\r\n
77 77 s> host: $LOCALIP:$HGPORT\r\n (glob)
78 78 s> user-agent: Mercurial debugwireproto\r\n
79 79 s> \r\n
80 80 s> .\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa1Enodes\x81TBk\xad\xa5\xc6u\x98\xcae\x03mW\xd9\xe4\xb6K\x0c\x1c\xe7\xa0DnameEknown
81 81 s> makefile('rb', None)
82 82 s> HTTP/1.1 200 OK\r\n
83 83 s> Server: testing stub value\r\n
84 84 s> Date: $HTTP_DATE$\r\n
85 85 s> Content-Type: application/mercurial-exp-framing-0005\r\n
86 86 s> Transfer-Encoding: chunked\r\n
87 87 s> \r\n
88 88 s> 13\r\n
89 89 s> \x0b\x00\x00\x01\x00\x02\x011
90 90 s> \xa1FstatusBok
91 91 s> \r\n
92 92 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
93 93 s> a\r\n
94 94 s> \x02\x00\x00\x01\x00\x02\x001
95 95 s> A1
96 96 s> \r\n
97 97 received frame(size=2; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
98 98 s> 8\r\n
99 99 s> \x00\x00\x00\x01\x00\x02\x002
100 100 s> \r\n
101 101 s> 0\r\n
102 102 s> \r\n
103 103 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
104 104 response: [
105 105 True
106 106 ]
107 107
108 108 Multiple nodes works
109 109
110 110 $ sendhttpv2peer << EOF
111 111 > command known
112 112 > nodes eval:[b'\x42\x6b\xad\xa5\xc6\x75\x98\xca\x65\x03\x6d\x57\xd9\xe4\xb6\x4b\x0c\x1c\xe7\xa0', b'00000000000000000000', b'\x11\x24\x78\x96\x29\x61\x14\x71\x24\xed\xd4\x35\x49\xae\xdd\x1a\x33\x5e\x44\xbf']
113 113 > EOF
114 114 creating http peer for wire protocol version 2
115 115 sending known command
116 s> POST /api/exp-http-v2-0001/ro/known HTTP/1.1\r\n
116 s> POST /api/exp-http-v2-0002/ro/known HTTP/1.1\r\n
117 117 s> Accept-Encoding: identity\r\n
118 118 s> accept: application/mercurial-exp-framing-0005\r\n
119 119 s> content-type: application/mercurial-exp-framing-0005\r\n
120 120 s> content-length: 96\r\n
121 121 s> host: $LOCALIP:$HGPORT\r\n (glob)
122 122 s> user-agent: Mercurial debugwireproto\r\n
123 123 s> \r\n
124 124 s> X\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa1Enodes\x83TBk\xad\xa5\xc6u\x98\xcae\x03mW\xd9\xe4\xb6K\x0c\x1c\xe7\xa0T00000000000000000000T\x11$x\x96)a\x14q$\xed\xd45I\xae\xdd\x1a3^D\xbfDnameEknown
125 125 s> makefile('rb', None)
126 126 s> HTTP/1.1 200 OK\r\n
127 127 s> Server: testing stub value\r\n
128 128 s> Date: $HTTP_DATE$\r\n
129 129 s> Content-Type: application/mercurial-exp-framing-0005\r\n
130 130 s> Transfer-Encoding: chunked\r\n
131 131 s> \r\n
132 132 s> 13\r\n
133 133 s> \x0b\x00\x00\x01\x00\x02\x011
134 134 s> \xa1FstatusBok
135 135 s> \r\n
136 136 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
137 137 s> c\r\n
138 138 s> \x04\x00\x00\x01\x00\x02\x001
139 139 s> C101
140 140 s> \r\n
141 141 received frame(size=4; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
142 142 s> 8\r\n
143 143 s> \x00\x00\x00\x01\x00\x02\x002
144 144 s> \r\n
145 145 s> 0\r\n
146 146 s> \r\n
147 147 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
148 148 response: [
149 149 True,
150 150 False,
151 151 True
152 152 ]
153 153
154 154 $ cat error.log
@@ -1,161 +1,161 b''
1 1 $ . $TESTDIR/wireprotohelpers.sh
2 2
3 3 $ hg init server
4 4 $ enablehttpv2 server
5 5 $ cd server
6 6 $ hg debugdrawdag << EOF
7 7 > C D
8 8 > |/
9 9 > B
10 10 > |
11 11 > A
12 12 > EOF
13 13
14 14 $ hg phase --public -r C
15 15 $ hg book -r C @
16 16
17 17 $ hg log -T '{rev}:{node} {desc}\n'
18 18 3:be0ef73c17ade3fc89dc41701eb9fc3a91b58282 D
19 19 2:26805aba1e600a82e93661149f2313866a221a7b C
20 20 1:112478962961147124edd43549aedd1a335e44bf B
21 21 0:426bada5c67598ca65036d57d9e4b64b0c1ce7a0 A
22 22
23 23 $ hg serve -p $HGPORT -d --pid-file hg.pid -E error.log
24 24 $ cat hg.pid > $DAEMON_PIDS
25 25
26 26 Request for namespaces works
27 27
28 28 $ sendhttpv2peer << EOF
29 29 > command listkeys
30 30 > namespace namespaces
31 31 > EOF
32 32 creating http peer for wire protocol version 2
33 33 sending listkeys command
34 s> POST /api/exp-http-v2-0001/ro/listkeys HTTP/1.1\r\n
34 s> POST /api/exp-http-v2-0002/ro/listkeys HTTP/1.1\r\n
35 35 s> Accept-Encoding: identity\r\n
36 36 s> accept: application/mercurial-exp-framing-0005\r\n
37 37 s> content-type: application/mercurial-exp-framing-0005\r\n
38 38 s> content-length: 50\r\n
39 39 s> host: $LOCALIP:$HGPORT\r\n (glob)
40 40 s> user-agent: Mercurial debugwireproto\r\n
41 41 s> \r\n
42 42 s> *\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa1InamespaceJnamespacesDnameHlistkeys
43 43 s> makefile('rb', None)
44 44 s> HTTP/1.1 200 OK\r\n
45 45 s> Server: testing stub value\r\n
46 46 s> Date: $HTTP_DATE$\r\n
47 47 s> Content-Type: application/mercurial-exp-framing-0005\r\n
48 48 s> Transfer-Encoding: chunked\r\n
49 49 s> \r\n
50 50 s> 13\r\n
51 51 s> \x0b\x00\x00\x01\x00\x02\x011
52 52 s> \xa1FstatusBok
53 53 s> \r\n
54 54 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
55 55 s> 28\r\n
56 56 s> \x00\x00\x01\x00\x02\x001
57 57 s> \xa3Ibookmarks@Jnamespaces@Fphases@
58 58 s> \r\n
59 59 received frame(size=32; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
60 60 s> 8\r\n
61 61 s> \x00\x00\x00\x01\x00\x02\x002
62 62 s> \r\n
63 63 s> 0\r\n
64 64 s> \r\n
65 65 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
66 66 response: {
67 67 b'bookmarks': b'',
68 68 b'namespaces': b'',
69 69 b'phases': b''
70 70 }
71 71
72 72 Request for phases works
73 73
74 74 $ sendhttpv2peer << EOF
75 75 > command listkeys
76 76 > namespace phases
77 77 > EOF
78 78 creating http peer for wire protocol version 2
79 79 sending listkeys command
80 s> POST /api/exp-http-v2-0001/ro/listkeys HTTP/1.1\r\n
80 s> POST /api/exp-http-v2-0002/ro/listkeys HTTP/1.1\r\n
81 81 s> Accept-Encoding: identity\r\n
82 82 s> accept: application/mercurial-exp-framing-0005\r\n
83 83 s> content-type: application/mercurial-exp-framing-0005\r\n
84 84 s> content-length: 46\r\n
85 85 s> host: $LOCALIP:$HGPORT\r\n (glob)
86 86 s> user-agent: Mercurial debugwireproto\r\n
87 87 s> \r\n
88 88 s> &\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa1InamespaceFphasesDnameHlistkeys
89 89 s> makefile('rb', None)
90 90 s> HTTP/1.1 200 OK\r\n
91 91 s> Server: testing stub value\r\n
92 92 s> Date: $HTTP_DATE$\r\n
93 93 s> Content-Type: application/mercurial-exp-framing-0005\r\n
94 94 s> Transfer-Encoding: chunked\r\n
95 95 s> \r\n
96 96 s> 13\r\n
97 97 s> \x0b\x00\x00\x01\x00\x02\x011
98 98 s> \xa1FstatusBok
99 99 s> \r\n
100 100 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
101 101 s> 45\r\n
102 102 s> =\x00\x00\x01\x00\x02\x001
103 103 s> \xa2X(be0ef73c17ade3fc89dc41701eb9fc3a91b58282A1JpublishingDTrue
104 104 s> \r\n
105 105 received frame(size=61; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
106 106 s> 8\r\n
107 107 s> \x00\x00\x00\x01\x00\x02\x002
108 108 s> \r\n
109 109 s> 0\r\n
110 110 s> \r\n
111 111 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
112 112 response: {
113 113 b'be0ef73c17ade3fc89dc41701eb9fc3a91b58282': b'1',
114 114 b'publishing': b'True'
115 115 }
116 116
117 117 Request for bookmarks works
118 118
119 119 $ sendhttpv2peer << EOF
120 120 > command listkeys
121 121 > namespace bookmarks
122 122 > EOF
123 123 creating http peer for wire protocol version 2
124 124 sending listkeys command
125 s> POST /api/exp-http-v2-0001/ro/listkeys HTTP/1.1\r\n
125 s> POST /api/exp-http-v2-0002/ro/listkeys HTTP/1.1\r\n
126 126 s> Accept-Encoding: identity\r\n
127 127 s> accept: application/mercurial-exp-framing-0005\r\n
128 128 s> content-type: application/mercurial-exp-framing-0005\r\n
129 129 s> content-length: 49\r\n
130 130 s> host: $LOCALIP:$HGPORT\r\n (glob)
131 131 s> user-agent: Mercurial debugwireproto\r\n
132 132 s> \r\n
133 133 s> )\x00\x00\x01\x00\x01\x01\x11\xa2Dargs\xa1InamespaceIbookmarksDnameHlistkeys
134 134 s> makefile('rb', None)
135 135 s> HTTP/1.1 200 OK\r\n
136 136 s> Server: testing stub value\r\n
137 137 s> Date: $HTTP_DATE$\r\n
138 138 s> Content-Type: application/mercurial-exp-framing-0005\r\n
139 139 s> Transfer-Encoding: chunked\r\n
140 140 s> \r\n
141 141 s> 13\r\n
142 142 s> \x0b\x00\x00\x01\x00\x02\x011
143 143 s> \xa1FstatusBok
144 144 s> \r\n
145 145 received frame(size=11; request=1; stream=2; streamflags=stream-begin; type=command-response; flags=continuation)
146 146 s> 35\r\n
147 147 s> -\x00\x00\x01\x00\x02\x001
148 148 s> \xa1A@X(26805aba1e600a82e93661149f2313866a221a7b
149 149 s> \r\n
150 150 received frame(size=45; request=1; stream=2; streamflags=; type=command-response; flags=continuation)
151 151 s> 8\r\n
152 152 s> \x00\x00\x00\x01\x00\x02\x002
153 153 s> \r\n
154 154 s> 0\r\n
155 155 s> \r\n
156 156 received frame(size=0; request=1; stream=2; streamflags=; type=command-response; flags=eos)
157 157 response: {
158 158 b'@': b'26805aba1e600a82e93661149f2313866a221a7b'
159 159 }
160 160
161 161 $ cat error.log
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
1 NO CONTENT: modified file
The requested commit or file is too big and content was truncated. Show full diff
General Comments 0
You need to be logged in to leave comments. Login now