Mercurial > public > mercurial-scm > hg-stable
comparison 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 |
comparison
equal
deleted
inserted
replaced
1980:dfb796786337 | 1981:736b6c96bbbc |
---|---|
11 """ | 11 """ |
12 | 12 |
13 from node import * | 13 from node import * |
14 from i18n import gettext as _ | 14 from i18n import gettext as _ |
15 from demandload import demandload | 15 from demandload import demandload |
16 demandload(globals(), "util os struct") | 16 demandload(globals(), "changegroup util os struct") |
17 | 17 |
18 import localrepo, changelog, manifest, filelog, revlog | 18 import localrepo, changelog, manifest, filelog, revlog |
19 | |
20 def getchunk(source): | |
21 """get a chunk from a group""" | |
22 d = source.read(4) | |
23 if not d: | |
24 return "" | |
25 l = struct.unpack(">l", d)[0] | |
26 if l <= 4: | |
27 return "" | |
28 d = source.read(l - 4) | |
29 if len(d) < l - 4: | |
30 raise util.Abort(_("premature EOF reading chunk" | |
31 " (got %d bytes, expected %d)") | |
32 % (len(d), l - 4)) | |
33 return d | |
34 | 19 |
35 class bundlerevlog(revlog.revlog): | 20 class bundlerevlog(revlog.revlog): |
36 def __init__(self, opener, indexfile, datafile, bundlefile, | 21 def __init__(self, opener, indexfile, datafile, bundlefile, |
37 linkmapper=None): | 22 linkmapper=None): |
38 # How it works: | 23 # How it works: |
44 # len(index[r]). If the tuple is bigger than 7, it is a bundle | 29 # len(index[r]). If the tuple is bigger than 7, it is a bundle |
45 # (it is bigger since we store the node to which the delta is) | 30 # (it is bigger since we store the node to which the delta is) |
46 # | 31 # |
47 revlog.revlog.__init__(self, opener, indexfile, datafile) | 32 revlog.revlog.__init__(self, opener, indexfile, datafile) |
48 self.bundlefile = bundlefile | 33 self.bundlefile = bundlefile |
49 def genchunk(): | 34 def chunkpositer(): |
50 while 1: | 35 for chunk in changegroup.chunkiter(bundlefile): |
51 pos = bundlefile.tell() | 36 pos = bundlefile.tell() |
52 chunk = getchunk(bundlefile) | 37 yield chunk, pos - len(chunk) |
53 if not chunk: | |
54 break | |
55 yield chunk, pos + 4 # XXX struct.calcsize(">l") == 4 | |
56 n = self.count() | 38 n = self.count() |
57 prev = None | 39 prev = None |
58 for chunk, start in genchunk(): | 40 for chunk, start in chunkpositer(): |
59 size = len(chunk) | 41 size = len(chunk) |
60 if size < 80: | 42 if size < 80: |
61 raise util.Abort("invalid changegroup") | 43 raise util.Abort("invalid changegroup") |
62 start += 80 | 44 start += 80 |
63 size -= 80 | 45 size -= 80 |
192 self.manifest = bundlemanifest(self.opener, self.bundlefile, | 174 self.manifest = bundlemanifest(self.opener, self.bundlefile, |
193 self.changelog.rev) | 175 self.changelog.rev) |
194 # dict with the mapping 'filename' -> position in the bundle | 176 # dict with the mapping 'filename' -> position in the bundle |
195 self.bundlefilespos = {} | 177 self.bundlefilespos = {} |
196 while 1: | 178 while 1: |
197 f = getchunk(self.bundlefile) | 179 f = changegroup.getchunk(self.bundlefile) |
198 if not f: | 180 if not f: |
199 break | 181 break |
200 self.bundlefilespos[f] = self.bundlefile.tell() | 182 self.bundlefilespos[f] = self.bundlefile.tell() |
201 while getchunk(self.bundlefile): | 183 for c in changegroup.chunkiter(self.bundlefile): |
202 pass | 184 pass |
203 | 185 |
204 def dev(self): | 186 def dev(self): |
205 return -1 | 187 return -1 |
206 | 188 |
207 def file(self, f): | 189 def file(self, f): |