Show More
@@ -307,6 +307,11 b' 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 | |
@@ -329,16 +334,22 b' def unshare(ui, repo):' | |||||
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() | |
341 |
|
348 | |||
|
349 | localrepo.poisonrepository(repo) | |||
|
350 | ||||
|
351 | return newrepo | |||
|
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 |
@@ -2503,3 +2503,28 b' def createrepository(ui, path, createopt' | |||||
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) |
General Comments 0
You need to be logged in to leave comments.
Login now