##// END OF EJS Templates
bundlerepo: dynamically create repository type from base repository...
Gregory Szorc -
r39640:335ae4d0 default
parent child Browse files
Show More
@@ -255,7 +255,7 b' def _getfilestarts(cgunpacker):'
255 pass
255 pass
256 return filespos
256 return filespos
257
257
258 class bundlerepository(localrepo.localrepository):
258 class bundlerepository(object):
259 """A repository instance that is a union of a local repo and a bundle.
259 """A repository instance that is a union of a local repo and a bundle.
260
260
261 Instances represent a read-only repository composed of a local repository
261 Instances represent a read-only repository composed of a local repository
@@ -263,25 +263,19 b' class bundlerepository(localrepo.localre'
263 conceptually similar to the state of a repository after an
263 conceptually similar to the state of a repository after an
264 ``hg unbundle`` operation. However, the contents of the bundle are never
264 ``hg unbundle`` operation. However, the contents of the bundle are never
265 applied to the actual base repository.
265 applied to the actual base repository.
266
267 Instances constructed directly are not usable as repository objects.
268 Use instance() or makebundlerepository() to create instances.
266 """
269 """
267 def __init__(self, ui, repopath, bundlepath):
270 def __init__(self, bundlepath, url, tempparent):
268 self._tempparent = None
271 self._tempparent = tempparent
269 try:
272 self._url = url
270 localrepo.localrepository.__init__(self, ui, repopath)
273
271 except error.RepoError:
272 self._tempparent = pycompat.mkdtemp()
273 localrepo.instance(ui, self._tempparent, create=True)
274 localrepo.localrepository.__init__(self, ui, self._tempparent)
275 self.ui.setconfig('phases', 'publish', False, 'bundlerepo')
274 self.ui.setconfig('phases', 'publish', False, 'bundlerepo')
276
275
277 if repopath:
278 self._url = 'bundle:' + util.expandpath(repopath) + '+' + bundlepath
279 else:
280 self._url = 'bundle:' + bundlepath
281
282 self.tempfile = None
276 self.tempfile = None
283 f = util.posixfile(bundlepath, "rb")
277 f = util.posixfile(bundlepath, "rb")
284 bundle = exchange.readbundle(ui, f, bundlepath)
278 bundle = exchange.readbundle(self.ui, f, bundlepath)
285
279
286 if isinstance(bundle, bundle2.unbundle20):
280 if isinstance(bundle, bundle2.unbundle20):
287 self._bundlefile = bundle
281 self._bundlefile = bundle
@@ -311,7 +305,7 b' class bundlerepository(localrepo.localre'
311 if bundle.compressed():
305 if bundle.compressed():
312 f = self._writetempbundle(bundle.read, '.hg10un',
306 f = self._writetempbundle(bundle.read, '.hg10un',
313 header='HG10UN')
307 header='HG10UN')
314 bundle = exchange.readbundle(ui, f, bundlepath, self.vfs)
308 bundle = exchange.readbundle(self.ui, f, bundlepath, self.vfs)
315
309
316 self._bundlefile = bundle
310 self._bundlefile = bundle
317 self._cgunpacker = bundle
311 self._cgunpacker = bundle
@@ -484,7 +478,41 b' def instance(ui, path, create, intents=N'
484
478
485 def makebundlerepository(ui, repopath, bundlepath):
479 def makebundlerepository(ui, repopath, bundlepath):
486 """Make a bundle repository object based on repo and bundle paths."""
480 """Make a bundle repository object based on repo and bundle paths."""
487 return bundlerepository(ui, repopath, bundlepath)
481 if repopath:
482 url = 'bundle:%s+%s' % (util.expandpath(repopath), bundlepath)
483 else:
484 url = 'bundle:%s' % bundlepath
485
486 # Because we can't make any guarantees about the type of the base
487 # repository, we can't have a static class representing the bundle
488 # repository. We also can't make any guarantees about how to even
489 # call the base repository's constructor!
490 #
491 # So, our strategy is to go through ``localrepo.instance()`` to construct
492 # a repo instance. Then, we dynamically create a new type derived from
493 # both it and our ``bundlerepository`` class which overrides some
494 # functionality. We then change the type of the constructed repository
495 # to this new type and initialize the bundle-specific bits of it.
496
497 try:
498 parentrepo = localrepo.instance(ui, repopath, create=False)
499 tempparent = None
500 except error.RepoError:
501 tempparent = pycompat.mkdtemp()
502 try:
503 parentrepo = localrepo.instance(ui, tempparent, create=True)
504 except Exception:
505 shutil.rmtree(tempparent)
506 raise
507
508 class derivedbundlerepository(bundlerepository, parentrepo.__class__):
509 pass
510
511 repo = parentrepo
512 repo.__class__ = derivedbundlerepository
513 bundlerepository.__init__(repo, bundlepath, url, tempparent)
514
515 return repo
488
516
489 class bundletransactionmanager(object):
517 class bundletransactionmanager(object):
490 def transaction(self):
518 def transaction(self):
General Comments 0
You need to be logged in to leave comments. Login now