mercurial/bundlerepo.py
changeset 14142 cb91ea6af733
parent 14076 924c82157d46
child 14144 3c3c53d8343a
--- a/mercurial/bundlerepo.py	Sat Apr 30 10:00:41 2011 +0200
+++ b/mercurial/bundlerepo.py	Sat Apr 30 10:41:06 2011 +0200
@@ -18,8 +18,7 @@
 import localrepo, changelog, manifest, filelog, revlog, error
 
 class bundlerevlog(revlog.revlog):
-    def __init__(self, opener, indexfile, bundle,
-                 linkmapper=None):
+    def __init__(self, opener, indexfile, bundle, linkmapper):
         # How it works:
         # to retrieve a revision, we need to know the offset of
         # the revision in the bundle (an unbundle object).
@@ -32,43 +31,39 @@
         revlog.revlog.__init__(self, opener, indexfile)
         self.bundle = bundle
         self.basemap = {}
-        def chunkpositer():
-            while 1:
-                chunk = bundle.chunk()
-                if not chunk:
-                    break
-                pos = bundle.tell()
-                yield chunk, pos - len(chunk)
         n = len(self)
-        prev = None
-        for chunk, start in chunkpositer():
-            size = len(chunk)
-            if size < 80:
-                raise util.Abort(_("invalid changegroup"))
-            start += 80
-            size -= 80
-            node, p1, p2, cs = struct.unpack("20s20s20s20s", chunk[:80])
+        chain = None
+        while 1:
+            chunkdata = bundle.parsechunk(chain)
+            if not chunkdata:
+                break
+            node = chunkdata['node']
+            p1 = chunkdata['p1']
+            p2 = chunkdata['p2']
+            cs = chunkdata['cs']
+            deltabase = chunkdata['deltabase']
+            delta = chunkdata['delta']
+
+            size = len(delta)
+            start = bundle.tell() - size
+
+            link = linkmapper(cs)
             if node in self.nodemap:
-                prev = node
+                # this can happen if two branches make the same change
+                chain = node
                 continue
+
             for p in (p1, p2):
                 if not p in self.nodemap:
                     raise error.LookupError(p, self.indexfile,
                                             _("unknown parent"))
-            if linkmapper is None:
-                link = n
-            else:
-                link = linkmapper(cs)
-
-            if not prev:
-                prev = p1
             # start, size, full unc. size, base (unused), link, p1, p2, node
             e = (revlog.offset_type(start, 0), size, -1, -1, link,
                  self.rev(p1), self.rev(p2), node)
-            self.basemap[n] = prev
+            self.basemap[n] = deltabase
             self.index.insert(-1, e)
             self.nodemap[node] = n
-            prev = node
+            chain = node
             n += 1
 
     def inbundle(self, rev):
@@ -144,7 +139,9 @@
 class bundlechangelog(bundlerevlog, changelog.changelog):
     def __init__(self, opener, bundle):
         changelog.changelog.__init__(self, opener)
-        bundlerevlog.__init__(self, opener, self.indexfile, bundle)
+        linkmapper = lambda x: x
+        bundlerevlog.__init__(self, opener, self.indexfile, bundle,
+                              linkmapper)
 
 class bundlemanifest(bundlerevlog, manifest.manifest):
     def __init__(self, opener, bundle, linkmapper):