##// END OF EJS Templates
hg: don't reuse repo instance after unshare()...
Gregory Szorc -
r39896:c5e6c1ba default
parent child Browse files
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