Show More
@@ -307,6 +307,11 b' def unshare(ui, repo):' | |||
|
307 | 307 | """convert a shared repository to a normal one |
|
308 | 308 | |
|
309 | 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 | 317 | destlock = lock = None |
@@ -329,16 +334,22 b' def unshare(ui, repo):' | |||
|
329 | 334 | destlock and destlock.release() |
|
330 | 335 | lock and lock.release() |
|
331 | 336 | |
|
332 | # update store, spath, svfs and sjoin of repo | |
|
333 | repo.unfiltered().__init__(repo.baseui, repo.root) | |
|
337 | # Removing share changes some fundamental properties of the repo instance. | |
|
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 | 342 | # TODO: figure out how to access subrepos that exist, but were previously |
|
336 | 343 | # removed from .hgsub |
|
337 | c = repo['.'] | |
|
344 | c = newrepo['.'] | |
|
338 | 345 | subs = c.substate |
|
339 | 346 | for s in sorted(subs): |
|
340 | 347 | c.sub(s).unshare() |
|
341 | 348 | |
|
349 | localrepo.poisonrepository(repo) | |
|
350 | ||
|
351 | return newrepo | |
|
352 | ||
|
342 | 353 | def postshare(sourcerepo, destrepo, bookmarks=True, defaultpath=None): |
|
343 | 354 | """Called after a new shared repo is created. |
|
344 | 355 |
@@ -2503,3 +2503,28 b' def createrepository(ui, path, createopt' | |||
|
2503 | 2503 | b'layout') |
|
2504 | 2504 | |
|
2505 | 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) |
General Comments 0
You need to be logged in to leave comments.
Login now