Mercurial > public > mercurial-scm > hg-stable
comparison mercurial/localrepo.py @ 39622: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 | 76b58f240821 |
children | 24870f1be088 |
comparison
equal
deleted
inserted
replaced
39621:23f2299e9e53 | 39622:c5e6c1ba1c79 |
---|---|
2501 hgvfs.append(b'00changelog.i', | 2501 hgvfs.append(b'00changelog.i', |
2502 b'\0\0\0\2 dummy changelog to prevent using the old repo ' | 2502 b'\0\0\0\2 dummy changelog to prevent using the old repo ' |
2503 b'layout') | 2503 b'layout') |
2504 | 2504 |
2505 scmutil.writerequires(hgvfs, requirements) | 2505 scmutil.writerequires(hgvfs, requirements) |
2506 | |
2507 def poisonrepository(repo): | |
2508 """Poison a repository instance so it can no longer be used.""" | |
2509 # Perform any cleanup on the instance. | |
2510 repo.close() | |
2511 | |
2512 # Our strategy is to replace the type of the object with one that | |
2513 # has all attribute lookups result in error. | |
2514 # | |
2515 # But we have to allow the close() method because some constructors | |
2516 # of repos call close() on repo references. | |
2517 class poisonedrepository(object): | |
2518 def __getattribute__(self, item): | |
2519 if item == r'close': | |
2520 return object.__getattribute__(self, item) | |
2521 | |
2522 raise error.ProgrammingError('repo instances should not be used ' | |
2523 'after unshare') | |
2524 | |
2525 def close(self): | |
2526 pass | |
2527 | |
2528 # We may have a repoview, which intercepts __setattr__. So be sure | |
2529 # we operate at the lowest level possible. | |
2530 object.__setattr__(repo, r'__class__', poisonedrepository) |