##// END OF EJS Templates
bundlerepo: use bundle objects everywhere
Matt Mackall -
r12332:680fe77a default
parent child Browse files
Show More
@@ -18,11 +18,11 b' import changegroup, util, mdiff'
18 18 import localrepo, changelog, manifest, filelog, revlog, error
19 19
20 20 class bundlerevlog(revlog.revlog):
21 def __init__(self, opener, indexfile, bundlefile,
21 def __init__(self, opener, indexfile, bundle,
22 22 linkmapper=None):
23 23 # How it works:
24 24 # to retrieve a revision, we need to know the offset of
25 # the revision in the bundlefile (an opened file).
25 # the revision in the bundle (an unbundle object).
26 26 #
27 27 # We store this offset in the index (start), to differentiate a
28 28 # rev in the bundle and from a rev in the revlog, we check
@@ -30,11 +30,11 b' class bundlerevlog(revlog.revlog):'
30 30 # (it is bigger since we store the node to which the delta is)
31 31 #
32 32 revlog.revlog.__init__(self, opener, indexfile)
33 self.bundlefile = bundlefile
33 self.bundle = bundle
34 34 self.basemap = {}
35 35 def chunkpositer():
36 for chunk in changegroup.chunkiter(bundlefile):
37 pos = bundlefile.tell()
36 for chunk in changegroup.chunkiter(bundle):
37 pos = bundle.tell()
38 38 yield chunk, pos - len(chunk)
39 39 n = len(self)
40 40 prev = None
@@ -68,7 +68,7 b' class bundlerevlog(revlog.revlog):'
68 68 prev = node
69 69 n += 1
70 70
71 def bundle(self, rev):
71 def inbundle(self, rev):
72 72 """is rev from the bundle"""
73 73 if rev < 0:
74 74 return False
@@ -79,19 +79,19 b' class bundlerevlog(revlog.revlog):'
79 79 # Warning: in case of bundle, the diff is against bundlebase,
80 80 # not against rev - 1
81 81 # XXX: could use some caching
82 if not self.bundle(rev):
82 if not self.inbundle(rev):
83 83 return revlog.revlog._chunk(self, rev)
84 self.bundlefile.seek(self.start(rev))
85 return self.bundlefile.read(self.length(rev))
84 self.bundle.seek(self.start(rev))
85 return self.bundle.read(self.length(rev))
86 86
87 87 def revdiff(self, rev1, rev2):
88 88 """return or calculate a delta between two revisions"""
89 if self.bundle(rev1) and self.bundle(rev2):
89 if self.inbundle(rev1) and self.inbundle(rev2):
90 90 # hot path for bundle
91 91 revb = self.rev(self.bundlebase(rev2))
92 92 if revb == rev1:
93 93 return self._chunk(rev2)
94 elif not self.bundle(rev1) and not self.bundle(rev2):
94 elif not self.inbundle(rev1) and not self.inbundle(rev2):
95 95 return revlog.revlog.revdiff(self, rev1, rev2)
96 96
97 97 return mdiff.textdiff(self.revision(self.node(rev1)),
@@ -107,7 +107,7 b' class bundlerevlog(revlog.revlog):'
107 107 iter_node = node
108 108 rev = self.rev(iter_node)
109 109 # reconstruct the revision if it is from a changegroup
110 while self.bundle(rev):
110 while self.inbundle(rev):
111 111 if self._cache and self._cache[0] == iter_node:
112 112 text = self._cache[2]
113 113 break
@@ -139,20 +139,20 b' class bundlerevlog(revlog.revlog):'
139 139 raise NotImplementedError
140 140
141 141 class bundlechangelog(bundlerevlog, changelog.changelog):
142 def __init__(self, opener, bundlefile):
142 def __init__(self, opener, bundle):
143 143 changelog.changelog.__init__(self, opener)
144 bundlerevlog.__init__(self, opener, self.indexfile, bundlefile)
144 bundlerevlog.__init__(self, opener, self.indexfile, bundle)
145 145
146 146 class bundlemanifest(bundlerevlog, manifest.manifest):
147 def __init__(self, opener, bundlefile, linkmapper):
147 def __init__(self, opener, bundle, linkmapper):
148 148 manifest.manifest.__init__(self, opener)
149 bundlerevlog.__init__(self, opener, self.indexfile, bundlefile,
149 bundlerevlog.__init__(self, opener, self.indexfile, bundle,
150 150 linkmapper)
151 151
152 152 class bundlefilelog(bundlerevlog, filelog.filelog):
153 def __init__(self, opener, path, bundlefile, linkmapper):
153 def __init__(self, opener, path, bundle, linkmapper):
154 154 filelog.filelog.__init__(self, opener, path)
155 bundlerevlog.__init__(self, opener, self.indexfile, bundlefile,
155 bundlerevlog.__init__(self, opener, self.indexfile, bundle,
156 156 linkmapper)
157 157
158 158 class bundlerepository(localrepo.localrepository):
@@ -171,9 +171,9 b' class bundlerepository(localrepo.localre'
171 171 self._url = 'bundle:' + bundlename
172 172
173 173 self.tempfile = None
174 self.bundlefile = open(bundlename, "rb")
175 b = changegroup.readbundle(self.bundlefile, bundlename)
176 if b.compressed():
174 f = open(bundlename, "rb")
175 self.bundle = changegroup.readbundle(f, bundlename)
176 if self.bundle.compressed():
177 177 # we need a seekable, decompressed bundle
178 178 fdtemp, temp = tempfile.mkstemp(prefix="hg-bundle-",
179 179 suffix=".hg10un", dir=self.path)
@@ -183,31 +183,30 b' class bundlerepository(localrepo.localre'
183 183 try:
184 184 fptemp.write("HG10UN")
185 185 while 1:
186 chunk = b.read(2**18)
186 chunk = self.bundle.read(2**18)
187 187 if not chunk:
188 188 break
189 189 fptemp.write(chunk)
190 190 finally:
191 191 fptemp.close()
192 self.bundlefile.close()
193 192
194 self.bundlefile = open(self.tempfile, "rb")
195 self.bundlefile.seek(6)
193 f = open(self.tempfile, "rb")
194 self.bundle = changegroup.readbundle(f, bundlename)
196 195
197 196 # dict with the mapping 'filename' -> position in the bundle
198 197 self.bundlefilespos = {}
199 198
200 199 @util.propertycache
201 200 def changelog(self):
202 c = bundlechangelog(self.sopener, self.bundlefile)
203 self.manstart = self.bundlefile.tell()
201 c = bundlechangelog(self.sopener, self.bundle)
202 self.manstart = self.bundle.tell()
204 203 return c
205 204
206 205 @util.propertycache
207 206 def manifest(self):
208 self.bundlefile.seek(self.manstart)
209 m = bundlemanifest(self.sopener, self.bundlefile, self.changelog.rev)
210 self.filestart = self.bundlefile.tell()
207 self.bundle.seek(self.manstart)
208 m = bundlemanifest(self.sopener, self.bundle, self.changelog.rev)
209 self.filestart = self.bundle.tell()
211 210 return m
212 211
213 212 @util.propertycache
@@ -225,29 +224,26 b' class bundlerepository(localrepo.localre'
225 224
226 225 def file(self, f):
227 226 if not self.bundlefilespos:
228 self.bundlefile.seek(self.filestart)
227 self.bundle.seek(self.filestart)
229 228 while 1:
230 chunk = changegroup.getchunk(self.bundlefile)
229 chunk = changegroup.getchunk(self.bundle)
231 230 if not chunk:
232 231 break
233 self.bundlefilespos[chunk] = self.bundlefile.tell()
234 for c in changegroup.chunkiter(self.bundlefile):
232 self.bundlefilespos[chunk] = self.bundle.tell()
233 for c in changegroup.chunkiter(self.bundle):
235 234 pass
236 235
237 236 if f[0] == '/':
238 237 f = f[1:]
239 238 if f in self.bundlefilespos:
240 self.bundlefile.seek(self.bundlefilespos[f])
241 return bundlefilelog(self.sopener, f, self.bundlefile,
239 self.bundle.seek(self.bundlefilespos[f])
240 return bundlefilelog(self.sopener, f, self.bundle,
242 241 self.changelog.rev)
243 242 else:
244 243 return filelog.filelog(self.sopener, f)
245 244
246 245 def __del__(self):
247 bundlefile = getattr(self, 'bundlefile', None)
248 if bundlefile and not bundlefile.closed:
249 bundlefile.close()
250 tempfile = getattr(self, 'tempfile', None)
246 del self.bundle
251 247 if tempfile is not None:
252 248 os.unlink(tempfile)
253 249 if self._tempparent:
@@ -149,7 +149,7 b' class unbundle10(object):'
149 149 def seek(self, pos):
150 150 return self._stream.seek(pos)
151 151 def tell(self):
152 return self._stream.tell(pos)
152 return self._stream.tell()
153 153
154 154 class headerlessfixup(object):
155 155 def __init__(self, fh, h):
General Comments 0
You need to be logged in to leave comments. Login now