[PATCH 1 of 5] bundle2: very first version of a bundle2 bundler

pierre-yves.david at ens-lyon.org pierre-yves.david at ens-lyon.org
Wed Mar 19 17:02:02 CDT 2014


# HG changeset patch
# User Pierre-Yves David <pierre-yves.david at fb.com>
# Date 1395176450 25200
#      Tue Mar 18 14:00:50 2014 -0700
# Node ID f77651bc816e79ae36b17641f13194edb92e5dcf
# Parent  29b159bd71bc68e9868c5d2d748ab166dc7a5287
bundle2: very first version of a bundle2 bundler

This changeset is the very first of a long series. It create a new bundle2
module and add a simple class that generate and empty bundle2 container.

The module is documented with the current state of the implementation. For
information about the final goal you may want to consult the mercurial wiki
page:

    http://mercurial.selenic.com/wiki/BundleFormat2

The documentation of the module will be updated with later patches adding more and
more feature to the format.

This patches also introduce a test case. This test case build and use its own
small extension that use the new bundle2 module. Since the new format is unable
to do anything right now, we could not use real mercurial code to test it.
Moreover, some advanced feature of the bundle2 spec will not be used by core
mercurial at all. So we need to have them tested.

diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py
new file mode 100644
--- /dev/null
+++ b/mercurial/bundle2.py
@@ -0,0 +1,84 @@
+# bundle2.py - generic container format to transmit arbitrary data.
+#
+# Copyright 2013 Facebook, Inc.
+#
+# This software may be used and distributed according to the terms of the
+# GNU General Public License version 2 or any later version.
+"""Handling of the new bundle2 format
+
+The goal of bundle2 is to act as an atomically packet to transmit a set of
+payloads in an application agnostic way. It consist in a sequence of "parts"
+that will be handed to and processed by the application layer.
+
+
+General format architecture
+===========================
+
+The format is architectured as follow
+
+ - magic string
+ - stream level parameters
+ - payload parts (any number)
+ - end of stream marker.
+
+The current implementation is limited to empty bundle.
+
+Details on the Binary format
+============================
+
+All numbers are unsigned and big endian.
+
+stream level parameters
+------------------------
+
+Binary format is as follow
+
+:params size: (16 bits integer)
+
+  The total number of Bytes used by the parameters
+
+  Currently force to 0.
+
+:params value: arbitrary number of Bytes
+
+  A blob of `params size` containing the serialized version of all stream level
+  parameters.
+
+  Currently always empty.
+
+
+Payload part
+------------------------
+
+Binary format is as follow
+
+:header size: (16 bits inter)
+
+  The total number of Bytes used by the part headers. When the header is empty
+  (size = 0) this is interpreted as the end of stream marker.
+
+  Currently forced to 0 in the current state of the implementation
+"""
+
+_magicstring = 'HG20'
+
+class bundler(object):
+    """represent an outgoing bundle2 container
+
+    People will eventually by able to add param and parts to this object and
+    generated a stream from it."""
+
+    def __init__(self):
+        self._params = []
+        self._parts = []
+
+    def getchunks(self):
+        yield _magicstring
+        # no support for any param yet
+        # to be obviously fixed soon.
+        assert not self._params
+        yield '\0\0'
+        # no support for parts
+        # to be obviously fixed soon.
+        assert not self._parts
+        yield '\0\0'
diff --git a/tests/test-bundle2.t b/tests/test-bundle2.t
new file mode 100644
--- /dev/null
+++ b/tests/test-bundle2.t
@@ -0,0 +1,36 @@
+
+Create an extension to test bundle2 API
+
+  $ cat > bundle2.py << EOF
+  > """A small extension to test bundle2 implementation
+  > 
+  > Current bundle2 implementation is far too limited to be used in any core
+  > code. We still need to be able to test it while it grow up.
+  > """
+  > 
+  > from mercurial import cmdutil
+  > from mercurial import bundle2
+  > cmdtable = {}
+  > command = cmdutil.command(cmdtable)
+  > 
+  > @command('bundle2', [], '')
+  > def cmdbundle2(ui, repo):
+  >     """write a bundle2 container on standard ouput"""
+  >     bundler = bundle2.bundler()
+  >     for chunk in bundler.getchunks():
+  >         ui.write(chunk)
+  > EOF
+  $ cat >> $HGRCPATH << EOF
+  > [extensions]
+  > bundle2=$TESTTMP/bundle2.py
+  > EOF
+
+The extension requires a repo (currently unused)
+
+  $ hg init main
+  $ cd main
+
+Test simple generation of empty bundle
+
+  $ hg bundle2
+  HG20\x00\x00\x00\x00 (no-eol) (esc)


More information about the Mercurial-devel mailing list