Mercurial > public > mercurial-scm > hg
comparison mercurial/hg.py @ 39606:c5e6c1ba1c79
hg: don't reuse repo instance after unshare()
Unsharing a repository is a pretty invasive procedure and fundamentally
changes the behavior of the repository.
Currently, hg.unshare() calls into localrepository.__init__ to
re-initialize the repository instance. This is a bit hacky. And
future commits that refactor how localrepository instances are
constructed will make this difficult to support.
This commit changes unshare() so it constructs a new repo instance
once the unshare I/O has completed. It then poisons the old repo
instance so any further use will result in error.
Surprisingly, nothing in core appears to access a repo instance
after it has been unshared!
.. api::
``hg.unshare()`` now poisons the repo instance so it can't be used.
It also returns a new repo instance suitable for interacting with
the unshared repository.
Differential Revision: https://phab.mercurial-scm.org/D4557
author | Gregory Szorc <gregory.szorc@gmail.com> |
---|---|
date | Wed, 12 Sep 2018 19:00:46 -0700 |
parents | cb675e95a2c2 |
children | 4ece3cdfd907 |
comparison
equal
deleted
inserted
replaced
39605:23f2299e9e53 | 39606:c5e6c1ba1c79 |
---|---|
305 | 305 |
306 def unshare(ui, repo): | 306 def unshare(ui, repo): |
307 """convert a shared repository to a normal one | 307 """convert a shared repository to a normal one |
308 | 308 |
309 Copy the store data to the repo and remove the sharedpath data. | 309 Copy the store data to the repo and remove the sharedpath data. |
310 | |
311 Returns a new repository object representing the unshared repository. | |
312 | |
313 The passed repository object is not usable after this function is | |
314 called. | |
310 """ | 315 """ |
311 | 316 |
312 destlock = lock = None | 317 destlock = lock = None |
313 lock = repo.lock() | 318 lock = repo.lock() |
314 try: | 319 try: |
327 repo._writerequirements() | 332 repo._writerequirements() |
328 finally: | 333 finally: |
329 destlock and destlock.release() | 334 destlock and destlock.release() |
330 lock and lock.release() | 335 lock and lock.release() |
331 | 336 |
332 # update store, spath, svfs and sjoin of repo | 337 # Removing share changes some fundamental properties of the repo instance. |
333 repo.unfiltered().__init__(repo.baseui, repo.root) | 338 # So we instantiate a new repo object and operate on it rather than |
339 # try to keep the existing repo usable. | |
340 newrepo = repository(repo.baseui, repo.root, create=False) | |
334 | 341 |
335 # TODO: figure out how to access subrepos that exist, but were previously | 342 # TODO: figure out how to access subrepos that exist, but were previously |
336 # removed from .hgsub | 343 # removed from .hgsub |
337 c = repo['.'] | 344 c = newrepo['.'] |
338 subs = c.substate | 345 subs = c.substate |
339 for s in sorted(subs): | 346 for s in sorted(subs): |
340 c.sub(s).unshare() | 347 c.sub(s).unshare() |
348 | |
349 localrepo.poisonrepository(repo) | |
350 | |
351 return newrepo | |
341 | 352 |
342 def postshare(sourcerepo, destrepo, bookmarks=True, defaultpath=None): | 353 def postshare(sourcerepo, destrepo, bookmarks=True, defaultpath=None): |
343 """Called after a new shared repo is created. | 354 """Called after a new shared repo is created. |
344 | 355 |
345 The new repo only has a requirements file and pointer to the source. | 356 The new repo only has a requirements file and pointer to the source. |