34
34
from bzrlib.branch import BranchReferenceFormat
35
35
from bzrlib.bzrdir import BzrDir, RemoteBzrDirFormat
36
from bzrlib.decorators import needs_read_lock, needs_write_lock, only_raises
36
from bzrlib.decorators import needs_read_lock, needs_write_lock
37
37
from bzrlib.errors import (
39
39
SmartProtocolError,
89
89
class RemoteBzrDir(BzrDir, _RpcHelper):
90
90
"""Control directory on a remote server, accessed via bzr:// or similar."""
92
def __init__(self, transport, format, _client=None, _force_probe=False):
92
def __init__(self, transport, format, _client=None):
93
93
"""Construct a RemoteBzrDir.
95
95
:param _client: Private parameter for testing. Disables probing and the
99
99
# this object holds a delegated bzrdir that uses file-level operations
100
100
# to talk to the other side
101
101
self._real_bzrdir = None
102
self._has_working_tree = None
103
102
# 1-shot cache for the call pattern 'create_branch; open_branch' - see
104
103
# create_branch for details.
105
104
self._next_open_branch_result = None
109
108
self._client = client._SmartClient(medium)
111
110
self._client = _client
117
def _probe_bzrdir(self):
118
medium = self._client._medium
119
113
path = self._path_for_remote_call(self._client)
120
if medium._is_remote_before((2, 1)):
124
self._rpc_open_2_1(path)
126
except errors.UnknownSmartMethod:
127
medium._remember_remote_is_before((2, 1))
130
def _rpc_open_2_1(self, path):
131
response = self._call('BzrDir.open_2.1', path)
132
if response == ('no',):
133
raise errors.NotBranchError(path=self.root_transport.base)
134
elif response[0] == 'yes':
135
if response[1] == 'yes':
136
self._has_working_tree = True
137
elif response[1] == 'no':
138
self._has_working_tree = False
140
raise errors.UnexpectedSmartServerResponse(response)
142
raise errors.UnexpectedSmartServerResponse(response)
144
def _rpc_open(self, path):
145
114
response = self._call('BzrDir.open', path)
146
115
if response not in [('yes',), ('no',)]:
147
116
raise errors.UnexpectedSmartServerResponse(response)
148
117
if response == ('no',):
149
raise errors.NotBranchError(path=self.root_transport.base)
118
raise errors.NotBranchError(path=transport.base)
151
120
def _ensure_real(self):
152
121
"""Ensure that there is a _real_bzrdir set.
154
123
Used before calls to self._real_bzrdir.
156
125
if not self._real_bzrdir:
157
if 'hpssvfs' in debug.debug_flags:
159
warning('VFS BzrDir access triggered\n%s',
160
''.join(traceback.format_stack()))
161
126
self._real_bzrdir = BzrDir.open_from_transport(
162
127
self.root_transport, _server_formats=False)
163
128
self._format._network_name = \
391
356
raise errors.NoRepositoryPresent(self)
393
def has_workingtree(self):
394
if self._has_working_tree is None:
396
self._has_working_tree = self._real_bzrdir.has_workingtree()
397
return self._has_working_tree
399
358
def open_workingtree(self, recommend_upgrade=True):
400
if self.has_workingtree():
360
if self._real_bzrdir.has_workingtree():
401
361
raise errors.NotLocalUrl(self.root_transport)
403
363
raise errors.NoWorkingTree(self.root_transport.base)
601
561
return self._custom_format._fetch_reconcile
603
563
def get_format_description(self):
605
return 'Remote: ' + self._custom_format.get_format_description()
564
return 'bzr remote repository'
607
566
def __eq__(self, other):
608
567
return self.__class__ is other.__class__
624
583
return self._custom_format._serializer
627
class RemoteRepository(_RpcHelper, lock._RelockDebugMixin):
586
class RemoteRepository(_RpcHelper):
628
587
"""Repository accessed over rpc.
630
589
For the moment most operations are performed using local transport-backed
951
910
def is_write_locked(self):
952
911
return self._lock_mode == 'w'
954
def _warn_if_deprecated(self, branch=None):
955
# If we have a real repository, the check will be done there, if we
956
# don't the check will be done remotely.
959
913
def lock_read(self):
960
914
# wrong eventually - want a local lock cache context
961
915
if not self._lock_mode:
963
916
self._lock_mode = 'r'
964
917
self._lock_count = 1
965
918
self._unstacked_provider.enable_cache(cache_misses=True)
1936
1887
:param search: The overall search to satisfy with streams.
1937
1888
:param sources: A list of Repository objects to query.
1939
self.from_serialiser = self.from_repository._format._serializer
1890
self.serialiser = self.to_format._serializer
1940
1891
self.seen_revs = set()
1941
1892
self.referenced_revs = set()
1942
1893
# If there are heads in the search, or the key count is > 0, we are not
1959
1910
def missing_parents_rev_handler(self, substream):
1960
1911
for content in substream:
1961
1912
revision_bytes = content.get_bytes_as('fulltext')
1962
revision = self.from_serialiser.read_revision_from_string(
1913
revision = self.serialiser.read_revision_from_string(revision_bytes)
1964
1914
self.seen_revs.add(content.key[-1])
1965
1915
self.referenced_revs.update(revision.parent_ids)
2095
2044
return self._custom_format.supports_set_append_revisions_only()
2098
class RemoteBranch(branch.Branch, _RpcHelper, lock._RelockDebugMixin):
2047
class RemoteBranch(branch.Branch, _RpcHelper):
2099
2048
"""Branch stored on a server accessed by HPSS RPC.
2101
2050
At the moment most operations are mapped down to simple file operations.
2359
2307
def lock_write(self, token=None):
2360
2308
if not self._lock_mode:
2361
self._note_lock('w')
2362
2309
# Lock the branch and repo in one remote call.
2363
2310
remote_tokens = self._remote_lock_write(token)
2364
2311
self._lock_token, self._repo_lock_token = remote_tokens