##// END OF EJS Templates
bundlerepo: drop bundlebase wrapper function for basemap
Mads Kiilerich -
r18413:0ccb16f5 default
parent child Browse files
Show More
@@ -1,388 +1,387 b''
1 # bundlerepo.py - repository class for viewing uncompressed bundles
1 # bundlerepo.py - repository class for viewing uncompressed bundles
2 #
2 #
3 # Copyright 2006, 2007 Benoit Boissinot <bboissin@gmail.com>
3 # Copyright 2006, 2007 Benoit Boissinot <bboissin@gmail.com>
4 #
4 #
5 # This software may be used and distributed according to the terms of the
5 # This software may be used and distributed according to the terms of the
6 # GNU General Public License version 2 or any later version.
6 # GNU General Public License version 2 or any later version.
7
7
8 """Repository class for viewing uncompressed bundles.
8 """Repository class for viewing uncompressed bundles.
9
9
10 This provides a read-only repository interface to bundles as if they
10 This provides a read-only repository interface to bundles as if they
11 were part of the actual repository.
11 were part of the actual repository.
12 """
12 """
13
13
14 from node import nullid
14 from node import nullid
15 from i18n import _
15 from i18n import _
16 import os, tempfile, shutil
16 import os, tempfile, shutil
17 import changegroup, util, mdiff, discovery, cmdutil, scmutil
17 import changegroup, util, mdiff, discovery, cmdutil, scmutil
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, linkmapper):
21 def __init__(self, opener, indexfile, bundle, linkmapper):
22 # How it works:
22 # How it works:
23 # To retrieve a revision, we need to know the offset of the revision in
23 # To retrieve a revision, we need to know the offset of the revision in
24 # the bundle (an unbundle object). We store this offset in the index
24 # the bundle (an unbundle object). We store this offset in the index
25 # (start).
25 # (start).
26 #
26 #
27 # basemap is indexed with revisions coming from the bundle, and it
27 # basemap is indexed with revisions coming from the bundle, and it
28 # maps to the node that is the base of the corresponding delta.
28 # maps to the node that is the base of the corresponding delta.
29 #
29 #
30 # To differentiate a rev in the bundle from a rev in the revlog, we
30 # To differentiate a rev in the bundle from a rev in the revlog, we
31 # check revision against basemap.
31 # check revision against basemap.
32 opener = scmutil.readonlyvfs(opener)
32 opener = scmutil.readonlyvfs(opener)
33 revlog.revlog.__init__(self, opener, indexfile)
33 revlog.revlog.__init__(self, opener, indexfile)
34 self.bundle = bundle
34 self.bundle = bundle
35 self.basemap = {}
35 self.basemap = {}
36 n = len(self)
36 n = len(self)
37 chain = None
37 chain = None
38 self.bundlerevs = set() # used by 'bundle()' revset expression
38 self.bundlerevs = set() # used by 'bundle()' revset expression
39 while True:
39 while True:
40 chunkdata = bundle.deltachunk(chain)
40 chunkdata = bundle.deltachunk(chain)
41 if not chunkdata:
41 if not chunkdata:
42 break
42 break
43 node = chunkdata['node']
43 node = chunkdata['node']
44 p1 = chunkdata['p1']
44 p1 = chunkdata['p1']
45 p2 = chunkdata['p2']
45 p2 = chunkdata['p2']
46 cs = chunkdata['cs']
46 cs = chunkdata['cs']
47 deltabase = chunkdata['deltabase']
47 deltabase = chunkdata['deltabase']
48 delta = chunkdata['delta']
48 delta = chunkdata['delta']
49
49
50 size = len(delta)
50 size = len(delta)
51 start = bundle.tell() - size
51 start = bundle.tell() - size
52
52
53 link = linkmapper(cs)
53 link = linkmapper(cs)
54 if node in self.nodemap:
54 if node in self.nodemap:
55 # this can happen if two branches make the same change
55 # this can happen if two branches make the same change
56 chain = node
56 chain = node
57 self.bundlerevs.add(self.nodemap[node])
57 self.bundlerevs.add(self.nodemap[node])
58 continue
58 continue
59
59
60 for p in (p1, p2):
60 for p in (p1, p2):
61 if p not in self.nodemap:
61 if p not in self.nodemap:
62 raise error.LookupError(p, self.indexfile,
62 raise error.LookupError(p, self.indexfile,
63 _("unknown parent"))
63 _("unknown parent"))
64 # start, size, full unc. size, base (unused), link, p1, p2, node
64 # start, size, full unc. size, base (unused), link, p1, p2, node
65 e = (revlog.offset_type(start, 0), size, -1, -1, link,
65 e = (revlog.offset_type(start, 0), size, -1, -1, link,
66 self.rev(p1), self.rev(p2), node)
66 self.rev(p1), self.rev(p2), node)
67 self.basemap[n] = deltabase
67 self.basemap[n] = deltabase
68 self.index.insert(-1, e)
68 self.index.insert(-1, e)
69 self.nodemap[node] = n
69 self.nodemap[node] = n
70 self.bundlerevs.add(n)
70 self.bundlerevs.add(n)
71 chain = node
71 chain = node
72 n += 1
72 n += 1
73
73
74 def inbundle(self, rev):
74 def inbundle(self, rev):
75 """is rev from the bundle"""
75 """is rev from the bundle"""
76 if rev < 0:
76 if rev < 0:
77 return False
77 return False
78 return rev in self.basemap
78 return rev in self.basemap
79 def bundlebase(self, rev):
79
80 return self.basemap[rev]
81 def _chunk(self, rev):
80 def _chunk(self, rev):
82 # Warning: in case of bundle, the diff is against bundlebase,
81 # Warning: in case of bundle, the diff is against self.basemap,
83 # not against rev - 1
82 # not against rev - 1
84 # XXX: could use some caching
83 # XXX: could use some caching
85 if not self.inbundle(rev):
84 if not self.inbundle(rev):
86 return revlog.revlog._chunk(self, rev)
85 return revlog.revlog._chunk(self, rev)
87 self.bundle.seek(self.start(rev))
86 self.bundle.seek(self.start(rev))
88 return self.bundle.read(self.length(rev))
87 return self.bundle.read(self.length(rev))
89
88
90 def revdiff(self, rev1, rev2):
89 def revdiff(self, rev1, rev2):
91 """return or calculate a delta between two revisions"""
90 """return or calculate a delta between two revisions"""
92 if self.inbundle(rev1) and self.inbundle(rev2):
91 if self.inbundle(rev1) and self.inbundle(rev2):
93 # hot path for bundle
92 # hot path for bundle
94 revb = self.rev(self.bundlebase(rev2))
93 revb = self.rev(self.basemap[rev2])
95 if revb == rev1:
94 if revb == rev1:
96 return self._chunk(rev2)
95 return self._chunk(rev2)
97 elif not self.inbundle(rev1) and not self.inbundle(rev2):
96 elif not self.inbundle(rev1) and not self.inbundle(rev2):
98 return revlog.revlog.revdiff(self, rev1, rev2)
97 return revlog.revlog.revdiff(self, rev1, rev2)
99
98
100 return mdiff.textdiff(self.revision(self.node(rev1)),
99 return mdiff.textdiff(self.revision(self.node(rev1)),
101 self.revision(self.node(rev2)))
100 self.revision(self.node(rev2)))
102
101
103 def revision(self, nodeorrev):
102 def revision(self, nodeorrev):
104 """return an uncompressed revision of a given node or revision
103 """return an uncompressed revision of a given node or revision
105 number.
104 number.
106 """
105 """
107 if isinstance(nodeorrev, int):
106 if isinstance(nodeorrev, int):
108 rev = nodeorrev
107 rev = nodeorrev
109 node = self.node(rev)
108 node = self.node(rev)
110 else:
109 else:
111 node = nodeorrev
110 node = nodeorrev
112 rev = self.rev(node)
111 rev = self.rev(node)
113
112
114 if node == nullid:
113 if node == nullid:
115 return ""
114 return ""
116
115
117 text = None
116 text = None
118 chain = []
117 chain = []
119 iter_node = node
118 iter_node = node
120 # reconstruct the revision if it is from a changegroup
119 # reconstruct the revision if it is from a changegroup
121 while self.inbundle(rev):
120 while self.inbundle(rev):
122 if self._cache and self._cache[0] == iter_node:
121 if self._cache and self._cache[0] == iter_node:
123 text = self._cache[2]
122 text = self._cache[2]
124 break
123 break
125 chain.append(rev)
124 chain.append(rev)
126 iter_node = self.bundlebase(rev)
125 iter_node = self.basemap[rev]
127 rev = self.rev(iter_node)
126 rev = self.rev(iter_node)
128 if text is None:
127 if text is None:
129 text = revlog.revlog.revision(self, iter_node)
128 text = revlog.revlog.revision(self, iter_node)
130
129
131 while chain:
130 while chain:
132 delta = self._chunk(chain.pop())
131 delta = self._chunk(chain.pop())
133 text = mdiff.patches(text, [delta])
132 text = mdiff.patches(text, [delta])
134
133
135 p1, p2 = self.parents(node)
134 p1, p2 = self.parents(node)
136 if node != revlog.hash(text, p1, p2):
135 if node != revlog.hash(text, p1, p2):
137 raise error.RevlogError(_("integrity check failed on %s:%d")
136 raise error.RevlogError(_("integrity check failed on %s:%d")
138 % (self.datafile, self.rev(node)))
137 % (self.datafile, self.rev(node)))
139
138
140 self._cache = (node, self.rev(node), text)
139 self._cache = (node, self.rev(node), text)
141 return text
140 return text
142
141
143 def addrevision(self, text, transaction, link, p1=None, p2=None, d=None):
142 def addrevision(self, text, transaction, link, p1=None, p2=None, d=None):
144 raise NotImplementedError
143 raise NotImplementedError
145 def addgroup(self, revs, linkmapper, transaction):
144 def addgroup(self, revs, linkmapper, transaction):
146 raise NotImplementedError
145 raise NotImplementedError
147 def strip(self, rev, minlink):
146 def strip(self, rev, minlink):
148 raise NotImplementedError
147 raise NotImplementedError
149 def checksize(self):
148 def checksize(self):
150 raise NotImplementedError
149 raise NotImplementedError
151
150
152 class bundlechangelog(bundlerevlog, changelog.changelog):
151 class bundlechangelog(bundlerevlog, changelog.changelog):
153 def __init__(self, opener, bundle):
152 def __init__(self, opener, bundle):
154 changelog.changelog.__init__(self, opener)
153 changelog.changelog.__init__(self, opener)
155 linkmapper = lambda x: x
154 linkmapper = lambda x: x
156 bundlerevlog.__init__(self, opener, self.indexfile, bundle,
155 bundlerevlog.__init__(self, opener, self.indexfile, bundle,
157 linkmapper)
156 linkmapper)
158
157
159 class bundlemanifest(bundlerevlog, manifest.manifest):
158 class bundlemanifest(bundlerevlog, manifest.manifest):
160 def __init__(self, opener, bundle, linkmapper):
159 def __init__(self, opener, bundle, linkmapper):
161 manifest.manifest.__init__(self, opener)
160 manifest.manifest.__init__(self, opener)
162 bundlerevlog.__init__(self, opener, self.indexfile, bundle,
161 bundlerevlog.__init__(self, opener, self.indexfile, bundle,
163 linkmapper)
162 linkmapper)
164
163
165 class bundlefilelog(bundlerevlog, filelog.filelog):
164 class bundlefilelog(bundlerevlog, filelog.filelog):
166 def __init__(self, opener, path, bundle, linkmapper, repo):
165 def __init__(self, opener, path, bundle, linkmapper, repo):
167 filelog.filelog.__init__(self, opener, path)
166 filelog.filelog.__init__(self, opener, path)
168 bundlerevlog.__init__(self, opener, self.indexfile, bundle,
167 bundlerevlog.__init__(self, opener, self.indexfile, bundle,
169 linkmapper)
168 linkmapper)
170 self._repo = repo
169 self._repo = repo
171
170
172 def _file(self, f):
171 def _file(self, f):
173 self._repo.file(f)
172 self._repo.file(f)
174
173
175 class bundlepeer(localrepo.localpeer):
174 class bundlepeer(localrepo.localpeer):
176 def canpush(self):
175 def canpush(self):
177 return False
176 return False
178
177
179 class bundlerepository(localrepo.localrepository):
178 class bundlerepository(localrepo.localrepository):
180 def __init__(self, ui, path, bundlename):
179 def __init__(self, ui, path, bundlename):
181 self._tempparent = None
180 self._tempparent = None
182 try:
181 try:
183 localrepo.localrepository.__init__(self, ui, path)
182 localrepo.localrepository.__init__(self, ui, path)
184 except error.RepoError:
183 except error.RepoError:
185 self._tempparent = tempfile.mkdtemp()
184 self._tempparent = tempfile.mkdtemp()
186 localrepo.instance(ui, self._tempparent, 1)
185 localrepo.instance(ui, self._tempparent, 1)
187 localrepo.localrepository.__init__(self, ui, self._tempparent)
186 localrepo.localrepository.__init__(self, ui, self._tempparent)
188 self.ui.setconfig('phases', 'publish', False)
187 self.ui.setconfig('phases', 'publish', False)
189
188
190 if path:
189 if path:
191 self._url = 'bundle:' + util.expandpath(path) + '+' + bundlename
190 self._url = 'bundle:' + util.expandpath(path) + '+' + bundlename
192 else:
191 else:
193 self._url = 'bundle:' + bundlename
192 self._url = 'bundle:' + bundlename
194
193
195 self.tempfile = None
194 self.tempfile = None
196 f = util.posixfile(bundlename, "rb")
195 f = util.posixfile(bundlename, "rb")
197 self.bundle = changegroup.readbundle(f, bundlename)
196 self.bundle = changegroup.readbundle(f, bundlename)
198 if self.bundle.compressed():
197 if self.bundle.compressed():
199 fdtemp, temp = tempfile.mkstemp(prefix="hg-bundle-",
198 fdtemp, temp = tempfile.mkstemp(prefix="hg-bundle-",
200 suffix=".hg10un", dir=self.path)
199 suffix=".hg10un", dir=self.path)
201 self.tempfile = temp
200 self.tempfile = temp
202 fptemp = os.fdopen(fdtemp, 'wb')
201 fptemp = os.fdopen(fdtemp, 'wb')
203
202
204 try:
203 try:
205 fptemp.write("HG10UN")
204 fptemp.write("HG10UN")
206 while True:
205 while True:
207 chunk = self.bundle.read(2**18)
206 chunk = self.bundle.read(2**18)
208 if not chunk:
207 if not chunk:
209 break
208 break
210 fptemp.write(chunk)
209 fptemp.write(chunk)
211 finally:
210 finally:
212 fptemp.close()
211 fptemp.close()
213
212
214 f = util.posixfile(self.tempfile, "rb")
213 f = util.posixfile(self.tempfile, "rb")
215 self.bundle = changegroup.readbundle(f, bundlename)
214 self.bundle = changegroup.readbundle(f, bundlename)
216
215
217 # dict with the mapping 'filename' -> position in the bundle
216 # dict with the mapping 'filename' -> position in the bundle
218 self.bundlefilespos = {}
217 self.bundlefilespos = {}
219
218
220 @localrepo.unfilteredpropertycache
219 @localrepo.unfilteredpropertycache
221 def changelog(self):
220 def changelog(self):
222 # consume the header if it exists
221 # consume the header if it exists
223 self.bundle.changelogheader()
222 self.bundle.changelogheader()
224 c = bundlechangelog(self.sopener, self.bundle)
223 c = bundlechangelog(self.sopener, self.bundle)
225 self.manstart = self.bundle.tell()
224 self.manstart = self.bundle.tell()
226 return c
225 return c
227
226
228 @localrepo.unfilteredpropertycache
227 @localrepo.unfilteredpropertycache
229 def manifest(self):
228 def manifest(self):
230 self.bundle.seek(self.manstart)
229 self.bundle.seek(self.manstart)
231 # consume the header if it exists
230 # consume the header if it exists
232 self.bundle.manifestheader()
231 self.bundle.manifestheader()
233 m = bundlemanifest(self.sopener, self.bundle, self.changelog.rev)
232 m = bundlemanifest(self.sopener, self.bundle, self.changelog.rev)
234 self.filestart = self.bundle.tell()
233 self.filestart = self.bundle.tell()
235 return m
234 return m
236
235
237 @localrepo.unfilteredpropertycache
236 @localrepo.unfilteredpropertycache
238 def manstart(self):
237 def manstart(self):
239 self.changelog
238 self.changelog
240 return self.manstart
239 return self.manstart
241
240
242 @localrepo.unfilteredpropertycache
241 @localrepo.unfilteredpropertycache
243 def filestart(self):
242 def filestart(self):
244 self.manifest
243 self.manifest
245 return self.filestart
244 return self.filestart
246
245
247 def url(self):
246 def url(self):
248 return self._url
247 return self._url
249
248
250 def file(self, f):
249 def file(self, f):
251 if not self.bundlefilespos:
250 if not self.bundlefilespos:
252 self.bundle.seek(self.filestart)
251 self.bundle.seek(self.filestart)
253 while True:
252 while True:
254 chunkdata = self.bundle.filelogheader()
253 chunkdata = self.bundle.filelogheader()
255 if not chunkdata:
254 if not chunkdata:
256 break
255 break
257 fname = chunkdata['filename']
256 fname = chunkdata['filename']
258 self.bundlefilespos[fname] = self.bundle.tell()
257 self.bundlefilespos[fname] = self.bundle.tell()
259 while True:
258 while True:
260 c = self.bundle.deltachunk(None)
259 c = self.bundle.deltachunk(None)
261 if not c:
260 if not c:
262 break
261 break
263
262
264 if f[0] == '/':
263 if f[0] == '/':
265 f = f[1:]
264 f = f[1:]
266 if f in self.bundlefilespos:
265 if f in self.bundlefilespos:
267 self.bundle.seek(self.bundlefilespos[f])
266 self.bundle.seek(self.bundlefilespos[f])
268 return bundlefilelog(self.sopener, f, self.bundle,
267 return bundlefilelog(self.sopener, f, self.bundle,
269 self.changelog.rev, self)
268 self.changelog.rev, self)
270 else:
269 else:
271 return filelog.filelog(self.sopener, f)
270 return filelog.filelog(self.sopener, f)
272
271
273 def close(self):
272 def close(self):
274 """Close assigned bundle file immediately."""
273 """Close assigned bundle file immediately."""
275 self.bundle.close()
274 self.bundle.close()
276 if self.tempfile is not None:
275 if self.tempfile is not None:
277 os.unlink(self.tempfile)
276 os.unlink(self.tempfile)
278 if self._tempparent:
277 if self._tempparent:
279 shutil.rmtree(self._tempparent, True)
278 shutil.rmtree(self._tempparent, True)
280
279
281 def cancopy(self):
280 def cancopy(self):
282 return False
281 return False
283
282
284 def peer(self):
283 def peer(self):
285 return bundlepeer(self)
284 return bundlepeer(self)
286
285
287 def getcwd(self):
286 def getcwd(self):
288 return os.getcwd() # always outside the repo
287 return os.getcwd() # always outside the repo
289
288
290
289
291 def instance(ui, path, create):
290 def instance(ui, path, create):
292 if create:
291 if create:
293 raise util.Abort(_('cannot create new bundle repository'))
292 raise util.Abort(_('cannot create new bundle repository'))
294 parentpath = ui.config("bundle", "mainreporoot", "")
293 parentpath = ui.config("bundle", "mainreporoot", "")
295 if not parentpath:
294 if not parentpath:
296 # try to find the correct path to the working directory repo
295 # try to find the correct path to the working directory repo
297 parentpath = cmdutil.findrepo(os.getcwd())
296 parentpath = cmdutil.findrepo(os.getcwd())
298 if parentpath is None:
297 if parentpath is None:
299 parentpath = ''
298 parentpath = ''
300 if parentpath:
299 if parentpath:
301 # Try to make the full path relative so we get a nice, short URL.
300 # Try to make the full path relative so we get a nice, short URL.
302 # In particular, we don't want temp dir names in test outputs.
301 # In particular, we don't want temp dir names in test outputs.
303 cwd = os.getcwd()
302 cwd = os.getcwd()
304 if parentpath == cwd:
303 if parentpath == cwd:
305 parentpath = ''
304 parentpath = ''
306 else:
305 else:
307 cwd = os.path.join(cwd,'')
306 cwd = os.path.join(cwd,'')
308 if parentpath.startswith(cwd):
307 if parentpath.startswith(cwd):
309 parentpath = parentpath[len(cwd):]
308 parentpath = parentpath[len(cwd):]
310 u = util.url(path)
309 u = util.url(path)
311 path = u.localpath()
310 path = u.localpath()
312 if u.scheme == 'bundle':
311 if u.scheme == 'bundle':
313 s = path.split("+", 1)
312 s = path.split("+", 1)
314 if len(s) == 1:
313 if len(s) == 1:
315 repopath, bundlename = parentpath, s[0]
314 repopath, bundlename = parentpath, s[0]
316 else:
315 else:
317 repopath, bundlename = s
316 repopath, bundlename = s
318 else:
317 else:
319 repopath, bundlename = parentpath, path
318 repopath, bundlename = parentpath, path
320 return bundlerepository(ui, repopath, bundlename)
319 return bundlerepository(ui, repopath, bundlename)
321
320
322 def getremotechanges(ui, repo, other, onlyheads=None, bundlename=None,
321 def getremotechanges(ui, repo, other, onlyheads=None, bundlename=None,
323 force=False):
322 force=False):
324 '''obtains a bundle of changes incoming from other
323 '''obtains a bundle of changes incoming from other
325
324
326 "onlyheads" restricts the returned changes to those reachable from the
325 "onlyheads" restricts the returned changes to those reachable from the
327 specified heads.
326 specified heads.
328 "bundlename", if given, stores the bundle to this file path permanently;
327 "bundlename", if given, stores the bundle to this file path permanently;
329 otherwise it's stored to a temp file and gets deleted again when you call
328 otherwise it's stored to a temp file and gets deleted again when you call
330 the returned "cleanupfn".
329 the returned "cleanupfn".
331 "force" indicates whether to proceed on unrelated repos.
330 "force" indicates whether to proceed on unrelated repos.
332
331
333 Returns a tuple (local, csets, cleanupfn):
332 Returns a tuple (local, csets, cleanupfn):
334
333
335 "local" is a local repo from which to obtain the actual incoming
334 "local" is a local repo from which to obtain the actual incoming
336 changesets; it is a bundlerepo for the obtained bundle when the
335 changesets; it is a bundlerepo for the obtained bundle when the
337 original "other" is remote.
336 original "other" is remote.
338 "csets" lists the incoming changeset node ids.
337 "csets" lists the incoming changeset node ids.
339 "cleanupfn" must be called without arguments when you're done processing
338 "cleanupfn" must be called without arguments when you're done processing
340 the changes; it closes both the original "other" and the one returned
339 the changes; it closes both the original "other" and the one returned
341 here.
340 here.
342 '''
341 '''
343 tmp = discovery.findcommonincoming(repo, other, heads=onlyheads,
342 tmp = discovery.findcommonincoming(repo, other, heads=onlyheads,
344 force=force)
343 force=force)
345 common, incoming, rheads = tmp
344 common, incoming, rheads = tmp
346 if not incoming:
345 if not incoming:
347 try:
346 try:
348 if bundlename:
347 if bundlename:
349 os.unlink(bundlename)
348 os.unlink(bundlename)
350 except OSError:
349 except OSError:
351 pass
350 pass
352 return repo, [], other.close
351 return repo, [], other.close
353
352
354 bundle = None
353 bundle = None
355 bundlerepo = None
354 bundlerepo = None
356 localrepo = other.local()
355 localrepo = other.local()
357 if bundlename or not localrepo:
356 if bundlename or not localrepo:
358 # create a bundle (uncompressed if other repo is not local)
357 # create a bundle (uncompressed if other repo is not local)
359
358
360 if other.capable('getbundle'):
359 if other.capable('getbundle'):
361 cg = other.getbundle('incoming', common=common, heads=rheads)
360 cg = other.getbundle('incoming', common=common, heads=rheads)
362 elif onlyheads is None and not other.capable('changegroupsubset'):
361 elif onlyheads is None and not other.capable('changegroupsubset'):
363 # compat with older servers when pulling all remote heads
362 # compat with older servers when pulling all remote heads
364 cg = other.changegroup(incoming, "incoming")
363 cg = other.changegroup(incoming, "incoming")
365 rheads = None
364 rheads = None
366 else:
365 else:
367 cg = other.changegroupsubset(incoming, rheads, 'incoming')
366 cg = other.changegroupsubset(incoming, rheads, 'incoming')
368 bundletype = localrepo and "HG10BZ" or "HG10UN"
367 bundletype = localrepo and "HG10BZ" or "HG10UN"
369 fname = bundle = changegroup.writebundle(cg, bundlename, bundletype)
368 fname = bundle = changegroup.writebundle(cg, bundlename, bundletype)
370 # keep written bundle?
369 # keep written bundle?
371 if bundlename:
370 if bundlename:
372 bundle = None
371 bundle = None
373 if not localrepo:
372 if not localrepo:
374 # use the created uncompressed bundlerepo
373 # use the created uncompressed bundlerepo
375 localrepo = bundlerepo = bundlerepository(ui, repo.root, fname)
374 localrepo = bundlerepo = bundlerepository(ui, repo.root, fname)
376 # this repo contains local and other now, so filter out local again
375 # this repo contains local and other now, so filter out local again
377 common = repo.heads()
376 common = repo.heads()
378
377
379 csets = localrepo.changelog.findmissing(common, rheads)
378 csets = localrepo.changelog.findmissing(common, rheads)
380
379
381 def cleanup():
380 def cleanup():
382 if bundlerepo:
381 if bundlerepo:
383 bundlerepo.close()
382 bundlerepo.close()
384 if bundle:
383 if bundle:
385 os.unlink(bundle)
384 os.unlink(bundle)
386 other.close()
385 other.close()
387
386
388 return (localrepo, csets, cleanup)
387 return (localrepo, csets, cleanup)
General Comments 0
You need to be logged in to leave comments. Login now