Mercurial > public > mercurial-scm > hg
comparison mercurial/bundlerepo.py @ 14142:cb91ea6af733
bundlerepo: port to new bundle API
author | Benoit Boissinot <benoit.boissinot@ens-lyon.org> |
---|---|
date | Sat, 30 Apr 2011 10:41:06 +0200 |
parents | 924c82157d46 |
children | 3c3c53d8343a |
comparison
equal
deleted
inserted
replaced
14141:bd1cbfe5db5c | 14142:cb91ea6af733 |
---|---|
16 import os, struct, tempfile, shutil | 16 import os, struct, tempfile, shutil |
17 import changegroup, util, mdiff, discovery | 17 import changegroup, util, mdiff, discovery |
18 import localrepo, changelog, manifest, filelog, revlog, error | 18 import localrepo, changelog, manifest, filelog, revlog, error |
19 | 19 |
20 class bundlerevlog(revlog.revlog): | 20 class bundlerevlog(revlog.revlog): |
21 def __init__(self, opener, indexfile, bundle, | 21 def __init__(self, opener, indexfile, bundle, linkmapper): |
22 linkmapper=None): | |
23 # How it works: | 22 # How it works: |
24 # to retrieve a revision, we need to know the offset of | 23 # to retrieve a revision, we need to know the offset of |
25 # the revision in the bundle (an unbundle object). | 24 # the revision in the bundle (an unbundle object). |
26 # | 25 # |
27 # We store this offset in the index (start), to differentiate a | 26 # We store this offset in the index (start), to differentiate a |
30 # (it is bigger since we store the node to which the delta is) | 29 # (it is bigger since we store the node to which the delta is) |
31 # | 30 # |
32 revlog.revlog.__init__(self, opener, indexfile) | 31 revlog.revlog.__init__(self, opener, indexfile) |
33 self.bundle = bundle | 32 self.bundle = bundle |
34 self.basemap = {} | 33 self.basemap = {} |
35 def chunkpositer(): | |
36 while 1: | |
37 chunk = bundle.chunk() | |
38 if not chunk: | |
39 break | |
40 pos = bundle.tell() | |
41 yield chunk, pos - len(chunk) | |
42 n = len(self) | 34 n = len(self) |
43 prev = None | 35 chain = None |
44 for chunk, start in chunkpositer(): | 36 while 1: |
45 size = len(chunk) | 37 chunkdata = bundle.parsechunk(chain) |
46 if size < 80: | 38 if not chunkdata: |
47 raise util.Abort(_("invalid changegroup")) | 39 break |
48 start += 80 | 40 node = chunkdata['node'] |
49 size -= 80 | 41 p1 = chunkdata['p1'] |
50 node, p1, p2, cs = struct.unpack("20s20s20s20s", chunk[:80]) | 42 p2 = chunkdata['p2'] |
43 cs = chunkdata['cs'] | |
44 deltabase = chunkdata['deltabase'] | |
45 delta = chunkdata['delta'] | |
46 | |
47 size = len(delta) | |
48 start = bundle.tell() - size | |
49 | |
50 link = linkmapper(cs) | |
51 if node in self.nodemap: | 51 if node in self.nodemap: |
52 prev = node | 52 # this can happen if two branches make the same change |
53 chain = node | |
53 continue | 54 continue |
55 | |
54 for p in (p1, p2): | 56 for p in (p1, p2): |
55 if not p in self.nodemap: | 57 if not p in self.nodemap: |
56 raise error.LookupError(p, self.indexfile, | 58 raise error.LookupError(p, self.indexfile, |
57 _("unknown parent")) | 59 _("unknown parent")) |
58 if linkmapper is None: | |
59 link = n | |
60 else: | |
61 link = linkmapper(cs) | |
62 | |
63 if not prev: | |
64 prev = p1 | |
65 # start, size, full unc. size, base (unused), link, p1, p2, node | 60 # start, size, full unc. size, base (unused), link, p1, p2, node |
66 e = (revlog.offset_type(start, 0), size, -1, -1, link, | 61 e = (revlog.offset_type(start, 0), size, -1, -1, link, |
67 self.rev(p1), self.rev(p2), node) | 62 self.rev(p1), self.rev(p2), node) |
68 self.basemap[n] = prev | 63 self.basemap[n] = deltabase |
69 self.index.insert(-1, e) | 64 self.index.insert(-1, e) |
70 self.nodemap[node] = n | 65 self.nodemap[node] = n |
71 prev = node | 66 chain = node |
72 n += 1 | 67 n += 1 |
73 | 68 |
74 def inbundle(self, rev): | 69 def inbundle(self, rev): |
75 """is rev from the bundle""" | 70 """is rev from the bundle""" |
76 if rev < 0: | 71 if rev < 0: |
142 raise NotImplementedError | 137 raise NotImplementedError |
143 | 138 |
144 class bundlechangelog(bundlerevlog, changelog.changelog): | 139 class bundlechangelog(bundlerevlog, changelog.changelog): |
145 def __init__(self, opener, bundle): | 140 def __init__(self, opener, bundle): |
146 changelog.changelog.__init__(self, opener) | 141 changelog.changelog.__init__(self, opener) |
147 bundlerevlog.__init__(self, opener, self.indexfile, bundle) | 142 linkmapper = lambda x: x |
143 bundlerevlog.__init__(self, opener, self.indexfile, bundle, | |
144 linkmapper) | |
148 | 145 |
149 class bundlemanifest(bundlerevlog, manifest.manifest): | 146 class bundlemanifest(bundlerevlog, manifest.manifest): |
150 def __init__(self, opener, bundle, linkmapper): | 147 def __init__(self, opener, bundle, linkmapper): |
151 manifest.manifest.__init__(self, opener) | 148 manifest.manifest.__init__(self, opener) |
152 bundlerevlog.__init__(self, opener, self.indexfile, bundle, | 149 bundlerevlog.__init__(self, opener, self.indexfile, bundle, |