30
repository as _mod_repository,
31
32
revision as _mod_revision,
34
from bzrlib.branch import BranchReferenceFormat
36
from bzrlib.branch import BranchReferenceFormat, BranchWriteLockResult
35
37
from bzrlib.bzrdir import BzrDir, RemoteBzrDirFormat
36
from bzrlib.decorators import needs_read_lock, needs_write_lock
38
from bzrlib.decorators import needs_read_lock, needs_write_lock, only_raises
37
39
from bzrlib.errors import (
39
41
SmartProtocolError,
89
92
class RemoteBzrDir(BzrDir, _RpcHelper):
90
93
"""Control directory on a remote server, accessed via bzr:// or similar."""
92
def __init__(self, transport, format, _client=None):
95
def __init__(self, transport, format, _client=None, _force_probe=False):
93
96
"""Construct a RemoteBzrDir.
95
98
:param _client: Private parameter for testing. Disables probing and the
108
112
self._client = client._SmartClient(medium)
110
114
self._client = _client
121
return '%s(%r)' % (self.__class__.__name__, self._client)
123
def _probe_bzrdir(self):
124
medium = self._client._medium
113
125
path = self._path_for_remote_call(self._client)
126
if medium._is_remote_before((2, 1)):
130
self._rpc_open_2_1(path)
132
except errors.UnknownSmartMethod:
133
medium._remember_remote_is_before((2, 1))
136
def _rpc_open_2_1(self, path):
137
response = self._call('BzrDir.open_2.1', path)
138
if response == ('no',):
139
raise errors.NotBranchError(path=self.root_transport.base)
140
elif response[0] == 'yes':
141
if response[1] == 'yes':
142
self._has_working_tree = True
143
elif response[1] == 'no':
144
self._has_working_tree = False
146
raise errors.UnexpectedSmartServerResponse(response)
148
raise errors.UnexpectedSmartServerResponse(response)
150
def _rpc_open(self, path):
114
151
response = self._call('BzrDir.open', path)
115
152
if response not in [('yes',), ('no',)]:
116
153
raise errors.UnexpectedSmartServerResponse(response)
117
154
if response == ('no',):
118
raise errors.NotBranchError(path=transport.base)
155
raise errors.NotBranchError(path=self.root_transport.base)
120
157
def _ensure_real(self):
121
158
"""Ensure that there is a _real_bzrdir set.
123
160
Used before calls to self._real_bzrdir.
125
162
if not self._real_bzrdir:
163
if 'hpssvfs' in debug.debug_flags:
165
warning('VFS BzrDir access triggered\n%s',
166
''.join(traceback.format_stack()))
126
167
self._real_bzrdir = BzrDir.open_from_transport(
127
168
self.root_transport, _server_formats=False)
128
169
self._format._network_name = \
204
245
self._ensure_real()
205
246
self._real_bzrdir.destroy_repository()
207
def create_branch(self):
248
def create_branch(self, name=None):
208
249
# as per meta1 formats - just delegate to the format object which may
209
250
# be parameterised.
210
real_branch = self._format.get_branch_format().initialize(self)
251
real_branch = self._format.get_branch_format().initialize(self,
211
253
if not isinstance(real_branch, RemoteBranch):
212
result = RemoteBranch(self, self.find_repository(), real_branch)
254
result = RemoteBranch(self, self.find_repository(), real_branch,
214
257
result = real_branch
215
258
# BzrDir.clone_on_transport() uses the result of create_branch but does
221
264
self._next_open_branch_result = result
224
def destroy_branch(self):
267
def destroy_branch(self, name=None):
225
268
"""See BzrDir.destroy_branch"""
226
269
self._ensure_real()
227
self._real_bzrdir.destroy_branch()
270
self._real_bzrdir.destroy_branch(name=name)
228
271
self._next_open_branch_result = None
230
273
def create_workingtree(self, revision_id=None, from_branch=None):
231
274
raise errors.NotLocalUrl(self.transport.base)
233
def find_branch_format(self):
276
def find_branch_format(self, name=None):
234
277
"""Find the branch 'format' for this bzrdir.
236
279
This might be a synthetic object for e.g. RemoteBranch and SVN.
238
b = self.open_branch()
281
b = self.open_branch(name=name)
241
def get_branch_reference(self):
284
def get_branch_reference(self, name=None):
242
285
"""See BzrDir.get_branch_reference()."""
287
# XXX JRV20100304: Support opening colocated branches
288
raise errors.NoColocatedBranchSupport(self)
243
289
response = self._get_branch_reference()
244
290
if response[0] == 'ref':
245
291
return response[1]
249
295
def _get_branch_reference(self):
250
296
path = self._path_for_remote_call(self._client)
251
297
medium = self._client._medium
252
if not medium._is_remote_before((1, 13)):
299
('BzrDir.open_branchV3', (2, 1)),
300
('BzrDir.open_branchV2', (1, 13)),
301
('BzrDir.open_branch', None),
303
for verb, required_version in candidate_calls:
304
if required_version and medium._is_remote_before(required_version):
254
response = self._call('BzrDir.open_branchV2', path)
255
if response[0] not in ('ref', 'branch'):
256
raise errors.UnexpectedSmartServerResponse(response)
307
response = self._call(verb, path)
258
308
except errors.UnknownSmartMethod:
259
medium._remember_remote_is_before((1, 13))
260
response = self._call('BzrDir.open_branch', path)
261
if response[0] != 'ok':
309
if required_version is None:
311
medium._remember_remote_is_before(required_version)
314
if verb == 'BzrDir.open_branch':
315
if response[0] != 'ok':
316
raise errors.UnexpectedSmartServerResponse(response)
317
if response[1] != '':
318
return ('ref', response[1])
320
return ('branch', '')
321
if response[0] not in ('ref', 'branch'):
262
322
raise errors.UnexpectedSmartServerResponse(response)
263
if response[1] != '':
264
return ('ref', response[1])
266
return ('branch', '')
268
def _get_tree_branch(self):
325
def _get_tree_branch(self, name=None):
269
326
"""See BzrDir._get_tree_branch()."""
270
return None, self.open_branch()
327
return None, self.open_branch(name=name)
272
def open_branch(self, _unsupported=False, ignore_fallbacks=False):
329
def open_branch(self, name=None, unsupported=False,
330
ignore_fallbacks=False):
274
332
raise NotImplementedError('unsupported flag support not implemented yet.')
275
333
if self._next_open_branch_result is not None:
276
334
# See create_branch for details.
281
339
if response[0] == 'ref':
282
340
# a branch reference, use the existing BranchReference logic.
283
341
format = BranchReferenceFormat()
284
return format.open(self, _found=True, location=response[1],
285
ignore_fallbacks=ignore_fallbacks)
342
return format.open(self, name=name, _found=True,
343
location=response[1], ignore_fallbacks=ignore_fallbacks)
286
344
branch_format_name = response[1]
287
345
if not branch_format_name:
288
346
branch_format_name = None
289
347
format = RemoteBranchFormat(network_name=branch_format_name)
290
348
return RemoteBranch(self, self.find_repository(), format=format,
291
setup_stacking=not ignore_fallbacks)
349
setup_stacking=not ignore_fallbacks, name=name)
293
351
def _open_repo_v1(self, path):
294
352
verb = 'BzrDir.find_repository'
356
414
raise errors.NoRepositoryPresent(self)
416
def has_workingtree(self):
417
if self._has_working_tree is None:
419
self._has_working_tree = self._real_bzrdir.has_workingtree()
420
return self._has_working_tree
358
422
def open_workingtree(self, recommend_upgrade=True):
360
if self._real_bzrdir.has_workingtree():
423
if self.has_workingtree():
361
424
raise errors.NotLocalUrl(self.root_transport)
363
426
raise errors.NoWorkingTree(self.root_transport.base)
366
429
"""Return the path to be used for this bzrdir in a remote call."""
367
430
return client.remote_path_from_transport(self.root_transport)
369
def get_branch_transport(self, branch_format):
432
def get_branch_transport(self, branch_format, name=None):
370
433
self._ensure_real()
371
return self._real_bzrdir.get_branch_transport(branch_format)
434
return self._real_bzrdir.get_branch_transport(branch_format, name=name)
373
436
def get_repository_transport(self, repository_format):
374
437
self._ensure_real()
557
624
return self._custom_format._fetch_reconcile
559
626
def get_format_description(self):
560
return 'bzr remote repository'
628
return 'Remote: ' + self._custom_format.get_format_description()
562
630
def __eq__(self, other):
563
631
return self.__class__ is other.__class__
565
def check_conversion_target(self, target_format):
566
if self.rich_root_data and not target_format.rich_root_data:
567
raise errors.BadConversionTarget(
568
'Does not support rich root data.', target_format)
569
if (self.supports_tree_reference and
570
not getattr(target_format, 'supports_tree_reference', False)):
571
raise errors.BadConversionTarget(
572
'Does not support nested trees', target_format)
574
633
def network_name(self):
575
634
if self._network_name:
576
635
return self._network_name
637
697
# Additional places to query for data.
638
698
self._fallback_repositories = []
701
def user_transport(self):
702
return self.bzrdir.user_transport
705
def control_transport(self):
706
# XXX: Normally you shouldn't directly get at the remote repository
707
# transport, but I'm not sure it's worth making this method
708
# optional -- mbp 2010-04-21
709
return self.bzrdir.get_repository_transport(None)
640
711
def __str__(self):
641
712
return "%s(%s)" % (self.__class__.__name__, self.base)
828
899
def _has_same_fallbacks(self, other_repo):
829
900
"""Returns true if the repositories have the same fallbacks."""
830
901
# XXX: copied from Repository; it should be unified into a base class
831
# <https://bugs.edge.launchpad.net/bzr/+bug/401622>
902
# <https://bugs.launchpad.net/bzr/+bug/401622>
832
903
my_fb = self._fallback_repositories
833
904
other_fb = other_repo._fallback_repositories
834
905
if len(my_fb) != len(other_fb):
850
921
parents_provider = self._make_parents_provider(other_repository)
851
922
return graph.Graph(parents_provider)
925
def get_known_graph_ancestry(self, revision_ids):
926
"""Return the known graph for a set of revision ids and their ancestors.
928
st = static_tuple.StaticTuple
929
revision_keys = [st(r_id).intern() for r_id in revision_ids]
930
known_graph = self.revisions.get_known_graph_ancestry(revision_keys)
931
return graph.GraphThunkIdsToKeys(known_graph)
853
933
def gather_stats(self, revid=None, committers=None):
854
934
"""See Repository.gather_stats()."""
855
935
path = self.bzrdir._path_for_remote_call(self._client)
915
995
def is_write_locked(self):
916
996
return self._lock_mode == 'w'
998
def _warn_if_deprecated(self, branch=None):
999
# If we have a real repository, the check will be done there, if we
1000
# don't the check will be done remotely.
918
1003
def lock_read(self):
1004
"""Lock the repository for read operations.
1006
:return: A bzrlib.lock.LogicalLockResult.
919
1008
# wrong eventually - want a local lock cache context
920
1009
if not self._lock_mode:
1010
self._note_lock('r')
921
1011
self._lock_mode = 'r'
922
1012
self._lock_count = 1
923
1013
self._unstacked_provider.enable_cache(cache_misses=True)
1156
1249
# state, so always add a lock here. If a caller passes us a locked
1157
1250
# repository, they are responsible for unlocking it later.
1158
1251
repository.lock_read()
1252
self._check_fallback_repository(repository)
1159
1253
self._fallback_repositories.append(repository)
1160
1254
# If self._real_repository was parameterised already (e.g. because a
1161
1255
# _real_branch had its get_stacked_on_url method called), then the
1162
1256
# repository to be added may already be in the _real_repositories list.
1163
1257
if self._real_repository is not None:
1164
fallback_locations = [repo.bzrdir.root_transport.base for repo in
1258
fallback_locations = [repo.user_url for repo in
1165
1259
self._real_repository._fallback_repositories]
1166
if repository.bzrdir.root_transport.base not in fallback_locations:
1260
if repository.user_url not in fallback_locations:
1167
1261
self._real_repository.add_fallback_repository(repository)
1263
def _check_fallback_repository(self, repository):
1264
"""Check that this repository can fallback to repository safely.
1266
Raise an error if not.
1268
:param repository: A repository to fallback to.
1270
return _mod_repository.InterRepository._assert_same_model(
1169
1273
def add_inventory(self, revid, inv, parents):
1170
1274
self._ensure_real()
1171
1275
return self._real_repository.add_inventory(revid, inv, parents)
1173
1277
def add_inventory_by_delta(self, basis_revision_id, delta, new_revision_id,
1278
parents, basis_inv=None, propagate_caches=False):
1175
1279
self._ensure_real()
1176
1280
return self._real_repository.add_inventory_by_delta(basis_revision_id,
1177
delta, new_revision_id, parents)
1281
delta, new_revision_id, parents, basis_inv=basis_inv,
1282
propagate_caches=propagate_caches)
1179
1284
def add_revision(self, rev_id, rev, inv=None, config=None):
1180
1285
self._ensure_real()
1210
1315
return self._real_repository.make_working_trees()
1212
1317
def refresh_data(self):
1213
"""Re-read any data needed to to synchronise with disk.
1318
"""Re-read any data needed to synchronise with disk.
1215
1320
This method is intended to be called after another repository instance
1216
1321
(such as one used by a smart server) has inserted data into the
1217
repository. It may not be called during a write group, but may be
1218
called at any other time.
1322
repository. On all repositories this will work outside of write groups.
1323
Some repository formats (pack and newer for bzrlib native formats)
1324
support refresh_data inside write groups. If called inside a write
1325
group on a repository that does not support refreshing in a write group
1326
IsInWriteGroupError will be raised.
1220
if self.is_in_write_group():
1221
raise errors.InternalBzrError(
1222
"May not refresh_data while in a write group.")
1223
1328
if self._real_repository is not None:
1224
1329
self._real_repository.refresh_data()
1439
1544
return self._real_repository.get_signature_text(revision_id)
1441
1546
@needs_read_lock
1442
def get_inventory_xml(self, revision_id):
1444
return self._real_repository.get_inventory_xml(revision_id)
1446
def deserialise_inventory(self, revision_id, xml):
1448
return self._real_repository.deserialise_inventory(revision_id, xml)
1547
def _get_inventory_xml(self, revision_id):
1549
return self._real_repository._get_inventory_xml(revision_id)
1450
1551
def reconcile(self, other=None, thorough=False):
1451
1552
self._ensure_real()
1527
1628
return self._real_repository.inventories
1529
1630
@needs_write_lock
1530
def pack(self, hint=None):
1631
def pack(self, hint=None, clean_obsolete_packs=False):
1531
1632
"""Compress the data within the repository.
1533
1634
This is not currently implemented within the smart server.
1535
1636
self._ensure_real()
1536
return self._real_repository.pack(hint=hint)
1637
return self._real_repository.pack(hint=hint, clean_obsolete_packs=clean_obsolete_packs)
1539
1640
def revisions(self):
1744
1845
# The stream included an inventory-delta record, but the remote
1745
1846
# side isn't new enough to support them. So we need to send the
1746
1847
# rest of the stream via VFS.
1848
self.target_repo.refresh_data()
1747
1849
return self._resume_stream_with_vfs(response, src_format)
1748
1850
if response[0][0] == 'missing-basis':
1749
1851
tokens, missing_keys = bencode.bdecode_as_tuple(response[0][1])
1878
1980
if response_tuple[0] != 'ok':
1879
1981
raise errors.UnexpectedSmartServerResponse(response_tuple)
1880
1982
byte_stream = response_handler.read_streamed_body()
1881
src_format, stream = smart_repo._byte_stream_to_stream(byte_stream)
1983
src_format, stream = smart_repo._byte_stream_to_stream(byte_stream,
1984
self._record_counter)
1882
1985
if src_format.network_name() != repo._format.network_name():
1883
1986
raise AssertionError(
1884
1987
"Mismatched RemoteRepository and stream src %r, %r" % (
1914
2017
def missing_parents_rev_handler(self, substream):
1915
2018
for content in substream:
1916
2019
revision_bytes = content.get_bytes_as('fulltext')
1917
revision = self.serialiser.read_revision_from_string(revision_bytes)
2020
revision = self.from_serialiser.read_revision_from_string(
1918
2022
self.seen_revs.add(content.key[-1])
1919
2023
self.referenced_revs.update(revision.parent_ids)
1959
2063
self._network_name)
1961
2065
def get_format_description(self):
1962
return 'Remote BZR Branch'
2067
return 'Remote: ' + self._custom_format.get_format_description()
1964
2069
def network_name(self):
1965
2070
return self._network_name
1967
def open(self, a_bzrdir, ignore_fallbacks=False):
1968
return a_bzrdir.open_branch(ignore_fallbacks=ignore_fallbacks)
2072
def open(self, a_bzrdir, name=None, ignore_fallbacks=False):
2073
return a_bzrdir.open_branch(name=name,
2074
ignore_fallbacks=ignore_fallbacks)
1970
def _vfs_initialize(self, a_bzrdir):
2076
def _vfs_initialize(self, a_bzrdir, name):
1971
2077
# Initialisation when using a local bzrdir object, or a non-vfs init
1972
2078
# method is not available on the server.
1973
2079
# self._custom_format is always set - the start of initialize ensures
1975
2081
if isinstance(a_bzrdir, RemoteBzrDir):
1976
2082
a_bzrdir._ensure_real()
1977
result = self._custom_format.initialize(a_bzrdir._real_bzrdir)
2083
result = self._custom_format.initialize(a_bzrdir._real_bzrdir,
1979
2086
# We assume the bzrdir is parameterised; it may not be.
1980
result = self._custom_format.initialize(a_bzrdir)
2087
result = self._custom_format.initialize(a_bzrdir, name)
1981
2088
if (isinstance(a_bzrdir, RemoteBzrDir) and
1982
2089
not isinstance(result, RemoteBranch)):
1983
result = RemoteBranch(a_bzrdir, a_bzrdir.find_repository(), result)
2090
result = RemoteBranch(a_bzrdir, a_bzrdir.find_repository(), result,
1986
def initialize(self, a_bzrdir):
2094
def initialize(self, a_bzrdir, name=None):
1987
2095
# 1) get the network name to use.
1988
2096
if self._custom_format:
1989
2097
network_name = self._custom_format.network_name()
1995
2103
network_name = reference_format.network_name()
1996
2104
# Being asked to create on a non RemoteBzrDir:
1997
2105
if not isinstance(a_bzrdir, RemoteBzrDir):
1998
return self._vfs_initialize(a_bzrdir)
2106
return self._vfs_initialize(a_bzrdir, name=name)
1999
2107
medium = a_bzrdir._client._medium
2000
2108
if medium._is_remote_before((1, 13)):
2001
return self._vfs_initialize(a_bzrdir)
2109
return self._vfs_initialize(a_bzrdir, name=name)
2002
2110
# Creating on a remote bzr dir.
2003
2111
# 2) try direct creation via RPC
2004
2112
path = a_bzrdir._path_for_remote_call(a_bzrdir._client)
2113
if name is not None:
2114
# XXX JRV20100304: Support creating colocated branches
2115
raise errors.NoColocatedBranchSupport(self)
2005
2116
verb = 'BzrDir.create_branch'
2007
2118
response = a_bzrdir._call(verb, path, network_name)
2008
2119
except errors.UnknownSmartMethod:
2009
2120
# Fallback - use vfs methods
2010
2121
medium._remember_remote_is_before((1, 13))
2011
return self._vfs_initialize(a_bzrdir)
2122
return self._vfs_initialize(a_bzrdir, name=name)
2012
2123
if response[0] != 'ok':
2013
2124
raise errors.UnexpectedSmartServerResponse(response)
2014
2125
# Turn the response into a RemoteRepository object.
2022
2133
a_bzrdir._client)
2023
2134
remote_repo = RemoteRepository(repo_bzrdir, repo_format)
2024
2135
remote_branch = RemoteBranch(a_bzrdir, remote_repo,
2025
format=format, setup_stacking=False)
2136
format=format, setup_stacking=False, name=name)
2026
2137
# XXX: We know this is a new branch, so it must have revno 0, revid
2027
2138
# NULL_REVISION. Creating the branch locked would make this be unable
2028
2139
# to be wrong; here its simply very unlikely to be wrong. RBC 20090225
2048
2159
return self._custom_format.supports_set_append_revisions_only()
2051
class RemoteBranch(branch.Branch, _RpcHelper):
2162
class RemoteBranch(branch.Branch, _RpcHelper, lock._RelockDebugMixin):
2052
2163
"""Branch stored on a server accessed by HPSS RPC.
2054
2165
At the moment most operations are mapped down to simple file operations.
2057
2168
def __init__(self, remote_bzrdir, remote_repository, real_branch=None,
2058
_client=None, format=None, setup_stacking=True):
2169
_client=None, format=None, setup_stacking=True, name=None):
2059
2170
"""Create a RemoteBranch instance.
2061
2172
:param real_branch: An optional local implementation of the branch
2162
2276
'to use vfs implementation')
2163
2277
self.bzrdir._ensure_real()
2164
2278
self._real_branch = self.bzrdir._real_bzrdir.open_branch(
2165
ignore_fallbacks=self._real_ignore_fallbacks)
2279
ignore_fallbacks=self._real_ignore_fallbacks, name=self._name)
2166
2280
if self.repository._real_repository is None:
2167
2281
# Give the remote repository the matching real repo.
2168
2282
real_repo = self._real_branch.repository
2282
2397
self._vfs_set_tags_bytes(bytes)
2284
2399
def lock_read(self):
2400
"""Lock the branch for read operations.
2402
:return: A bzrlib.lock.LogicalLockResult.
2285
2404
self.repository.lock_read()
2286
2405
if not self._lock_mode:
2406
self._note_lock('r')
2287
2407
self._lock_mode = 'r'
2288
2408
self._lock_count = 1
2289
2409
if self._real_branch is not None:
2290
2410
self._real_branch.lock_read()
2292
2412
self._lock_count += 1
2413
return lock.LogicalLockResult(self.unlock)
2294
2415
def _remote_lock_write(self, token):
2295
2416
if token is None:
2296
2417
branch_token = repo_token = ''
2298
2419
branch_token = token
2299
repo_token = self.repository.lock_write()
2420
repo_token = self.repository.lock_write().repository_token
2300
2421
self.repository.unlock()
2301
2422
err_context = {'token': token}
2302
response = self._call(
2303
'Branch.lock_write', self._remote_path(), branch_token,
2304
repo_token or '', **err_context)
2424
response = self._call(
2425
'Branch.lock_write', self._remote_path(), branch_token,
2426
repo_token or '', **err_context)
2427
except errors.LockContention, e:
2428
# The LockContention from the server doesn't have any
2429
# information about the lock_url. We re-raise LockContention
2430
# with valid lock_url.
2431
raise errors.LockContention('(remote lock)',
2432
self.repository.base.split('.bzr/')[0])
2305
2433
if response[0] != 'ok':
2306
2434
raise errors.UnexpectedSmartServerResponse(response)
2307
2435
ok, branch_token, repo_token = response
2338
2467
self._lock_count += 1
2339
2468
# Re-lock the repository too.
2340
2469
self.repository.lock_write(self._repo_lock_token)
2341
return self._lock_token or None
2470
return BranchWriteLockResult(self.unlock, self._lock_token or None)
2343
2472
def _unlock(self, branch_token, repo_token):
2344
2473
err_context = {'token': str((branch_token, repo_token))}
2665
2796
medium = self._branch._client._medium
2666
2797
if medium._is_remote_before((1, 14)):
2667
2798
return self._vfs_set_option(value, name, section)
2799
if isinstance(value, dict):
2800
if medium._is_remote_before((2, 2)):
2801
return self._vfs_set_option(value, name, section)
2802
return self._set_config_option_dict(value, name, section)
2804
return self._set_config_option(value, name, section)
2806
def _set_config_option(self, value, name, section):
2669
2808
path = self._branch._remote_path()
2670
2809
response = self._branch._client.call('Branch.set_config_option',
2671
2810
path, self._branch._lock_token, self._branch._repo_lock_token,
2672
2811
value.encode('utf8'), name, section or '')
2673
2812
except errors.UnknownSmartMethod:
2813
medium = self._branch._client._medium
2674
2814
medium._remember_remote_is_before((1, 14))
2675
2815
return self._vfs_set_option(value, name, section)
2676
2816
if response != ():
2677
2817
raise errors.UnexpectedSmartServerResponse(response)
2819
def _serialize_option_dict(self, option_dict):
2821
for key, value in option_dict.items():
2822
if isinstance(key, unicode):
2823
key = key.encode('utf8')
2824
if isinstance(value, unicode):
2825
value = value.encode('utf8')
2826
utf8_dict[key] = value
2827
return bencode.bencode(utf8_dict)
2829
def _set_config_option_dict(self, value, name, section):
2831
path = self._branch._remote_path()
2832
serialised_dict = self._serialize_option_dict(value)
2833
response = self._branch._client.call(
2834
'Branch.set_config_option_dict',
2835
path, self._branch._lock_token, self._branch._repo_lock_token,
2836
serialised_dict, name, section or '')
2837
except errors.UnknownSmartMethod:
2838
medium = self._branch._client._medium
2839
medium._remember_remote_is_before((2, 2))
2840
return self._vfs_set_option(value, name, section)
2842
raise errors.UnexpectedSmartServerResponse(response)
2679
2844
def _real_object(self):
2680
2845
self._branch._ensure_real()
2681
2846
return self._branch._real_branch
2764
2929
'Missing key %r in context %r', key_err.args[0], context)
2767
if err.error_verb == 'NoSuchRevision':
2932
if err.error_verb == 'IncompatibleRepositories':
2933
raise errors.IncompatibleRepositories(err.error_args[0],
2934
err.error_args[1], err.error_args[2])
2935
elif err.error_verb == 'NoSuchRevision':
2768
2936
raise NoSuchRevision(find('branch'), err.error_args[0])
2769
2937
elif err.error_verb == 'nosuchrevision':
2770
2938
raise NoSuchRevision(find('repository'), err.error_args[0])
2771
elif err.error_tuple == ('nobranch',):
2772
raise errors.NotBranchError(path=find('bzrdir').root_transport.base)
2939
elif err.error_verb == 'nobranch':
2940
if len(err.error_args) >= 1:
2941
extra = err.error_args[0]
2944
raise errors.NotBranchError(path=find('bzrdir').root_transport.base,
2773
2946
elif err.error_verb == 'norepository':
2774
2947
raise errors.NoRepositoryPresent(find('bzrdir'))
2775
2948
elif err.error_verb == 'LockContention':