equal
deleted
inserted
replaced
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): |