801
801
if len(old_repository._fallback_repositories) != 1:
802
802
raise AssertionError("can't cope with fallback repositories "
803
803
"of %r" % (self.repository,))
804
# unlock it, including unlocking the fallback
804
# Open the new repository object.
805
# Repositories don't offer an interface to remove fallback
806
# repositories today; take the conceptually simpler option and just
807
# reopen it. We reopen it starting from the URL so that we
808
# get a separate connection for RemoteRepositories and can
809
# stream from one of them to the other. This does mean doing
810
# separate SSH connection setup, but unstacking is not a
811
# common operation so it's tolerable.
812
new_bzrdir = bzrdir.BzrDir.open(self.bzrdir.root_transport.base)
813
new_repository = new_bzrdir.find_repository()
814
if new_repository._fallback_repositories:
815
raise AssertionError("didn't expect %r to have "
816
"fallback_repositories"
817
% (self.repository,))
818
# Replace self.repository with the new repository.
819
# Do our best to transfer the lock state (i.e. lock-tokens and
820
# lock count) of self.repository to the new repository.
821
lock_token = old_repository.lock_write().repository_token
822
self.repository = new_repository
823
if isinstance(self, remote.RemoteBranch):
824
# Remote branches can have a second reference to the old
825
# repository that need to be replaced.
826
if self._real_branch is not None:
827
self._real_branch.repository = new_repository
828
self.repository.lock_write(token=lock_token)
829
if lock_token is not None:
830
old_repository.leave_lock_in_place()
805
831
old_repository.unlock()
832
if lock_token is not None:
833
# XXX: self.repository.leave_lock_in_place() before this
834
# function will not be preserved. Fortunately that doesn't
835
# affect the current default format (2a), and would be a
836
# corner-case anyway.
837
# - Andrew Bennetts, 2010/06/30
838
self.repository.dont_leave_lock_in_place()
842
old_repository.unlock()
843
except errors.LockNotHeld:
846
if old_lock_count == 0:
847
raise AssertionError(
848
'old_repository should have been locked at least once.')
849
for i in range(old_lock_count-1):
850
self.repository.lock_write()
851
# Fetch from the old repository into the new.
806
852
old_repository.lock_read()
808
# Repositories don't offer an interface to remove fallback
809
# repositories today; take the conceptually simpler option and just
810
# reopen it. We reopen it starting from the URL so that we
811
# get a separate connection for RemoteRepositories and can
812
# stream from one of them to the other. This does mean doing
813
# separate SSH connection setup, but unstacking is not a
814
# common operation so it's tolerable.
815
new_bzrdir = bzrdir.BzrDir.open(self.bzrdir.root_transport.base)
816
new_repository = new_bzrdir.find_repository()
817
self.repository = new_repository
818
if self.repository._fallback_repositories:
819
raise AssertionError("didn't expect %r to have "
820
"fallback_repositories"
821
% (self.repository,))
822
# this is not paired with an unlock because it's just restoring
823
# the previous state; the lock's released when set_stacked_on_url
825
self.repository.lock_write()
826
854
# XXX: If you unstack a branch while it has a working tree
827
855
# with a pending merge, the pending-merged revisions will no
828
856
# longer be present. You can (probably) revert and remerge.