70
70
except errors.ErrorFromSmartServer, err:
71
71
self._translate_error(err, **err_context)
74
def response_tuple_to_repo_format(response):
75
"""Convert a response tuple describing a repository format to a format."""
76
format = RemoteRepositoryFormat()
77
format.rich_root_data = (response[0] == 'yes')
78
format.supports_tree_reference = (response[1] == 'yes')
79
format.supports_external_lookups = (response[2] == 'yes')
80
format._network_name = response[3]
73
84
# Note: RemoteBzrDirFormat is in bzrdir.py
75
86
class RemoteBzrDir(BzrDir, _RpcHelper):
343
354
return self._vfs_initialize(a_bzrdir, shared)
345
356
# Turn the response into a RemoteRepository object.
346
format = RemoteRepositoryFormat()
347
format.rich_root_data = (response[1] == 'yes')
348
format.supports_tree_reference = (response[2] == 'yes')
349
format.supports_external_lookups = (response[3] == 'yes')
350
format._network_name = response[4]
357
format = response_tuple_to_repo_format(response[1:])
351
358
# Used to support creating a real format instance when needed.
352
359
format._creating_bzrdir = a_bzrdir
353
360
remote_repo = RemoteRepository(a_bzrdir, format)
384
391
def _serializer(self):
385
# We should only be getting asked for the serializer for
386
# RemoteRepositoryFormat objects when the RemoteRepositoryFormat object
387
# is a concrete instance for a RemoteRepository. In this case we know
388
# the creating_repo and can use it to supply the serializer.
389
self._creating_repo._ensure_real()
390
return self._creating_repo._real_repository._format._serializer
392
if self._custom_format is not None:
393
return self._custom_format._serializer
394
elif self._network_name is not None:
395
self._custom_format = repository.network_format_registry.get(
397
return self._custom_format._serializer
399
# We should only be getting asked for the serializer for
400
# RemoteRepositoryFormat objects when the RemoteRepositoryFormat object
401
# is a concrete instance for a RemoteRepository. In this case we know
402
# the creating_repo and can use it to supply the serializer.
403
self._creating_repo._ensure_real()
404
return self._creating_repo._real_repository._format._serializer
393
407
class RemoteRepository(_RpcHelper):
1464
1481
def get_format_description(self):
1465
1482
return 'Remote BZR Branch'
1467
def get_format_string(self):
1468
return 'Remote BZR Branch'
1484
def network_name(self):
1485
return self._network_name
1470
1487
def open(self, a_bzrdir):
1471
1488
return a_bzrdir.open_branch()
1490
def _vfs_initialize(self, a_bzrdir):
1491
# Initialisation when using a local bzrdir object, or a non-vfs init
1492
# method is not available on the server.
1493
# self._custom_format is always set - the start of initialize ensures
1495
if isinstance(a_bzrdir, RemoteBzrDir):
1496
a_bzrdir._ensure_real()
1497
result = self._custom_format.initialize(a_bzrdir._real_bzrdir)
1499
# We assume the bzrdir is parameterised; it may not be.
1500
result = self._custom_format.initialize(a_bzrdir)
1501
if (isinstance(a_bzrdir, RemoteBzrDir) and
1502
not isinstance(result, RemoteBranch)):
1503
result = RemoteBranch(a_bzrdir, a_bzrdir.find_repository(), result)
1473
1506
def initialize(self, a_bzrdir):
1474
# Delegate to a _real object here - the RemoteBzrDir format now
1475
# supports delegating to parameterised branch formats and as such
1476
# this RemoteBranchFormat method is only called when no specific format
1507
# 1) get the network name to use.
1508
if self._custom_format:
1509
network_name = self._custom_format.network_name()
1511
# Select the current bzrlib default and ask for that.
1512
reference_bzrdir_format = bzrdir.format_registry.get('default')()
1513
reference_format = reference_bzrdir_format.get_branch_format()
1514
self._custom_format = reference_format
1515
network_name = reference_format.network_name()
1516
# Being asked to create on a non RemoteBzrDir:
1478
1517
if not isinstance(a_bzrdir, RemoteBzrDir):
1479
result = a_bzrdir.create_branch()
1518
return self._vfs_initialize(a_bzrdir)
1519
medium = a_bzrdir._client._medium
1520
if medium._is_remote_before((1, 13)):
1521
return self._vfs_initialize(a_bzrdir)
1522
# Creating on a remote bzr dir.
1523
# 2) try direct creation via RPC
1524
path = a_bzrdir._path_for_remote_call(a_bzrdir._client)
1525
verb = 'BzrDir.create_branch'
1527
response = a_bzrdir._call(verb, path, network_name)
1528
except errors.UnknownSmartMethod:
1529
# Fallback - use vfs methods
1530
return self._vfs_initialize(a_bzrdir)
1531
if response[0] != 'ok':
1532
raise errors.UnexpectedSmartServerResponse(response)
1533
# Turn the response into a RemoteRepository object.
1534
format = RemoteBranchFormat()
1535
format._network_name = response[1]
1536
repo_format = response_tuple_to_repo_format(response[3:])
1537
if response[2] == '':
1538
repo_bzrdir = a_bzrdir
1481
a_bzrdir._ensure_real()
1482
result = a_bzrdir._real_bzrdir.create_branch()
1483
if not isinstance(result, RemoteBranch):
1484
result = RemoteBranch(a_bzrdir, a_bzrdir.find_repository(), result)
1540
repo_bzrdir = RemoteBzrDir(
1541
a_bzrdir.root_transport.clone(response[2]), a_bzrdir._format,
1543
remote_repo = RemoteRepository(repo_bzrdir, repo_format)
1544
remote_branch = RemoteBranch(a_bzrdir, remote_repo,
1545
format=format, setup_stacking=False)
1546
return remote_branch
1487
1548
def supports_tags(self):
1488
1549
# Remote branches might support tags, but we won't know until we
1499
1560
def __init__(self, remote_bzrdir, remote_repository, real_branch=None,
1561
_client=None, format=None, setup_stacking=True):
1501
1562
"""Create a RemoteBranch instance.
1503
1564
:param real_branch: An optional local implementation of the branch
1504
1565
format, usually accessing the data via the VFS.
1505
1566
:param _client: Private parameter for testing.
1567
:param format: A RemoteBranchFormat object, None to create one
1568
automatically. If supplied it should have a network_name already
1570
:param setup_stacking: If True make an RPC call to determine the
1571
stacked (or not) status of the branch. If False assume the branch
1507
1574
# We intentionally don't call the parent class's __init__, because it
1508
1575
# will try to assign to self.tags, which is a property in this subclass.
1539
1605
self._repo_lock_token = None
1540
1606
self._lock_count = 0
1541
1607
self._leave_lock = False
1608
# Setup a format: note that we cannot call _ensure_real until all the
1609
# attributes above are set: This code cannot be moved higher up in this
1612
self._format = RemoteBranchFormat()
1613
if real_branch is not None:
1614
self._format._network_name = \
1615
self._real_branch._format.network_name()
1617
# # XXX: Need to get this from BzrDir.open_branch's return value.
1618
# self._ensure_real()
1619
# self._format._network_name = \
1620
# self._real_branch._format.network_name()
1622
self._format = format
1542
1623
# The base class init is not called, so we duplicate this:
1543
1624
hooks = branch.Branch.hooks['open']
1544
1625
for hook in hooks:
1546
self._setup_stacking()
1628
self._setup_stacking()
1548
1630
def _setup_stacking(self):
1549
1631
# configure stacking into the remote repository, by reading it from
1889
1971
self._ensure_real()
1890
1972
return self._real_branch.set_stacked_on_url(stacked_location)
1892
def sprout(self, to_bzrdir, revision_id=None):
1893
branch_format = to_bzrdir._format._branch_format
1894
if (branch_format is None or
1895
isinstance(branch_format, RemoteBranchFormat)):
1896
# The to_bzrdir specifies RemoteBranchFormat (or no format, which
1897
# implies the same thing), but RemoteBranches can't be created at
1898
# arbitrary URLs. So create a branch in the same format as
1899
# _real_branch instead.
1900
# XXX: if to_bzrdir is a RemoteBzrDir, this should perhaps do
1901
# to_bzrdir.create_branch to create a RemoteBranch after all...
1903
result = self._real_branch._format.initialize(to_bzrdir)
1904
self.copy_content_into(result, revision_id=revision_id)
1905
result.set_parent(self.bzrdir.root_transport.base)
1907
result = branch.Branch.sprout(
1908
self, to_bzrdir, revision_id=revision_id)
1911
1974
@needs_write_lock
1912
1975
def pull(self, source, overwrite=False, stop_revision=None,