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