diff mercurial/bundlerepo.py @ 1981:736b6c96bbbc

make incoming work via ssh (issue139); move chunk code into separate module. Incoming ssh needs to detect the end of the changegroup, otherwise it would block trying to read from the ssh pipe. This is done by parsing the changegroup chunks. bundlerepo.getchunk() already is identical to localrepo.addchangegroup.getchunk(), which is followed by getgroup which looks much like what you can re-use in bundlerepository.__init__() and in write_bundle(). bundlerevlog.__init__.genchunk() looks very similar, too, as do some while loops in localrepo.py. Applied patch from Benoit Boissinot to move duplicate/related code to mercurial/changegroup.py and use this to fix incoming ssh.
author Thomas Arendsen Hein <thomas@intevation.de>
date Tue, 21 Mar 2006 11:47:21 +0100
parents dfb796786337
children 01ee43dda681
line wrap: on
line diff
--- a/mercurial/bundlerepo.py
+++ b/mercurial/bundlerepo.py
@@ -13,25 +13,10 @@ of the GNU General Public License, incor
 from node import *
 from i18n import gettext as _
 from demandload import demandload
-demandload(globals(), "util os struct")
+demandload(globals(), "changegroup util os struct")
 
 import localrepo, changelog, manifest, filelog, revlog
 
-def getchunk(source):
-    """get a chunk from a group"""
-    d = source.read(4)
-    if not d:
-        return ""
-    l = struct.unpack(">l", d)[0]
-    if l <= 4:
-        return ""
-    d = source.read(l - 4)
-    if len(d) < l - 4:
-        raise util.Abort(_("premature EOF reading chunk"
-                           " (got %d bytes, expected %d)")
-                          % (len(d), l - 4))
-    return d
-
 class bundlerevlog(revlog.revlog):
     def __init__(self, opener, indexfile, datafile, bundlefile,
                  linkmapper=None):
@@ -46,16 +31,13 @@ class bundlerevlog(revlog.revlog):
         #
         revlog.revlog.__init__(self, opener, indexfile, datafile)
         self.bundlefile = bundlefile
-        def genchunk():
-            while 1:
+        def chunkpositer():
+            for chunk in changegroup.chunkiter(bundlefile):
                 pos = bundlefile.tell()
-                chunk = getchunk(bundlefile)
-                if not chunk:
-                    break
-                yield chunk, pos + 4 # XXX struct.calcsize(">l") == 4
+                yield chunk, pos - len(chunk)
         n = self.count()
         prev = None
-        for chunk, start in genchunk():
+        for chunk, start in chunkpositer():
             size = len(chunk)
             if size < 80:
                 raise util.Abort("invalid changegroup")
@@ -194,12 +176,12 @@ class bundlerepository(localrepo.localre
         # dict with the mapping 'filename' -> position in the bundle
         self.bundlefilespos = {}
         while 1:
-                f = getchunk(self.bundlefile)
-                if not f:
-                    break
-                self.bundlefilespos[f] = self.bundlefile.tell()
-                while getchunk(self.bundlefile):
-                    pass
+            f = changegroup.getchunk(self.bundlefile)
+            if not f:
+                break
+            self.bundlefilespos[f] = self.bundlefile.tell()
+            for c in changegroup.chunkiter(self.bundlefile):
+                pass
 
     def dev(self):
         return -1