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,