[PATCH 3 of 3] bundlerepo: Add basic bundle2 support
Eric Sumner
ericsumner at fb.com
Thu Feb 5 13:10:31 CST 2015
# HG changeset patch
# User Eric Sumner <ericsumner at fb.com>
# Date 1421358976 28800
# Thu Jan 15 13:56:16 2015 -0800
# Node ID 881132ed1e3b99dbf24ba097a573b3dbac5bef03
# Parent cacd3119be7dd5681f6bf05a167115d0cba01236
bundlerepo: Add basic bundle2 support
This will use the highest-version changegroup part from the bundle2 file for
the bundlerepo. Over time, handlers can be added for additional parts, like
pushkeys.
diff --git a/mercurial/bundle2.py b/mercurial/bundle2.py
--- a/mercurial/bundle2.py
+++ b/mercurial/bundle2.py
@@ -497,7 +497,7 @@
"""read exactly <size> bytes from the stream"""
return changegroup.readexactly(self._fp, size)
- def seek(self, offset, whence):
+ def seek(self, offset, whence=0):
"""move the underlying file pointer"""
if self._seekable:
return self._fp.seek(offset, whence)
@@ -607,6 +607,9 @@
return self._readexact(headersize)
return None
+ def compressed(self):
+ return False
+
class bundlepart(object):
"""A bundle2 part contains application level payload
diff --git a/mercurial/bundlerepo.py b/mercurial/bundlerepo.py
--- a/mercurial/bundlerepo.py
+++ b/mercurial/bundlerepo.py
@@ -15,7 +15,7 @@
from i18n import _
import os, tempfile, shutil
import changegroup, util, mdiff, discovery, cmdutil, scmutil, exchange
-import localrepo, changelog, manifest, filelog, revlog, error, phases
+import localrepo, changelog, manifest, filelog, revlog, error, phases, bundle2
class bundlerevlog(revlog.revlog):
def __init__(self, opener, indexfile, bundle, linkmapper):
@@ -216,7 +216,7 @@
self.tempfile = None
f = util.posixfile(bundlename, "rb")
- self.bundle = exchange.readbundle(ui, f, bundlename)
+ self.bundlefile = self.bundle = exchange.readbundle(ui, f, bundlename)
if self.bundle.compressed():
fdtemp, temp = self.vfs.mkstemp(prefix="hg-bundle-",
suffix=".hg10un")
@@ -236,6 +236,23 @@
f = self.vfs.open(self.tempfile, mode="rb")
self.bundle = exchange.readbundle(ui, f, bundlename, self.vfs)
+ if isinstance(self.bundle, bundle2.unbundle20):
+ cgparts = [part for part in self.bundle.iterparts()
+ if (part.type == 'b2x:changegroup')
+ and (part.params.get('version', '01')
+ in changegroup.packermap)]
+
+ if not cgparts:
+ raise util.Abort('No changegroups found')
+ version = cgparts[0].params.get('version', '01')
+ cgparts = [p for p in cgparts
+ if p.params.get('version', '01') == version]
+ if len(cgparts) > 1:
+ raise NotImplementedError("Can't process multiple changegroups")
+ part = cgparts[0]
+
+ part.seek(0)
+ self.bundle = changegroup.packermap[version][1](part, 'UN')
# dict with the mapping 'filename' -> position in the bundle
self.bundlefilespos = {}
@@ -300,7 +317,7 @@
def close(self):
"""Close assigned bundle file immediately."""
- self.bundle.close()
+ self.bundlefile.close()
if self.tempfile is not None:
self.vfs.unlink(self.tempfile)
if self._tempparent:
diff --git a/mercurial/util.py b/mercurial/util.py
--- a/mercurial/util.py
+++ b/mercurial/util.py
@@ -1220,6 +1220,9 @@
return ''.join(buf)
+ def close(self):
+ pass
+
def filechunkiter(f, size=65536, limit=None):
"""Create a generator that produces the data in the file size
(default 65536) bytes at a time, up to optional limit (default is
diff --git a/tests/test-bundle2-format.t b/tests/test-bundle2-format.t
--- a/tests/test-bundle2-format.t
+++ b/tests/test-bundle2-format.t
@@ -206,6 +206,7 @@
$ cat >> $HGRCPATH << EOF
> [extensions]
> bundle2=$TESTTMP/bundle2.py
+ > strip=
> [experimental]
> bundle2-exp=True
> evolution=createmarkers
@@ -768,6 +769,47 @@
adding file changes
added 0 changesets with 0 changes to 3 files
+ $ hg strip --rev '8+7+5+4'
+ saved backup bundle to $TESTTMP/main/.hg/strip-backup/9520eea781bc-backup.hg (glob)
+ $ hg incoming ../rev.hg2 -G
+ comparing with ../rev.hg2
+ searching for changes
+ o 8:02de42196ebe draft Nicolas Dumazet <nicdumz.commits at gmail.com> H
+
+ o 7:eea13746799a draft Nicolas Dumazet <nicdumz.commits at gmail.com> G
+ |
+ o 6:9520eea781bc draft Nicolas Dumazet <nicdumz.commits at gmail.com> E
+
+ o 5:32af7686d403 draft Nicolas Dumazet <nicdumz.commits at gmail.com> D
+
+ $ hg pull ../rev.hg2
+ pulling from ../rev.hg2
+ searching for changes
+ adding changesets
+ adding manifests
+ adding file changes
+ added 4 changesets with 3 changes to 3 files (+1 heads)
+ (run 'hg heads .' to see heads, 'hg merge' to merge)
+ $ hg log -G
+ o 8:02de42196ebe draft Nicolas Dumazet <nicdumz.commits at gmail.com> H
+ |
+ | o 7:eea13746799a draft Nicolas Dumazet <nicdumz.commits at gmail.com> G
+ |/|
+ | o 6:9520eea781bc draft Nicolas Dumazet <nicdumz.commits at gmail.com> E
+ | |
+ | | o 5:32af7686d403 draft Nicolas Dumazet <nicdumz.commits at gmail.com> D
+ | | |
+ o | | 4:24b6387c8c8c draft Nicolas Dumazet <nicdumz.commits at gmail.com> F
+ |/ /
+ | o 3:5fddd98957c8 draft Nicolas Dumazet <nicdumz.commits at gmail.com> C
+ | |
+ | o 2:42ccdea3bb16 draft Nicolas Dumazet <nicdumz.commits at gmail.com> B
+ |/
+ o 1:cd010b8cd998 draft Nicolas Dumazet <nicdumz.commits at gmail.com> A
+
+ @ 0:3903775176ed draft test a
+
+
with reply
$ hg bundle2 --rev '8+7+5+4' --reply ../rev-rr.hg2
More information about the Mercurial-devel
mailing list