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