94
94
If there is a tree, the tree is opened and break_lock() called.
95
95
Otherwise, branch is tried, and finally repository.
97
# XXX: This seems more like a UI function than something that really
98
# belongs in this class.
98
100
thing_to_unlock = self.open_workingtree()
99
101
except (errors.NotLocalUrl, errors.NoWorkingTree):
416
if ((found_bzrdir.root_transport.base ==
418
if ((found_bzrdir.root_transport.base ==
417
419
self.root_transport.base) or repository.is_shared()):
418
420
return repository
420
422
raise errors.NoRepositoryPresent(self)
421
423
raise errors.NoRepositoryPresent(self)
425
def get_branch_reference(self):
426
"""Return the referenced URL for the branch in this bzrdir.
428
:raises NotBranchError: If there is no Branch.
429
:return: The URL the branch in this bzrdir references if it is a
430
reference branch, or None for regular branches.
423
434
def get_branch_transport(self, branch_format):
424
435
"""Get the transport for use by branch format in this BzrDir.
517
528
return BzrDir.open_from_transport(t, _unsupported=_unsupported)
520
def open_from_transport(transport, _unsupported=False):
531
def open_from_transport(transport, _unsupported=False,
532
_server_formats=True):
521
533
"""Open a bzrdir within a particular directory.
523
535
:param transport: Transport containing the bzrdir.
526
538
base = transport.base
528
540
def find_format(transport):
529
return transport, BzrDirFormat.find_format(transport)
541
return transport, BzrDirFormat.find_format(
542
transport, _server_formats=_server_formats)
531
544
def redirected(transport, e, redirection_notice):
532
545
qualified_source = e.get_source_url()
598
611
return result, urlutils.unescape(a_transport.relpath(url))
599
612
except errors.NotBranchError, e:
601
new_t = a_transport.clone('..')
615
new_t = a_transport.clone('..')
616
except errors.InvalidURLJoin:
617
# reached the root, whatever that may be
618
raise errors.NotBranchError(path=url)
602
619
if new_t.base == a_transport.base:
603
620
# reached the root, whatever that may be
604
621
raise errors.NotBranchError(path=url)
637
654
raise NotImplementedError(self.open_repository)
639
def open_workingtree(self, _unsupported=False):
656
def open_workingtree(self, _unsupported=False,
657
recommend_upgrade=True):
640
658
"""Open the workingtree object at this BzrDir if one is present.
642
TODO: static convenience version of this?
660
:param recommend_upgrade: Optional keyword parameter, when True (the
661
default), emit through the ui module a recommendation that the user
662
upgrade the working tree when the workingtree being opened is old
663
(but still fully supported).
644
665
raise NotImplementedError(self.open_workingtree)
681
703
except errors.NotBranchError:
682
704
source_branch = None
683
705
source_repository = self.open_repository()
684
result_format.repository_format = source_repository._format
685
706
except errors.NoRepositoryPresent:
686
707
source_repository = None
709
# XXX TODO: This isinstance is here because we have not implemented
710
# the fix recommended in bug # 103195 - to delegate this choice the
712
repo_format = source_repository._format
713
if not isinstance(repo_format, remote.RemoteRepositoryFormat):
714
result_format.repository_format = repo_format
688
716
# TODO: Couldn't we just probe for the format in these cases,
689
717
# rather than opening the whole tree? It would be a little
754
782
result.create_repository()
755
783
elif source_repository is not None and result_repo is None:
756
784
# have source, and want to make a new target repo
757
# we don't clone the repo because that preserves attributes
758
# like is_shared(), and we have not yet implemented a
759
# repository sprout().
760
result_repo = result.create_repository()
761
if result_repo is not None:
785
result_repo = source_repository.sprout(result, revision_id=revision_id)
762
787
# fetch needed content into target.
763
788
if source_repository is not None:
790
# source_repository.copy_content_into(result_repo, revision_id=revision_id)
791
# so we can override the copy method
764
792
result_repo.fetch(source_repository, revision_id=revision_id)
765
793
if source_branch is not None:
766
794
source_branch.sprout(result, revision_id=revision_id)
1044
1072
def destroy_workingtree_metadata(self):
1045
1073
self.transport.delete_tree('checkout')
1075
def find_branch_format(self):
1076
"""Find the branch 'format' for this bzrdir.
1078
This might be a synthetic object for e.g. RemoteBranch and SVN.
1080
from bzrlib.branch import BranchFormat
1081
return BranchFormat.find_format(self)
1047
1083
def _get_mkdir_mode(self):
1048
1084
"""Figure out the mode to use when creating a bzrdir subdir."""
1049
1085
temp_control = lockable_files.LockableFiles(self.transport, '',
1050
1086
lockable_files.TransportLock)
1051
1087
return temp_control._dir_mode
1089
def get_branch_reference(self):
1090
"""See BzrDir.get_branch_reference()."""
1091
from bzrlib.branch import BranchFormat
1092
format = BranchFormat.find_format(self)
1093
return format.get_reference(self)
1053
1095
def get_branch_transport(self, branch_format):
1054
1096
"""See BzrDir.get_branch_transport()."""
1055
1097
if branch_format is None:
1127
1169
def open_branch(self, unsupported=False):
1128
1170
"""See BzrDir.open_branch."""
1129
from bzrlib.branch import BranchFormat
1130
format = BranchFormat.find_format(self)
1171
format = self.find_branch_format()
1131
1172
self._check_supported(format, unsupported)
1132
1173
return format.open(self, _found=True)
1178
1219
This is a list of BzrDirFormat objects.
1222
_control_server_formats = []
1223
"""The registered control server formats, e.g. RemoteBzrDirs.
1225
This is a list of BzrDirFormat objects.
1181
1228
_lock_file_name = 'branch-lock'
1183
1230
# _lock_class must be set in subclasses to the lock type, typ.
1184
1231
# TransportLock or LockDir
1187
def find_format(klass, transport):
1234
def find_format(klass, transport, _server_formats=True):
1188
1235
"""Return the format present at transport."""
1189
for format in klass._control_formats:
1237
formats = klass._control_server_formats + klass._control_formats
1239
formats = klass._control_formats
1240
for format in formats:
1191
1242
return format.probe_transport(transport)
1192
1243
except errors.NotBranchError:
1342
1393
klass._control_formats.append(format)
1396
def register_control_server_format(klass, format):
1397
"""Register a control format for client-server environments.
1399
These formats will be tried before ones registered with
1400
register_control_format. This gives implementations that decide to the
1401
chance to grab it before anything looks at the contents of the format
1404
klass._control_server_formats.append(format)
1345
1407
@symbol_versioning.deprecated_method(symbol_versioning.zero_fourteen)
1346
1408
def set_default_format(klass, format):
1347
1409
klass._set_default_format(format)
1641
1703
easy to identify.
1644
def __init__(self, transport_server, transport_readonly_server, formats):
1706
def __init__(self, vfs_factory, transport_server, transport_readonly_server,
1708
"""Create an object to adapt tests.
1710
:param vfs_server: A factory to create a Transport Server which has
1711
all the VFS methods working, and is writable.
1713
self._vfs_factory = vfs_factory
1645
1714
self._transport_server = transport_server
1646
1715
self._transport_readonly_server = transport_readonly_server
1647
1716
self._formats = formats
1650
1719
result = unittest.TestSuite()
1651
1720
for format in self._formats:
1652
1721
new_test = deepcopy(test)
1722
new_test.vfs_transport_factory = self._vfs_factory
1653
1723
new_test.transport_server = self._transport_server
1654
1724
new_test.transport_readonly_server = self._transport_readonly_server
1655
1725
new_test.bzrdir_format = format
2149
2219
return to_convert
2222
# This is not in remote.py because it's small, and needs to be registered.
2223
# Putting it in remote.py creates a circular import problem.
2224
# we can make it a lazy object if the control formats is turned into something
2226
class RemoteBzrDirFormat(BzrDirMetaFormat1):
2227
"""Format representing bzrdirs accessed via a smart server"""
2229
def get_format_description(self):
2230
return 'bzr remote bzrdir'
2233
def probe_transport(klass, transport):
2234
"""Return a RemoteBzrDirFormat object if it looks possible."""
2236
client = transport.get_smart_client()
2237
except (NotImplementedError, AttributeError,
2238
errors.TransportNotPossible):
2239
# no smart server, so not a branch for this format type.
2240
raise errors.NotBranchError(path=transport.base)
2242
# Send a 'hello' request in protocol version one, and decline to
2243
# open it if the server doesn't support our required version (2) so
2244
# that the VFS-based transport will do it.
2245
request = client.get_request()
2246
smart_protocol = protocol.SmartClientRequestProtocolOne(request)
2247
server_version = smart_protocol.query_version()
2248
if server_version != 2:
2249
raise errors.NotBranchError(path=transport.base)
2252
def initialize_on_transport(self, transport):
2254
# hand off the request to the smart server
2255
medium = transport.get_smart_medium()
2256
except errors.NoSmartMedium:
2257
# TODO: lookup the local format from a server hint.
2258
local_dir_format = BzrDirMetaFormat1()
2259
return local_dir_format.initialize_on_transport(transport)
2260
client = _SmartClient(medium)
2261
path = client.remote_path_from_transport(transport)
2262
response = _SmartClient(medium).call('BzrDirFormat.initialize', path)
2263
assert response[0] in ('ok', ), 'unexpected response code %s' % (response,)
2264
return remote.RemoteBzrDir(transport)
2266
def _open(self, transport):
2267
return remote.RemoteBzrDir(transport)
2269
def __eq__(self, other):
2270
if not isinstance(other, RemoteBzrDirFormat):
2272
return self.get_format_description() == other.get_format_description()
2275
BzrDirFormat.register_control_server_format(RemoteBzrDirFormat)
2152
2278
class BzrDirFormatInfo(object):
2154
2280
def __init__(self, native, deprecated, hidden):