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