changeset 21075:438803e4bd97

bundle2: support for push over the wire We use the new method defined in the past changeset to send a bundle2 stream and receive one in reply. The http version is missing remote output support. This will be done later using a bundle part.
author Pierre-Yves David <pierre-yves.david@fb.com>
date Tue, 15 Apr 2014 11:53:10 -0400
parents f8a0d82b0463
children 5236c7a72a2d
files mercurial/wireproto.py tests/test-bundle2.t
diffstat 2 files changed, 98 insertions(+), 13 deletions(-) [+]
line wrap: on
line diff
--- a/mercurial/wireproto.py	Tue Apr 15 17:53:52 2014 -0400
+++ b/mercurial/wireproto.py	Tue Apr 15 11:53:10 2014 -0400
@@ -343,8 +343,12 @@
     def unbundle(self, cg, heads, source):
         '''Send cg (a readable file-like object representing the
         changegroup to push, typically a chunkbuffer object) to the
-        remote server as a bundle. Return an integer indicating the
-        result of the push (see localrepository.addchangegroup()).'''
+        remote server as a bundle.
+
+        When pushing a bundle10 stream, return an integer indicating the
+        result of the push (see localrepository.addchangegroup()).
+
+        When pushing a bundle20 stream, return a bundle20 stream.'''
 
         if heads != ['force'] and self.capable('unbundlehash'):
             heads = encodelist(['hashed',
@@ -352,18 +356,24 @@
         else:
             heads = encodelist(heads)
 
-        ret, output = self._callpush("unbundle", cg, heads=heads)
-        if ret == "":
-            raise error.ResponseError(
-                _('push failed:'), output)
-        try:
-            ret = int(ret)
-        except ValueError:
-            raise error.ResponseError(
-                _('push failed (unexpected response):'), ret)
+        if util.safehasattr(cg, 'deltaheader'):
+            # this a bundle10, do the old style call sequence
+            ret, output = self._callpush("unbundle", cg, heads=heads)
+            if ret == "":
+                raise error.ResponseError(
+                    _('push failed:'), output)
+            try:
+                ret = int(ret)
+            except ValueError:
+                raise error.ResponseError(
+                    _('push failed (unexpected response):'), ret)
 
-        for l in output.splitlines(True):
-            self.ui.status(_('remote: '), l)
+            for l in output.splitlines(True):
+                self.ui.status(_('remote: '), l)
+        else:
+            # bundle2 push. Send a stream, fetch a stream.
+            stream = self._calltwowaystream('unbundle', cg, heads=heads)
+            ret = bundle2.unbundle20(self.ui, stream)
         return ret
 
     def debugwireargs(self, one, two, three=None, four=None, five=None):
@@ -781,6 +791,10 @@
             gen = exchange.readbundle(repo.ui, fp, None)
             r = exchange.unbundle(repo, gen, their_heads, 'serve',
                                   proto._client())
+            if util.safehasattr(r, 'addpart'):
+                # The return looks streameable, we are in the bundle2 case and
+                # should return a stream.
+                return streamres(r.getchunks())
             return pushres(r)
 
         finally:
--- a/tests/test-bundle2.t	Tue Apr 15 17:53:52 2014 -0400
+++ b/tests/test-bundle2.t	Tue Apr 15 11:53:10 2014 -0400
@@ -158,6 +158,9 @@
   > bundle2=True
   > [ui]
   > ssh=python "$TESTDIR/dummyssh"
+  > [web]
+  > push_ssl = false
+  > allow_push = *
   > EOF
 
 The extension requires a repo (currently unused)
@@ -711,4 +714,72 @@
   (run 'hg heads .' to see heads, 'hg merge' to merge)
   $ cat main-error.log
 
+push over ssh
 
+  $ hg -R main push ssh://user@dummy/other -r 5fddd98957c8
+  pushing to ssh://user@dummy/other
+  searching for changes
+  remote: adding changesets
+  remote: adding manifests
+  remote: adding file changes
+  remote: added 1 changesets with 1 changes to 1 files
+
+push over http
+
+  $ hg -R other serve -p $HGPORT2 -d --pid-file=other.pid -E other-error.log
+  $ cat other.pid >> $DAEMON_PIDS
+
+  $ hg -R main push http://localhost:$HGPORT2/ -r 32af7686d403
+  pushing to http://localhost:$HGPORT2/
+  searching for changes
+  $ cat other-error.log
+
+Check final content.
+
+  $ hg -R other log -G
+  o  changeset:   7:32af7686d403
+  |  tag:         tip
+  |  user:        Nicolas Dumazet <nicdumz.commits@gmail.com>
+  |  date:        Sat Apr 30 15:24:48 2011 +0200
+  |  summary:     D
+  |
+  o  changeset:   6:5fddd98957c8
+  |  user:        Nicolas Dumazet <nicdumz.commits@gmail.com>
+  |  date:        Sat Apr 30 15:24:48 2011 +0200
+  |  summary:     C
+  |
+  o  changeset:   5:42ccdea3bb16
+  |  parent:      0:cd010b8cd998
+  |  user:        Nicolas Dumazet <nicdumz.commits@gmail.com>
+  |  date:        Sat Apr 30 15:24:48 2011 +0200
+  |  summary:     B
+  |
+  | o  changeset:   4:02de42196ebe
+  | |  parent:      2:24b6387c8c8c
+  | |  user:        Nicolas Dumazet <nicdumz.commits@gmail.com>
+  | |  date:        Sat Apr 30 15:24:48 2011 +0200
+  | |  summary:     H
+  | |
+  | | o  changeset:   3:eea13746799a
+  | |/|  parent:      2:24b6387c8c8c
+  | | |  parent:      1:9520eea781bc
+  | | |  user:        Nicolas Dumazet <nicdumz.commits@gmail.com>
+  | | |  date:        Sat Apr 30 15:24:48 2011 +0200
+  | | |  summary:     G
+  | | |
+  | o |  changeset:   2:24b6387c8c8c
+  |/ /   parent:      0:cd010b8cd998
+  | |    user:        Nicolas Dumazet <nicdumz.commits@gmail.com>
+  | |    date:        Sat Apr 30 15:24:48 2011 +0200
+  | |    summary:     F
+  | |
+  | @  changeset:   1:9520eea781bc
+  |/   user:        Nicolas Dumazet <nicdumz.commits@gmail.com>
+  |    date:        Sat Apr 30 15:24:48 2011 +0200
+  |    summary:     E
+  |
+  o  changeset:   0:cd010b8cd998
+     user:        Nicolas Dumazet <nicdumz.commits@gmail.com>
+     date:        Sat Apr 30 15:24:48 2011 +0200
+     summary:     A
+