##// END OF EJS Templates
bundle2: make error testing more modular...
Pierre-Yves David -
r21178:9a813e70 stable
parent child Browse files
Show More
@@ -1,962 +1,971
1 1
2 2 Create an extension to test bundle2 API
3 3
4 4 $ cat > bundle2.py << EOF
5 5 > """A small extension to test bundle2 implementation
6 6 >
7 7 > Current bundle2 implementation is far too limited to be used in any core
8 8 > code. We still need to be able to test it while it grow up.
9 9 > """
10 10 >
11 11 > import sys
12 12 > from mercurial import cmdutil
13 13 > from mercurial import util
14 14 > from mercurial import bundle2
15 15 > from mercurial import scmutil
16 16 > from mercurial import discovery
17 17 > from mercurial import changegroup
18 18 > cmdtable = {}
19 19 > command = cmdutil.command(cmdtable)
20 20 >
21 21 > ELEPHANTSSONG = """Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
22 22 > Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
23 23 > Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko."""
24 24 > assert len(ELEPHANTSSONG) == 178 # future test say 178 bytes, trust it.
25 25 >
26 26 > @bundle2.parthandler('test:song')
27 27 > def songhandler(op, part):
28 28 > """handle a "test:song" bundle2 part, printing the lyrics on stdin"""
29 29 > op.ui.write('The choir starts singing:\n')
30 30 > verses = 0
31 31 > for line in part.read().split('\n'):
32 32 > op.ui.write(' %s\n' % line)
33 33 > verses += 1
34 34 > op.records.add('song', {'verses': verses})
35 35 >
36 36 > @bundle2.parthandler('test:ping')
37 37 > def pinghandler(op, part):
38 38 > op.ui.write('received ping request (id %i)\n' % part.id)
39 39 > if op.reply is not None and 'ping-pong' in op.reply.capabilities:
40 40 > op.ui.write_err('replying to ping request (id %i)\n' % part.id)
41 41 > rpart = bundle2.bundlepart('test:pong',
42 42 > [('in-reply-to', str(part.id))])
43 43 > op.reply.addpart(rpart)
44 44 >
45 45 > @bundle2.parthandler('test:debugreply')
46 46 > def debugreply(op, part):
47 47 > """print data about the capacity of the bundle reply"""
48 48 > if op.reply is None:
49 49 > op.ui.write('debugreply: no reply\n')
50 50 > else:
51 51 > op.ui.write('debugreply: capabilities:\n')
52 52 > for cap in sorted(op.reply.capabilities):
53 53 > op.ui.write('debugreply: %r\n' % cap)
54 54 > for val in op.reply.capabilities[cap]:
55 55 > op.ui.write('debugreply: %r\n' % val)
56 56 >
57 57 > @command('bundle2',
58 58 > [('', 'param', [], 'stream level parameter'),
59 59 > ('', 'unknown', False, 'include an unknown mandatory part in the bundle'),
60 60 > ('', 'parts', False, 'include some arbitrary parts to the bundle'),
61 61 > ('', 'reply', False, 'produce a reply bundle'),
62 62 > ('r', 'rev', [], 'includes those changeset in the bundle'),],
63 63 > '[OUTPUTFILE]')
64 64 > def cmdbundle2(ui, repo, path=None, **opts):
65 65 > """write a bundle2 container on standard ouput"""
66 66 > bundler = bundle2.bundle20(ui)
67 67 > for p in opts['param']:
68 68 > p = p.split('=', 1)
69 69 > try:
70 70 > bundler.addparam(*p)
71 71 > except ValueError, exc:
72 72 > raise util.Abort('%s' % exc)
73 73 >
74 74 > if opts['reply']:
75 75 > capsstring = 'ping-pong\nelephants=babar,celeste\ncity%3D%21=celeste%2Cville'
76 76 > bundler.addpart(bundle2.bundlepart('b2x:replycaps', data=capsstring))
77 77 >
78 78 > revs = opts['rev']
79 79 > if 'rev' in opts:
80 80 > revs = scmutil.revrange(repo, opts['rev'])
81 81 > if revs:
82 82 > # very crude version of a changegroup part creation
83 83 > bundled = repo.revs('%ld::%ld', revs, revs)
84 84 > headmissing = [c.node() for c in repo.set('heads(%ld)', revs)]
85 85 > headcommon = [c.node() for c in repo.set('parents(%ld) - %ld', revs, revs)]
86 86 > outgoing = discovery.outgoing(repo.changelog, headcommon, headmissing)
87 87 > cg = changegroup.getlocalbundle(repo, 'test:bundle2', outgoing, None)
88 88 > part = bundle2.bundlepart('b2x:changegroup', data=cg.getchunks())
89 89 > bundler.addpart(part)
90 90 >
91 91 > if opts['parts']:
92 92 > part = bundle2.bundlepart('test:empty')
93 93 > bundler.addpart(part)
94 94 > # add a second one to make sure we handle multiple parts
95 95 > part = bundle2.bundlepart('test:empty')
96 96 > bundler.addpart(part)
97 97 > part = bundle2.bundlepart('test:song', data=ELEPHANTSSONG)
98 98 > bundler.addpart(part)
99 99 > part = bundle2.bundlepart('test:debugreply')
100 100 > bundler.addpart(part)
101 101 > part = bundle2.bundlepart('test:math',
102 102 > [('pi', '3.14'), ('e', '2.72')],
103 103 > [('cooking', 'raw')],
104 104 > '42')
105 105 > bundler.addpart(part)
106 106 > if opts['unknown']:
107 107 > part = bundle2.bundlepart('test:UNKNOWN',
108 108 > data='some random content')
109 109 > bundler.addpart(part)
110 110 > if opts['parts']:
111 111 > part = bundle2.bundlepart('test:ping')
112 112 > bundler.addpart(part)
113 113 >
114 114 > if path is None:
115 115 > file = sys.stdout
116 116 > else:
117 117 > file = open(path, 'w')
118 118 >
119 119 > for chunk in bundler.getchunks():
120 120 > file.write(chunk)
121 121 >
122 122 > @command('unbundle2', [], '')
123 123 > def cmdunbundle2(ui, repo, replypath=None):
124 124 > """process a bundle2 stream from stdin on the current repo"""
125 125 > try:
126 126 > tr = None
127 127 > lock = repo.lock()
128 128 > tr = repo.transaction('processbundle')
129 129 > try:
130 130 > unbundler = bundle2.unbundle20(ui, sys.stdin)
131 131 > op = bundle2.processbundle(repo, unbundler, lambda: tr)
132 132 > tr.close()
133 133 > except KeyError, exc:
134 134 > raise util.Abort('missing support for %s' % exc)
135 135 > finally:
136 136 > if tr is not None:
137 137 > tr.release()
138 138 > lock.release()
139 139 > remains = sys.stdin.read()
140 140 > ui.write('%i unread bytes\n' % len(remains))
141 141 > if op.records['song']:
142 142 > totalverses = sum(r['verses'] for r in op.records['song'])
143 143 > ui.write('%i total verses sung\n' % totalverses)
144 144 > for rec in op.records['changegroup']:
145 145 > ui.write('addchangegroup return: %i\n' % rec['return'])
146 146 > if op.reply is not None and replypath is not None:
147 147 > file = open(replypath, 'w')
148 148 > for chunk in op.reply.getchunks():
149 149 > file.write(chunk)
150 150 >
151 151 > @command('statbundle2', [], '')
152 152 > def cmdstatbundle2(ui, repo):
153 153 > """print statistic on the bundle2 container read from stdin"""
154 154 > unbundler = bundle2.unbundle20(ui, sys.stdin)
155 155 > try:
156 156 > params = unbundler.params
157 157 > except KeyError, exc:
158 158 > raise util.Abort('unknown parameters: %s' % exc)
159 159 > ui.write('options count: %i\n' % len(params))
160 160 > for key in sorted(params):
161 161 > ui.write('- %s\n' % key)
162 162 > value = params[key]
163 163 > if value is not None:
164 164 > ui.write(' %s\n' % value)
165 165 > count = 0
166 166 > for p in unbundler.iterparts():
167 167 > count += 1
168 168 > ui.write(' :%s:\n' % p.type)
169 169 > ui.write(' mandatory: %i\n' % len(p.mandatoryparams))
170 170 > ui.write(' advisory: %i\n' % len(p.advisoryparams))
171 171 > ui.write(' payload: %i bytes\n' % len(p.read()))
172 172 > ui.write('parts count: %i\n' % count)
173 173 > EOF
174 174 $ cat >> $HGRCPATH << EOF
175 175 > [extensions]
176 176 > bundle2=$TESTTMP/bundle2.py
177 177 > [experimental]
178 178 > bundle2-exp=True
179 179 > [ui]
180 180 > ssh=python "$TESTDIR/dummyssh"
181 181 > [web]
182 182 > push_ssl = false
183 183 > allow_push = *
184 184 > EOF
185 185
186 186 The extension requires a repo (currently unused)
187 187
188 188 $ hg init main
189 189 $ cd main
190 190 $ touch a
191 191 $ hg add a
192 192 $ hg commit -m 'a'
193 193
194 194
195 195 Empty bundle
196 196 =================
197 197
198 198 - no option
199 199 - no parts
200 200
201 201 Test bundling
202 202
203 203 $ hg bundle2
204 204 HG2X\x00\x00\x00\x00 (no-eol) (esc)
205 205
206 206 Test unbundling
207 207
208 208 $ hg bundle2 | hg statbundle2
209 209 options count: 0
210 210 parts count: 0
211 211
212 212 Test old style bundle are detected and refused
213 213
214 214 $ hg bundle --all ../bundle.hg
215 215 1 changesets found
216 216 $ hg statbundle2 < ../bundle.hg
217 217 abort: unknown bundle version 10
218 218 [255]
219 219
220 220 Test parameters
221 221 =================
222 222
223 223 - some options
224 224 - no parts
225 225
226 226 advisory parameters, no value
227 227 -------------------------------
228 228
229 229 Simplest possible parameters form
230 230
231 231 Test generation simple option
232 232
233 233 $ hg bundle2 --param 'caution'
234 234 HG2X\x00\x07caution\x00\x00 (no-eol) (esc)
235 235
236 236 Test unbundling
237 237
238 238 $ hg bundle2 --param 'caution' | hg statbundle2
239 239 options count: 1
240 240 - caution
241 241 parts count: 0
242 242
243 243 Test generation multiple option
244 244
245 245 $ hg bundle2 --param 'caution' --param 'meal'
246 246 HG2X\x00\x0ccaution meal\x00\x00 (no-eol) (esc)
247 247
248 248 Test unbundling
249 249
250 250 $ hg bundle2 --param 'caution' --param 'meal' | hg statbundle2
251 251 options count: 2
252 252 - caution
253 253 - meal
254 254 parts count: 0
255 255
256 256 advisory parameters, with value
257 257 -------------------------------
258 258
259 259 Test generation
260 260
261 261 $ hg bundle2 --param 'caution' --param 'meal=vegan' --param 'elephants'
262 262 HG2X\x00\x1ccaution meal=vegan elephants\x00\x00 (no-eol) (esc)
263 263
264 264 Test unbundling
265 265
266 266 $ hg bundle2 --param 'caution' --param 'meal=vegan' --param 'elephants' | hg statbundle2
267 267 options count: 3
268 268 - caution
269 269 - elephants
270 270 - meal
271 271 vegan
272 272 parts count: 0
273 273
274 274 parameter with special char in value
275 275 ---------------------------------------------------
276 276
277 277 Test generation
278 278
279 279 $ hg bundle2 --param 'e|! 7/=babar%#==tutu' --param simple
280 280 HG2X\x00)e%7C%21%207/=babar%25%23%3D%3Dtutu simple\x00\x00 (no-eol) (esc)
281 281
282 282 Test unbundling
283 283
284 284 $ hg bundle2 --param 'e|! 7/=babar%#==tutu' --param simple | hg statbundle2
285 285 options count: 2
286 286 - e|! 7/
287 287 babar%#==tutu
288 288 - simple
289 289 parts count: 0
290 290
291 291 Test unknown mandatory option
292 292 ---------------------------------------------------
293 293
294 294 $ hg bundle2 --param 'Gravity' | hg statbundle2
295 295 abort: unknown parameters: 'Gravity'
296 296 [255]
297 297
298 298 Test debug output
299 299 ---------------------------------------------------
300 300
301 301 bundling debug
302 302
303 303 $ hg bundle2 --debug --param 'e|! 7/=babar%#==tutu' --param simple ../out.hg2
304 304 start emission of HG2X stream
305 305 bundle parameter: e%7C%21%207/=babar%25%23%3D%3Dtutu simple
306 306 start of parts
307 307 end of bundle
308 308
309 309 file content is ok
310 310
311 311 $ cat ../out.hg2
312 312 HG2X\x00)e%7C%21%207/=babar%25%23%3D%3Dtutu simple\x00\x00 (no-eol) (esc)
313 313
314 314 unbundling debug
315 315
316 316 $ hg statbundle2 --debug < ../out.hg2
317 317 start processing of HG2X stream
318 318 reading bundle2 stream parameters
319 319 ignoring unknown parameter 'e|! 7/'
320 320 ignoring unknown parameter 'simple'
321 321 options count: 2
322 322 - e|! 7/
323 323 babar%#==tutu
324 324 - simple
325 325 start extraction of bundle2 parts
326 326 part header size: 0
327 327 end of bundle2 stream
328 328 parts count: 0
329 329
330 330
331 331 Test buggy input
332 332 ---------------------------------------------------
333 333
334 334 empty parameter name
335 335
336 336 $ hg bundle2 --param '' --quiet
337 337 abort: empty parameter name
338 338 [255]
339 339
340 340 bad parameter name
341 341
342 342 $ hg bundle2 --param 42babar
343 343 abort: non letter first character: '42babar'
344 344 [255]
345 345
346 346
347 347 Test part
348 348 =================
349 349
350 350 $ hg bundle2 --parts ../parts.hg2 --debug
351 351 start emission of HG2X stream
352 352 bundle parameter:
353 353 start of parts
354 354 bundle part: "test:empty"
355 355 bundle part: "test:empty"
356 356 bundle part: "test:song"
357 357 bundle part: "test:debugreply"
358 358 bundle part: "test:math"
359 359 bundle part: "test:ping"
360 360 end of bundle
361 361
362 362 $ cat ../parts.hg2
363 363 HG2X\x00\x00\x00\x11 (esc)
364 364 test:empty\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x11 (esc)
365 365 test:empty\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x10 test:song\x00\x00\x00\x02\x00\x00\x00\x00\x00\xb2Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko (esc)
366 366 Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
367 367 Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.\x00\x00\x00\x00\x00\x16\x0ftest:debugreply\x00\x00\x00\x03\x00\x00\x00\x00\x00\x00\x00+ test:math\x00\x00\x00\x04\x02\x01\x02\x04\x01\x04\x07\x03pi3.14e2.72cookingraw\x00\x00\x00\x0242\x00\x00\x00\x00\x00\x10 test:ping\x00\x00\x00\x05\x00\x00\x00\x00\x00\x00\x00\x00 (no-eol) (esc)
368 368
369 369
370 370 $ hg statbundle2 < ../parts.hg2
371 371 options count: 0
372 372 :test:empty:
373 373 mandatory: 0
374 374 advisory: 0
375 375 payload: 0 bytes
376 376 :test:empty:
377 377 mandatory: 0
378 378 advisory: 0
379 379 payload: 0 bytes
380 380 :test:song:
381 381 mandatory: 0
382 382 advisory: 0
383 383 payload: 178 bytes
384 384 :test:debugreply:
385 385 mandatory: 0
386 386 advisory: 0
387 387 payload: 0 bytes
388 388 :test:math:
389 389 mandatory: 2
390 390 advisory: 1
391 391 payload: 2 bytes
392 392 :test:ping:
393 393 mandatory: 0
394 394 advisory: 0
395 395 payload: 0 bytes
396 396 parts count: 6
397 397
398 398 $ hg statbundle2 --debug < ../parts.hg2
399 399 start processing of HG2X stream
400 400 reading bundle2 stream parameters
401 401 options count: 0
402 402 start extraction of bundle2 parts
403 403 part header size: 17
404 404 part type: "test:empty"
405 405 part id: "0"
406 406 part parameters: 0
407 407 :test:empty:
408 408 mandatory: 0
409 409 advisory: 0
410 410 payload chunk size: 0
411 411 payload: 0 bytes
412 412 part header size: 17
413 413 part type: "test:empty"
414 414 part id: "1"
415 415 part parameters: 0
416 416 :test:empty:
417 417 mandatory: 0
418 418 advisory: 0
419 419 payload chunk size: 0
420 420 payload: 0 bytes
421 421 part header size: 16
422 422 part type: "test:song"
423 423 part id: "2"
424 424 part parameters: 0
425 425 :test:song:
426 426 mandatory: 0
427 427 advisory: 0
428 428 payload chunk size: 178
429 429 payload chunk size: 0
430 430 payload: 178 bytes
431 431 part header size: 22
432 432 part type: "test:debugreply"
433 433 part id: "3"
434 434 part parameters: 0
435 435 :test:debugreply:
436 436 mandatory: 0
437 437 advisory: 0
438 438 payload chunk size: 0
439 439 payload: 0 bytes
440 440 part header size: 43
441 441 part type: "test:math"
442 442 part id: "4"
443 443 part parameters: 3
444 444 :test:math:
445 445 mandatory: 2
446 446 advisory: 1
447 447 payload chunk size: 2
448 448 payload chunk size: 0
449 449 payload: 2 bytes
450 450 part header size: 16
451 451 part type: "test:ping"
452 452 part id: "5"
453 453 part parameters: 0
454 454 :test:ping:
455 455 mandatory: 0
456 456 advisory: 0
457 457 payload chunk size: 0
458 458 payload: 0 bytes
459 459 part header size: 0
460 460 end of bundle2 stream
461 461 parts count: 6
462 462
463 463 Test actual unbundling of test part
464 464 =======================================
465 465
466 466 Process the bundle
467 467
468 468 $ hg unbundle2 --debug < ../parts.hg2
469 469 start processing of HG2X stream
470 470 reading bundle2 stream parameters
471 471 start extraction of bundle2 parts
472 472 part header size: 17
473 473 part type: "test:empty"
474 474 part id: "0"
475 475 part parameters: 0
476 476 ignoring unknown advisory part 'test:empty'
477 477 payload chunk size: 0
478 478 part header size: 17
479 479 part type: "test:empty"
480 480 part id: "1"
481 481 part parameters: 0
482 482 ignoring unknown advisory part 'test:empty'
483 483 payload chunk size: 0
484 484 part header size: 16
485 485 part type: "test:song"
486 486 part id: "2"
487 487 part parameters: 0
488 488 found a handler for part 'test:song'
489 489 The choir starts singing:
490 490 payload chunk size: 178
491 491 payload chunk size: 0
492 492 Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
493 493 Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
494 494 Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
495 495 part header size: 22
496 496 part type: "test:debugreply"
497 497 part id: "3"
498 498 part parameters: 0
499 499 found a handler for part 'test:debugreply'
500 500 debugreply: no reply
501 501 payload chunk size: 0
502 502 part header size: 43
503 503 part type: "test:math"
504 504 part id: "4"
505 505 part parameters: 3
506 506 ignoring unknown advisory part 'test:math'
507 507 payload chunk size: 2
508 508 payload chunk size: 0
509 509 part header size: 16
510 510 part type: "test:ping"
511 511 part id: "5"
512 512 part parameters: 0
513 513 found a handler for part 'test:ping'
514 514 received ping request (id 5)
515 515 payload chunk size: 0
516 516 part header size: 0
517 517 end of bundle2 stream
518 518 0 unread bytes
519 519 3 total verses sung
520 520
521 521 Unbundle with an unknown mandatory part
522 522 (should abort)
523 523
524 524 $ hg bundle2 --parts --unknown ../unknown.hg2
525 525
526 526 $ hg unbundle2 < ../unknown.hg2
527 527 The choir starts singing:
528 528 Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
529 529 Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
530 530 Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
531 531 debugreply: no reply
532 532 0 unread bytes
533 533 abort: missing support for 'test:unknown'
534 534 [255]
535 535
536 536 unbundle with a reply
537 537
538 538 $ hg bundle2 --parts --reply ../parts-reply.hg2
539 539 $ hg unbundle2 ../reply.hg2 < ../parts-reply.hg2
540 540 0 unread bytes
541 541 3 total verses sung
542 542
543 543 The reply is a bundle
544 544
545 545 $ cat ../reply.hg2
546 546 HG2X\x00\x00\x00\x1f (esc)
547 547 b2x:output\x00\x00\x00\x00\x00\x01\x0b\x01in-reply-to3\x00\x00\x00\xd9The choir starts singing: (esc)
548 548 Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
549 549 Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
550 550 Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
551 551 \x00\x00\x00\x00\x00\x1f (esc)
552 552 b2x:output\x00\x00\x00\x01\x00\x01\x0b\x01in-reply-to4\x00\x00\x00\xc9debugreply: capabilities: (esc)
553 553 debugreply: 'city=!'
554 554 debugreply: 'celeste,ville'
555 555 debugreply: 'elephants'
556 556 debugreply: 'babar'
557 557 debugreply: 'celeste'
558 558 debugreply: 'ping-pong'
559 559 \x00\x00\x00\x00\x00\x1e test:pong\x00\x00\x00\x02\x01\x00\x0b\x01in-reply-to6\x00\x00\x00\x00\x00\x1f (esc)
560 560 b2x:output\x00\x00\x00\x03\x00\x01\x0b\x01in-reply-to6\x00\x00\x00=received ping request (id 6) (esc)
561 561 replying to ping request (id 6)
562 562 \x00\x00\x00\x00\x00\x00 (no-eol) (esc)
563 563
564 564 The reply is valid
565 565
566 566 $ hg statbundle2 < ../reply.hg2
567 567 options count: 0
568 568 :b2x:output:
569 569 mandatory: 0
570 570 advisory: 1
571 571 payload: 217 bytes
572 572 :b2x:output:
573 573 mandatory: 0
574 574 advisory: 1
575 575 payload: 201 bytes
576 576 :test:pong:
577 577 mandatory: 1
578 578 advisory: 0
579 579 payload: 0 bytes
580 580 :b2x:output:
581 581 mandatory: 0
582 582 advisory: 1
583 583 payload: 61 bytes
584 584 parts count: 4
585 585
586 586 Unbundle the reply to get the output:
587 587
588 588 $ hg unbundle2 < ../reply.hg2
589 589 remote: The choir starts singing:
590 590 remote: Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
591 591 remote: Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
592 592 remote: Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
593 593 remote: debugreply: capabilities:
594 594 remote: debugreply: 'city=!'
595 595 remote: debugreply: 'celeste,ville'
596 596 remote: debugreply: 'elephants'
597 597 remote: debugreply: 'babar'
598 598 remote: debugreply: 'celeste'
599 599 remote: debugreply: 'ping-pong'
600 600 remote: received ping request (id 6)
601 601 remote: replying to ping request (id 6)
602 602 0 unread bytes
603 603
604 604 Support for changegroup
605 605 ===================================
606 606
607 607 $ hg unbundle $TESTDIR/bundles/rebase.hg
608 608 adding changesets
609 609 adding manifests
610 610 adding file changes
611 611 added 8 changesets with 7 changes to 7 files (+3 heads)
612 612 (run 'hg heads' to see heads, 'hg merge' to merge)
613 613
614 614 $ hg log -G
615 615 o changeset: 8:02de42196ebe
616 616 | tag: tip
617 617 | parent: 6:24b6387c8c8c
618 618 | user: Nicolas Dumazet <nicdumz.commits@gmail.com>
619 619 | date: Sat Apr 30 15:24:48 2011 +0200
620 620 | summary: H
621 621 |
622 622 | o changeset: 7:eea13746799a
623 623 |/| parent: 6:24b6387c8c8c
624 624 | | parent: 5:9520eea781bc
625 625 | | user: Nicolas Dumazet <nicdumz.commits@gmail.com>
626 626 | | date: Sat Apr 30 15:24:48 2011 +0200
627 627 | | summary: G
628 628 | |
629 629 o | changeset: 6:24b6387c8c8c
630 630 | | parent: 1:cd010b8cd998
631 631 | | user: Nicolas Dumazet <nicdumz.commits@gmail.com>
632 632 | | date: Sat Apr 30 15:24:48 2011 +0200
633 633 | | summary: F
634 634 | |
635 635 | o changeset: 5:9520eea781bc
636 636 |/ parent: 1:cd010b8cd998
637 637 | user: Nicolas Dumazet <nicdumz.commits@gmail.com>
638 638 | date: Sat Apr 30 15:24:48 2011 +0200
639 639 | summary: E
640 640 |
641 641 | o changeset: 4:32af7686d403
642 642 | | user: Nicolas Dumazet <nicdumz.commits@gmail.com>
643 643 | | date: Sat Apr 30 15:24:48 2011 +0200
644 644 | | summary: D
645 645 | |
646 646 | o changeset: 3:5fddd98957c8
647 647 | | user: Nicolas Dumazet <nicdumz.commits@gmail.com>
648 648 | | date: Sat Apr 30 15:24:48 2011 +0200
649 649 | | summary: C
650 650 | |
651 651 | o changeset: 2:42ccdea3bb16
652 652 |/ user: Nicolas Dumazet <nicdumz.commits@gmail.com>
653 653 | date: Sat Apr 30 15:24:48 2011 +0200
654 654 | summary: B
655 655 |
656 656 o changeset: 1:cd010b8cd998
657 657 parent: -1:000000000000
658 658 user: Nicolas Dumazet <nicdumz.commits@gmail.com>
659 659 date: Sat Apr 30 15:24:48 2011 +0200
660 660 summary: A
661 661
662 662 @ changeset: 0:3903775176ed
663 663 user: test
664 664 date: Thu Jan 01 00:00:00 1970 +0000
665 665 summary: a
666 666
667 667
668 668 $ hg bundle2 --debug --rev '8+7+5+4' ../rev.hg2
669 669 4 changesets found
670 670 list of changesets:
671 671 32af7686d403cf45b5d95f2d70cebea587ac806a
672 672 9520eea781bcca16c1e15acc0ba14335a0e8e5ba
673 673 eea13746799a9e0bfd88f29d3c2e9dc9389f524f
674 674 02de42196ebee42ef284b6780a87cdc96e8eaab6
675 675 start emission of HG2X stream
676 676 bundle parameter:
677 677 start of parts
678 678 bundle part: "b2x:changegroup"
679 679 bundling: 1/4 changesets (25.00%)
680 680 bundling: 2/4 changesets (50.00%)
681 681 bundling: 3/4 changesets (75.00%)
682 682 bundling: 4/4 changesets (100.00%)
683 683 bundling: 1/4 manifests (25.00%)
684 684 bundling: 2/4 manifests (50.00%)
685 685 bundling: 3/4 manifests (75.00%)
686 686 bundling: 4/4 manifests (100.00%)
687 687 bundling: D 1/3 files (33.33%)
688 688 bundling: E 2/3 files (66.67%)
689 689 bundling: H 3/3 files (100.00%)
690 690 end of bundle
691 691
692 692 $ cat ../rev.hg2
693 693 HG2X\x00\x00\x00\x16\x0fb2x:changegroup\x00\x00\x00\x00\x00\x00\x00\x00\x06\x13\x00\x00\x00\xa42\xafv\x86\xd4\x03\xcfE\xb5\xd9_-p\xce\xbe\xa5\x87\xac\x80j_\xdd\xd9\x89W\xc8\xa5JMCm\xfe\x1d\xa9\xd8\x7f!\xa1\xb9{\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\xafv\x86\xd4\x03\xcfE\xb5\xd9_-p\xce\xbe\xa5\x87\xac\x80j\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00)6e1f4c47ecb533ffd0c8e52cdc88afb6cd39e20c (esc)
694 694 \x00\x00\x00f\x00\x00\x00h\x00\x00\x00\x02D (esc)
695 695 \x00\x00\x00i\x00\x00\x00j\x00\x00\x00\x01D\x00\x00\x00\xa4\x95 \xee\xa7\x81\xbc\xca\x16\xc1\xe1Z\xcc\x0b\xa1C5\xa0\xe8\xe5\xba\xcd\x01\x0b\x8c\xd9\x98\xf3\x98\x1aZ\x81\x15\xf9O\x8d\xa4\xabP`\x89\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95 \xee\xa7\x81\xbc\xca\x16\xc1\xe1Z\xcc\x0b\xa1C5\xa0\xe8\xe5\xba\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00)4dece9c826f69490507b98c6383a3009b295837d (esc)
696 696 \x00\x00\x00f\x00\x00\x00h\x00\x00\x00\x02E (esc)
697 697 \x00\x00\x00i\x00\x00\x00j\x00\x00\x00\x01E\x00\x00\x00\xa2\xee\xa17Fy\x9a\x9e\x0b\xfd\x88\xf2\x9d<.\x9d\xc98\x9fRO$\xb68|\x8c\x8c\xae7\x17\x88\x80\xf3\xfa\x95\xde\xd3\xcb\x1c\xf7\x85\x95 \xee\xa7\x81\xbc\xca\x16\xc1\xe1Z\xcc\x0b\xa1C5\xa0\xe8\xe5\xba\xee\xa17Fy\x9a\x9e\x0b\xfd\x88\xf2\x9d<.\x9d\xc98\x9fRO\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00)365b93d57fdf4814e2b5911d6bacff2b12014441 (esc)
698 698 \x00\x00\x00f\x00\x00\x00h\x00\x00\x00\x00\x00\x00\x00i\x00\x00\x00j\x00\x00\x00\x01G\x00\x00\x00\xa4\x02\xdeB\x19n\xbe\xe4.\xf2\x84\xb6x (esc)
699 699 \x87\xcd\xc9n\x8e\xaa\xb6$\xb68|\x8c\x8c\xae7\x17\x88\x80\xf3\xfa\x95\xde\xd3\xcb\x1c\xf7\x85\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xdeB\x19n\xbe\xe4.\xf2\x84\xb6x (esc)
700 700 \x87\xcd\xc9n\x8e\xaa\xb6\x00\x00\x00\x00\x00\x00\x00)\x00\x00\x00)8bee48edc7318541fc0013ee41b089276a8c24bf (esc)
701 701 \x00\x00\x00f\x00\x00\x00f\x00\x00\x00\x02H (esc)
702 702 \x00\x00\x00g\x00\x00\x00h\x00\x00\x00\x01H\x00\x00\x00\x00\x00\x00\x00\x8bn\x1fLG\xec\xb53\xff\xd0\xc8\xe5,\xdc\x88\xaf\xb6\xcd9\xe2\x0cf\xa5\xa0\x18\x17\xfd\xf5#\x9c'8\x02\xb5\xb7a\x8d\x05\x1c\x89\xe4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\xafv\x86\xd4\x03\xcfE\xb5\xd9_-p\xce\xbe\xa5\x87\xac\x80j\x00\x00\x00\x81\x00\x00\x00\x81\x00\x00\x00+D\x00c3f1ca2924c16a19b0656a84900e504e5b0aec2d (esc)
703 703 \x00\x00\x00\x8bM\xec\xe9\xc8&\xf6\x94\x90P{\x98\xc68:0 \xb2\x95\x83}\x00}\x8c\x9d\x88\x84\x13%\xf5\xc6\xb0cq\xb3[N\x8a+\x1a\x83\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95 \xee\xa7\x81\xbc\xca\x16\xc1\xe1Z\xcc\x0b\xa1C5\xa0\xe8\xe5\xba\x00\x00\x00+\x00\x00\x00\xac\x00\x00\x00+E\x009c6fd0350a6c0d0c49d4a9c5017cf07043f54e58 (esc)
704 704 \x00\x00\x00\x8b6[\x93\xd5\x7f\xdfH\x14\xe2\xb5\x91\x1dk\xac\xff+\x12\x01DA(\xa5\x84\xc6^\xf1!\xf8\x9e\xb6j\xb7\xd0\xbc\x15=\x80\x99\xe7\xceM\xec\xe9\xc8&\xf6\x94\x90P{\x98\xc68:0 \xb2\x95\x83}\xee\xa17Fy\x9a\x9e\x0b\xfd\x88\xf2\x9d<.\x9d\xc98\x9fRO\x00\x00\x00V\x00\x00\x00V\x00\x00\x00+F\x0022bfcfd62a21a3287edbd4d656218d0f525ed76a (esc)
705 705 \x00\x00\x00\x97\x8b\xeeH\xed\xc71\x85A\xfc\x00\x13\xeeA\xb0\x89'j\x8c$\xbf(\xa5\x84\xc6^\xf1!\xf8\x9e\xb6j\xb7\xd0\xbc\x15=\x80\x99\xe7\xce\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xdeB\x19n\xbe\xe4.\xf2\x84\xb6x (esc)
706 706 \x87\xcd\xc9n\x8e\xaa\xb6\x00\x00\x00+\x00\x00\x00V\x00\x00\x00\x00\x00\x00\x00\x81\x00\x00\x00\x81\x00\x00\x00+H\x008500189e74a9e0475e822093bc7db0d631aeb0b4 (esc)
707 707 \x00\x00\x00\x00\x00\x00\x00\x05D\x00\x00\x00b\xc3\xf1\xca)$\xc1j\x19\xb0ej\x84\x90\x0ePN[ (esc)
708 708 \xec-\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x002\xafv\x86\xd4\x03\xcfE\xb5\xd9_-p\xce\xbe\xa5\x87\xac\x80j\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02D (esc)
709 709 \x00\x00\x00\x00\x00\x00\x00\x05E\x00\x00\x00b\x9co\xd05 (esc)
710 710 l\r (no-eol) (esc)
711 711 \x0cI\xd4\xa9\xc5\x01|\xf0pC\xf5NX\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x95 \xee\xa7\x81\xbc\xca\x16\xc1\xe1Z\xcc\x0b\xa1C5\xa0\xe8\xe5\xba\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02E (esc)
712 712 \x00\x00\x00\x00\x00\x00\x00\x05H\x00\x00\x00b\x85\x00\x18\x9et\xa9\xe0G^\x82 \x93\xbc}\xb0\xd61\xae\xb0\xb4\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02\xdeB\x19n\xbe\xe4.\xf2\x84\xb6x (esc)
713 713 \x87\xcd\xc9n\x8e\xaa\xb6\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02H (esc)
714 714 \x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 (no-eol) (esc)
715 715
716 716 $ hg unbundle2 < ../rev.hg2
717 717 adding changesets
718 718 adding manifests
719 719 adding file changes
720 720 added 0 changesets with 0 changes to 3 files
721 721 0 unread bytes
722 722 addchangegroup return: 1
723 723
724 724 with reply
725 725
726 726 $ hg bundle2 --rev '8+7+5+4' --reply ../rev-rr.hg2
727 727 $ hg unbundle2 ../rev-reply.hg2 < ../rev-rr.hg2
728 728 0 unread bytes
729 729 addchangegroup return: 1
730 730
731 731 $ cat ../rev-reply.hg2
732 732 HG2X\x00\x00\x003\x15b2x:reply:changegroup\x00\x00\x00\x00\x00\x02\x0b\x01\x06\x01in-reply-to1return1\x00\x00\x00\x00\x00\x1f (esc)
733 733 b2x:output\x00\x00\x00\x01\x00\x01\x0b\x01in-reply-to1\x00\x00\x00dadding changesets (esc)
734 734 adding manifests
735 735 adding file changes
736 736 added 0 changesets with 0 changes to 3 files
737 737 \x00\x00\x00\x00\x00\x00 (no-eol) (esc)
738 738
739 739 Real world exchange
740 740 =====================
741 741
742 742
743 743 clone --pull
744 744
745 745 $ cd ..
746 746 $ hg clone main other --pull --rev 9520eea781bc
747 747 adding changesets
748 748 adding manifests
749 749 adding file changes
750 750 added 2 changesets with 2 changes to 2 files
751 751 updating to branch default
752 752 2 files updated, 0 files merged, 0 files removed, 0 files unresolved
753 753 $ hg -R other log -G
754 754 @ changeset: 1:9520eea781bc
755 755 | tag: tip
756 756 | user: Nicolas Dumazet <nicdumz.commits@gmail.com>
757 757 | date: Sat Apr 30 15:24:48 2011 +0200
758 758 | summary: E
759 759 |
760 760 o changeset: 0:cd010b8cd998
761 761 user: Nicolas Dumazet <nicdumz.commits@gmail.com>
762 762 date: Sat Apr 30 15:24:48 2011 +0200
763 763 summary: A
764 764
765 765
766 766 pull
767 767
768 768 $ hg -R other pull -r 24b6387c8c8c
769 769 pulling from $TESTTMP/main (glob)
770 770 searching for changes
771 771 adding changesets
772 772 adding manifests
773 773 adding file changes
774 774 added 1 changesets with 1 changes to 1 files (+1 heads)
775 775 (run 'hg heads' to see heads, 'hg merge' to merge)
776 776
777 777 push
778 778
779 779 $ hg -R main push other --rev eea13746799a
780 780 pushing to other
781 781 searching for changes
782 782 remote: adding changesets
783 783 remote: adding manifests
784 784 remote: adding file changes
785 785 remote: added 1 changesets with 0 changes to 0 files (-1 heads)
786 786
787 787 pull over ssh
788 788
789 789 $ hg -R other pull ssh://user@dummy/main -r 02de42196ebe --traceback
790 790 pulling from ssh://user@dummy/main
791 791 searching for changes
792 792 adding changesets
793 793 adding manifests
794 794 adding file changes
795 795 added 1 changesets with 1 changes to 1 files (+1 heads)
796 796 (run 'hg heads' to see heads, 'hg merge' to merge)
797 797
798 798 pull over http
799 799
800 800 $ hg -R main serve -p $HGPORT -d --pid-file=main.pid -E main-error.log
801 801 $ cat main.pid >> $DAEMON_PIDS
802 802
803 803 $ hg -R other pull http://localhost:$HGPORT/ -r 42ccdea3bb16
804 804 pulling from http://localhost:$HGPORT/
805 805 searching for changes
806 806 adding changesets
807 807 adding manifests
808 808 adding file changes
809 809 added 1 changesets with 1 changes to 1 files (+1 heads)
810 810 (run 'hg heads .' to see heads, 'hg merge' to merge)
811 811 $ cat main-error.log
812 812
813 813 push over ssh
814 814
815 815 $ hg -R main push ssh://user@dummy/other -r 5fddd98957c8
816 816 pushing to ssh://user@dummy/other
817 817 searching for changes
818 818 remote: adding changesets
819 819 remote: adding manifests
820 820 remote: adding file changes
821 821 remote: added 1 changesets with 1 changes to 1 files
822 822
823 823 push over http
824 824
825 825 $ hg -R other serve -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
826 826 $ cat other.pid >> $DAEMON_PIDS
827 827
828 828 $ hg -R main push http://localhost:$HGPORT2/ -r 32af7686d403
829 829 pushing to http://localhost:$HGPORT2/
830 830 searching for changes
831 831 remote: adding changesets
832 832 remote: adding manifests
833 833 remote: adding file changes
834 834 remote: added 1 changesets with 1 changes to 1 files
835 835 $ cat other-error.log
836 836
837 837 Check final content.
838 838
839 839 $ hg -R other log -G
840 840 o changeset: 7:32af7686d403
841 841 | tag: tip
842 842 | user: Nicolas Dumazet <nicdumz.commits@gmail.com>
843 843 | date: Sat Apr 30 15:24:48 2011 +0200
844 844 | summary: D
845 845 |
846 846 o changeset: 6:5fddd98957c8
847 847 | user: Nicolas Dumazet <nicdumz.commits@gmail.com>
848 848 | date: Sat Apr 30 15:24:48 2011 +0200
849 849 | summary: C
850 850 |
851 851 o changeset: 5:42ccdea3bb16
852 852 | parent: 0:cd010b8cd998
853 853 | user: Nicolas Dumazet <nicdumz.commits@gmail.com>
854 854 | date: Sat Apr 30 15:24:48 2011 +0200
855 855 | summary: B
856 856 |
857 857 | o changeset: 4:02de42196ebe
858 858 | | parent: 2:24b6387c8c8c
859 859 | | user: Nicolas Dumazet <nicdumz.commits@gmail.com>
860 860 | | date: Sat Apr 30 15:24:48 2011 +0200
861 861 | | summary: H
862 862 | |
863 863 | | o changeset: 3:eea13746799a
864 864 | |/| parent: 2:24b6387c8c8c
865 865 | | | parent: 1:9520eea781bc
866 866 | | | user: Nicolas Dumazet <nicdumz.commits@gmail.com>
867 867 | | | date: Sat Apr 30 15:24:48 2011 +0200
868 868 | | | summary: G
869 869 | | |
870 870 | o | changeset: 2:24b6387c8c8c
871 871 |/ / parent: 0:cd010b8cd998
872 872 | | user: Nicolas Dumazet <nicdumz.commits@gmail.com>
873 873 | | date: Sat Apr 30 15:24:48 2011 +0200
874 874 | | summary: F
875 875 | |
876 876 | @ changeset: 1:9520eea781bc
877 877 |/ user: Nicolas Dumazet <nicdumz.commits@gmail.com>
878 878 | date: Sat Apr 30 15:24:48 2011 +0200
879 879 | summary: E
880 880 |
881 881 o changeset: 0:cd010b8cd998
882 882 user: Nicolas Dumazet <nicdumz.commits@gmail.com>
883 883 date: Sat Apr 30 15:24:48 2011 +0200
884 884 summary: A
885 885
886 886
887 887 Error Handling
888 888 ==============
889 889
890 890 Check that errors are properly returned to the client during push.
891 891
892 892 Setting up
893 893
894 894 $ cat > failpush.py << EOF
895 895 > """A small extension that makes push fails when using bundle2
896 896 >
897 897 > used to test error handling in bundle2
898 898 > """
899 899 >
900 900 > from mercurial import util
901 901 > from mercurial import bundle2
902 902 > from mercurial import exchange
903 903 > from mercurial import extensions
904 904 >
905 905 > def _pushbundle2failpart(orig, pushop, bundler):
906 906 > extradata = orig(pushop, bundler)
907 > part = bundle2.bundlepart('test:abort')
908 > bundler.addpart(part)
907 > reason = pushop.ui.config('failpush', 'reason', None)
908 > part = None
909 > if reason == 'abort':
910 > part = bundle2.bundlepart('test:abort')
911 > if part is not None:
912 > bundler.addpart(part)
909 913 > return extradata
910 914 >
911 915 > @bundle2.parthandler("test:abort")
912 916 > def handleabort(op, part):
913 917 > raise util.Abort('Abandon ship!', hint="don't panic")
914 918 >
915 919 > def uisetup(ui):
916 920 > extensions.wrapfunction(exchange, '_pushbundle2extraparts', _pushbundle2failpart)
917 921 >
918 922 > EOF
919 923
920 924 $ cd main
921 925 $ hg up tip
922 926 3 files updated, 0 files merged, 1 files removed, 0 files unresolved
923 927 $ echo 'I' > I
924 928 $ hg add I
925 929 $ hg ci -m 'I'
926 930 $ hg id
927 931 e7ec4e813ba6 tip
928 932 $ cd ..
929 933
930 934 $ cat << EOF >> $HGRCPATH
931 935 > [extensions]
932 936 > failpush=$TESTTMP/failpush.py
933 937 > EOF
934 938
935 939 $ "$TESTDIR/killdaemons.py" $DAEMON_PIDS
936 940 $ hg -R other serve -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
937 941 $ cat other.pid >> $DAEMON_PIDS
938 942
939 943 Doing the actual push: Abort error
940 944
945 $ cat << EOF >> $HGRCPATH
946 > [failpush]
947 > reason = abort
948 > EOF
949
941 950 $ hg -R main push other -r e7ec4e813ba6
942 951 pushing to other
943 952 searching for changes
944 953 abort: Abandon ship!
945 954 (don't panic)
946 955 [255]
947 956
948 957 $ hg -R main push ssh://user@dummy/other -r e7ec4e813ba6
949 958 pushing to ssh://user@dummy/other
950 959 searching for changes
951 960 abort: Abandon ship!
952 961 (don't panic)
953 962 [255]
954 963
955 964 $ hg -R main push http://localhost:$HGPORT2/ -r e7ec4e813ba6
956 965 pushing to http://localhost:$HGPORT2/
957 966 searching for changes
958 967 abort: Abandon ship!
959 968 (don't panic)
960 969 [255]
961 970
962 971
General Comments 0
You need to be logged in to leave comments. Login now