bundle2: introduce `replycaps` part for on-demand reply
The bundle2 processing does not create a bundle2 reply by default anymore. It
is only done if the client requests it with a `replycaps` part. This part is
called `replycaps` as it will eventually contain data about which bundle2
capabilities are supported by the client.
We have to add a flag to the test command to control whether a reply is
generated or not.
--- a/mercurial/bundle2.py Wed Apr 16 18:41:48 2014 -0400
+++ b/mercurial/bundle2.py Wed Apr 16 14:09:35 2014 -0400
@@ -280,9 +280,6 @@
"""
op = bundleoperation(repo, transactiongetter)
# todo:
- # - only create reply bundle if requested.
- op.reply = bundle20(op.ui)
- # todo:
# - replace this is a init function soon.
# - exception catching
unbundler.params
@@ -674,3 +671,11 @@
assert not h
if heads != op.repo.heads():
raise exchange.PushRaced()
+
+@parthandler('replycaps')
+def handlereplycaps(op, inpart):
+ """Notify that a reply bundle should be created
+
+ Will convey bundle capability at some point too."""
+ if op.reply is None:
+ op.reply = bundle20(op.ui)
--- a/mercurial/exchange.py Wed Apr 16 18:41:48 2014 -0400
+++ b/mercurial/exchange.py Wed Apr 16 14:09:35 2014 -0400
@@ -208,6 +208,7 @@
evolve in the future."""
# Send known head to the server for race detection.
bundler = bundle2.bundle20(pushop.ui)
+ bundler.addpart(bundle2.bundlepart('replycaps'))
if not pushop.force:
part = bundle2.bundlepart('CHECK:HEADS', data=iter(pushop.remoteheads))
bundler.addpart(part)
--- a/tests/test-bundle2.t Wed Apr 16 18:41:48 2014 -0400
+++ b/tests/test-bundle2.t Wed Apr 16 14:09:35 2014 -0400
@@ -45,6 +45,7 @@
> [('', 'param', [], 'stream level parameter'),
> ('', 'unknown', False, 'include an unknown mandatory part in the bundle'),
> ('', 'parts', False, 'include some arbitrary parts to the bundle'),
+ > ('', 'reply', False, 'produce a reply bundle'),
> ('r', 'rev', [], 'includes those changeset in the bundle'),],
> '[OUTPUTFILE]')
> def cmdbundle2(ui, repo, path=None, **opts):
@@ -57,6 +58,9 @@
> except ValueError, exc:
> raise util.Abort('%s' % exc)
>
+ > if opts['reply']:
+ > bundler.addpart(bundle2.bundlepart('replycaps'))
+ >
> revs = opts['rev']
> if 'rev' in opts:
> revs = scmutil.revrange(repo, opts['rev'])
@@ -493,19 +497,20 @@
unbundle with a reply
- $ hg unbundle2 ../reply.hg2 < ../parts.hg2
+ $ hg bundle2 --parts --reply ../parts-reply.hg2
+ $ hg unbundle2 ../reply.hg2 < ../parts-reply.hg2
The choir starts singing:
Patali Dirapata, Cromda Cromda Ripalo, Pata Pata, Ko Ko Ko
Bokoro Dipoulito, Rondi Rondi Pepino, Pata Pata, Ko Ko Ko
Emana Karassoli, Loucra Loucra Ponponto, Pata Pata, Ko Ko Ko.
- received ping request (id 4)
+ received ping request (id 5)
0 unread bytes
3 total verses sung
The reply is a bundle
$ cat ../reply.hg2
- HG20\x00\x00\x00\x1e test:pong\x00\x00\x00\x00\x01\x00\x0b\x01in-reply-to4\x00\x00\x00\x00\x00\x00 (no-eol) (esc)
+ HG20\x00\x00\x00\x1e test:pong\x00\x00\x00\x00\x01\x00\x0b\x01in-reply-to5\x00\x00\x00\x00\x00\x00 (no-eol) (esc)
The reply is valid
@@ -629,7 +634,7 @@
\x87\xcd\xc9n\x8e\xaa\xb6\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x02H (esc)
\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00 (no-eol) (esc)
- $ hg unbundle2 ../rev-replay.hg2 < ../rev.hg2
+ $ hg unbundle2 < ../rev.hg2
adding changesets
adding manifests
adding file changes
@@ -637,8 +642,19 @@
0 unread bytes
addchangegroup return: 1
- $ cat ../rev-replay.hg2
- HG20\x00\x00\x00/\x11reply:changegroup\x00\x00\x00\x00\x00\x02\x0b\x01\x06\x01in-reply-to0return1\x00\x00\x00\x00\x00\x00 (no-eol) (esc)
+with reply
+
+ $ hg bundle2 --rev '8+7+5+4' --reply ../rev-rr.hg2
+ $ hg unbundle2 ../rev-reply.hg2 < ../rev-rr.hg2
+ adding changesets
+ adding manifests
+ adding file changes
+ added 0 changesets with 0 changes to 3 files
+ 0 unread bytes
+ addchangegroup return: 1
+
+ $ cat ../rev-reply.hg2
+ HG20\x00\x00\x00/\x11reply:changegroup\x00\x00\x00\x00\x00\x02\x0b\x01\x06\x01in-reply-to1return1\x00\x00\x00\x00\x00\x00 (no-eol) (esc)
Real world exchange
=====================