31
repository as _mod_repository,
33
31
revision as _mod_revision,
37
from bzrlib.branch import BranchReferenceFormat, BranchWriteLockResult
34
from bzrlib.branch import BranchReferenceFormat
38
35
from bzrlib.bzrdir import BzrDir, RemoteBzrDirFormat
39
from bzrlib.decorators import needs_read_lock, needs_write_lock, only_raises
36
from bzrlib.decorators import needs_read_lock, needs_write_lock
40
37
from bzrlib.errors import (
42
39
SmartProtocolError,
93
89
class RemoteBzrDir(BzrDir, _RpcHelper):
94
90
"""Control directory on a remote server, accessed via bzr:// or similar."""
96
def __init__(self, transport, format, _client=None, _force_probe=False):
92
def __init__(self, transport, format, _client=None):
97
93
"""Construct a RemoteBzrDir.
99
95
:param _client: Private parameter for testing. Disables probing and the
113
108
self._client = client._SmartClient(medium)
115
110
self._client = _client
122
return '%s(%r)' % (self.__class__.__name__, self._client)
124
def _probe_bzrdir(self):
125
medium = self._client._medium
126
113
path = self._path_for_remote_call(self._client)
127
if medium._is_remote_before((2, 1)):
131
self._rpc_open_2_1(path)
133
except errors.UnknownSmartMethod:
134
medium._remember_remote_is_before((2, 1))
137
def _rpc_open_2_1(self, path):
138
response = self._call('BzrDir.open_2.1', path)
139
if response == ('no',):
140
raise errors.NotBranchError(path=self.root_transport.base)
141
elif response[0] == 'yes':
142
if response[1] == 'yes':
143
self._has_working_tree = True
144
elif response[1] == 'no':
145
self._has_working_tree = False
147
raise errors.UnexpectedSmartServerResponse(response)
149
raise errors.UnexpectedSmartServerResponse(response)
151
def _rpc_open(self, path):
152
114
response = self._call('BzrDir.open', path)
153
115
if response not in [('yes',), ('no',)]:
154
116
raise errors.UnexpectedSmartServerResponse(response)
155
117
if response == ('no',):
156
raise errors.NotBranchError(path=self.root_transport.base)
118
raise errors.NotBranchError(path=transport.base)
158
120
def _ensure_real(self):
159
121
"""Ensure that there is a _real_bzrdir set.
161
123
Used before calls to self._real_bzrdir.
163
125
if not self._real_bzrdir:
164
if 'hpssvfs' in debug.debug_flags:
166
warning('VFS BzrDir access triggered\n%s',
167
''.join(traceback.format_stack()))
168
126
self._real_bzrdir = BzrDir.open_from_transport(
169
127
self.root_transport, _server_formats=False)
170
128
self._format._network_name = \
246
204
self._ensure_real()
247
205
self._real_bzrdir.destroy_repository()
249
def create_branch(self, name=None):
207
def create_branch(self):
250
208
# as per meta1 formats - just delegate to the format object which may
251
209
# be parameterised.
252
real_branch = self._format.get_branch_format().initialize(self,
210
real_branch = self._format.get_branch_format().initialize(self)
254
211
if not isinstance(real_branch, RemoteBranch):
255
result = RemoteBranch(self, self.find_repository(), real_branch,
212
result = RemoteBranch(self, self.find_repository(), real_branch)
258
214
result = real_branch
259
215
# BzrDir.clone_on_transport() uses the result of create_branch but does
265
221
self._next_open_branch_result = result
268
def destroy_branch(self, name=None):
224
def destroy_branch(self):
269
225
"""See BzrDir.destroy_branch"""
270
226
self._ensure_real()
271
self._real_bzrdir.destroy_branch(name=name)
227
self._real_bzrdir.destroy_branch()
272
228
self._next_open_branch_result = None
274
230
def create_workingtree(self, revision_id=None, from_branch=None):
275
231
raise errors.NotLocalUrl(self.transport.base)
277
def find_branch_format(self, name=None):
233
def find_branch_format(self):
278
234
"""Find the branch 'format' for this bzrdir.
280
236
This might be a synthetic object for e.g. RemoteBranch and SVN.
282
b = self.open_branch(name=name)
238
b = self.open_branch()
285
def get_branch_reference(self, name=None):
241
def get_branch_reference(self):
286
242
"""See BzrDir.get_branch_reference()."""
288
# XXX JRV20100304: Support opening colocated branches
289
raise errors.NoColocatedBranchSupport(self)
290
243
response = self._get_branch_reference()
291
244
if response[0] == 'ref':
292
245
return response[1]
296
249
def _get_branch_reference(self):
297
250
path = self._path_for_remote_call(self._client)
298
251
medium = self._client._medium
300
('BzrDir.open_branchV3', (2, 1)),
301
('BzrDir.open_branchV2', (1, 13)),
302
('BzrDir.open_branch', None),
304
for verb, required_version in candidate_calls:
305
if required_version and medium._is_remote_before(required_version):
252
if not medium._is_remote_before((1, 13)):
308
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)
309
258
except errors.UnknownSmartMethod:
310
if required_version is None:
312
medium._remember_remote_is_before(required_version)
315
if verb == 'BzrDir.open_branch':
316
if response[0] != 'ok':
317
raise errors.UnexpectedSmartServerResponse(response)
318
if response[1] != '':
319
return ('ref', response[1])
321
return ('branch', '')
322
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':
323
262
raise errors.UnexpectedSmartServerResponse(response)
263
if response[1] != '':
264
return ('ref', response[1])
266
return ('branch', '')
326
def _get_tree_branch(self, name=None):
268
def _get_tree_branch(self):
327
269
"""See BzrDir._get_tree_branch()."""
328
return None, self.open_branch(name=name)
270
return None, self.open_branch()
330
def open_branch(self, name=None, unsupported=False,
331
ignore_fallbacks=False):
272
def open_branch(self, _unsupported=False, ignore_fallbacks=False):
333
274
raise NotImplementedError('unsupported flag support not implemented yet.')
334
275
if self._next_open_branch_result is not None:
335
276
# See create_branch for details.
340
281
if response[0] == 'ref':
341
282
# a branch reference, use the existing BranchReference logic.
342
283
format = BranchReferenceFormat()
343
return format.open(self, name=name, _found=True,
344
location=response[1], ignore_fallbacks=ignore_fallbacks)
284
return format.open(self, _found=True, location=response[1],
285
ignore_fallbacks=ignore_fallbacks)
345
286
branch_format_name = response[1]
346
287
if not branch_format_name:
347
288
branch_format_name = None
348
289
format = RemoteBranchFormat(network_name=branch_format_name)
349
290
return RemoteBranch(self, self.find_repository(), format=format,
350
setup_stacking=not ignore_fallbacks, name=name)
291
setup_stacking=not ignore_fallbacks)
352
293
def _open_repo_v1(self, path):
353
294
verb = 'BzrDir.find_repository'
415
356
raise errors.NoRepositoryPresent(self)
417
def has_workingtree(self):
418
if self._has_working_tree is None:
420
self._has_working_tree = self._real_bzrdir.has_workingtree()
421
return self._has_working_tree
423
358
def open_workingtree(self, recommend_upgrade=True):
424
if self.has_workingtree():
360
if self._real_bzrdir.has_workingtree():
425
361
raise errors.NotLocalUrl(self.root_transport)
427
363
raise errors.NoWorkingTree(self.root_transport.base)
430
366
"""Return the path to be used for this bzrdir in a remote call."""
431
367
return client.remote_path_from_transport(self.root_transport)
433
def get_branch_transport(self, branch_format, name=None):
369
def get_branch_transport(self, branch_format):
434
370
self._ensure_real()
435
return self._real_bzrdir.get_branch_transport(branch_format, name=name)
371
return self._real_bzrdir.get_branch_transport(branch_format)
437
373
def get_repository_transport(self, repository_format):
438
374
self._ensure_real()
625
561
return self._custom_format._fetch_reconcile
627
563
def get_format_description(self):
629
return 'Remote: ' + self._custom_format.get_format_description()
564
return 'bzr remote repository'
631
566
def __eq__(self, other):
632
567
return self.__class__ is other.__class__
569
def check_conversion_target(self, target_format):
570
if self.rich_root_data and not target_format.rich_root_data:
571
raise errors.BadConversionTarget(
572
'Does not support rich root data.', target_format,
574
if (self.supports_tree_reference and
575
not getattr(target_format, 'supports_tree_reference', False)):
576
raise errors.BadConversionTarget(
577
'Does not support nested trees', target_format,
634
580
def network_name(self):
635
581
if self._network_name:
636
582
return self._network_name
698
643
# Additional places to query for data.
699
644
self._fallback_repositories = []
702
def user_transport(self):
703
return self.bzrdir.user_transport
706
def control_transport(self):
707
# XXX: Normally you shouldn't directly get at the remote repository
708
# transport, but I'm not sure it's worth making this method
709
# optional -- mbp 2010-04-21
710
return self.bzrdir.get_repository_transport(None)
712
646
def __str__(self):
713
647
return "%s(%s)" % (self.__class__.__name__, self.base)
900
834
def _has_same_fallbacks(self, other_repo):
901
835
"""Returns true if the repositories have the same fallbacks."""
902
836
# XXX: copied from Repository; it should be unified into a base class
903
# <https://bugs.launchpad.net/bzr/+bug/401622>
837
# <https://bugs.edge.launchpad.net/bzr/+bug/401622>
904
838
my_fb = self._fallback_repositories
905
839
other_fb = other_repo._fallback_repositories
906
840
if len(my_fb) != len(other_fb):
922
856
parents_provider = self._make_parents_provider(other_repository)
923
857
return graph.Graph(parents_provider)
926
def get_known_graph_ancestry(self, revision_ids):
927
"""Return the known graph for a set of revision ids and their ancestors.
929
st = static_tuple.StaticTuple
930
revision_keys = [st(r_id).intern() for r_id in revision_ids]
931
known_graph = self.revisions.get_known_graph_ancestry(revision_keys)
932
return graph.GraphThunkIdsToKeys(known_graph)
934
859
def gather_stats(self, revid=None, committers=None):
935
860
"""See Repository.gather_stats()."""
936
861
path = self.bzrdir._path_for_remote_call(self._client)
996
921
def is_write_locked(self):
997
922
return self._lock_mode == 'w'
999
def _warn_if_deprecated(self, branch=None):
1000
# If we have a real repository, the check will be done there, if we
1001
# don't the check will be done remotely.
1004
924
def lock_read(self):
1005
"""Lock the repository for read operations.
1007
:return: A bzrlib.lock.LogicalLockResult.
1009
925
# wrong eventually - want a local lock cache context
1010
926
if not self._lock_mode:
1011
self._note_lock('r')
1012
927
self._lock_mode = 'r'
1013
928
self._lock_count = 1
1014
929
self._unstacked_provider.enable_cache(cache_misses=True)
1250
1162
# state, so always add a lock here. If a caller passes us a locked
1251
1163
# repository, they are responsible for unlocking it later.
1252
1164
repository.lock_read()
1253
self._check_fallback_repository(repository)
1254
1165
self._fallback_repositories.append(repository)
1255
1166
# If self._real_repository was parameterised already (e.g. because a
1256
1167
# _real_branch had its get_stacked_on_url method called), then the
1257
1168
# repository to be added may already be in the _real_repositories list.
1258
1169
if self._real_repository is not None:
1259
fallback_locations = [repo.user_url for repo in
1170
fallback_locations = [repo.bzrdir.root_transport.base for repo in
1260
1171
self._real_repository._fallback_repositories]
1261
if repository.user_url not in fallback_locations:
1172
if repository.bzrdir.root_transport.base not in fallback_locations:
1262
1173
self._real_repository.add_fallback_repository(repository)
1264
def _check_fallback_repository(self, repository):
1265
"""Check that this repository can fallback to repository safely.
1267
Raise an error if not.
1269
:param repository: A repository to fallback to.
1271
return _mod_repository.InterRepository._assert_same_model(
1274
1175
def add_inventory(self, revid, inv, parents):
1275
1176
self._ensure_real()
1276
1177
return self._real_repository.add_inventory(revid, inv, parents)
1278
1179
def add_inventory_by_delta(self, basis_revision_id, delta, new_revision_id,
1279
parents, basis_inv=None, propagate_caches=False):
1280
1181
self._ensure_real()
1281
1182
return self._real_repository.add_inventory_by_delta(basis_revision_id,
1282
delta, new_revision_id, parents, basis_inv=basis_inv,
1283
propagate_caches=propagate_caches)
1183
delta, new_revision_id, parents)
1285
1185
def add_revision(self, rev_id, rev, inv=None, config=None):
1286
1186
self._ensure_real()
1316
1216
return self._real_repository.make_working_trees()
1318
1218
def refresh_data(self):
1319
"""Re-read any data needed to synchronise with disk.
1219
"""Re-read any data needed to to synchronise with disk.
1321
1221
This method is intended to be called after another repository instance
1322
1222
(such as one used by a smart server) has inserted data into the
1323
repository. On all repositories this will work outside of write groups.
1324
Some repository formats (pack and newer for bzrlib native formats)
1325
support refresh_data inside write groups. If called inside a write
1326
group on a repository that does not support refreshing in a write group
1327
IsInWriteGroupError will be raised.
1223
repository. It may not be called during a write group, but may be
1224
called at any other time.
1226
if self.is_in_write_group():
1227
raise errors.InternalBzrError(
1228
"May not refresh_data while in a write group.")
1329
1229
if self._real_repository is not None:
1330
1230
self._real_repository.refresh_data()
1545
1445
return self._real_repository.get_signature_text(revision_id)
1547
1447
@needs_read_lock
1548
def _get_inventory_xml(self, revision_id):
1550
return self._real_repository._get_inventory_xml(revision_id)
1448
def get_inventory_xml(self, revision_id):
1450
return self._real_repository.get_inventory_xml(revision_id)
1452
def deserialise_inventory(self, revision_id, xml):
1454
return self._real_repository.deserialise_inventory(revision_id, xml)
1552
1456
def reconcile(self, other=None, thorough=False):
1553
1457
self._ensure_real()
1629
1533
return self._real_repository.inventories
1631
1535
@needs_write_lock
1632
def pack(self, hint=None, clean_obsolete_packs=False):
1536
def pack(self, hint=None):
1633
1537
"""Compress the data within the repository.
1635
1539
This is not currently implemented within the smart server.
1637
1541
self._ensure_real()
1638
return self._real_repository.pack(hint=hint, clean_obsolete_packs=clean_obsolete_packs)
1542
return self._real_repository.pack(hint=hint)
1641
1545
def revisions(self):
1846
1750
# The stream included an inventory-delta record, but the remote
1847
1751
# side isn't new enough to support them. So we need to send the
1848
1752
# rest of the stream via VFS.
1849
self.target_repo.refresh_data()
1850
1753
return self._resume_stream_with_vfs(response, src_format)
1851
1754
if response[0][0] == 'missing-basis':
1852
1755
tokens, missing_keys = bencode.bdecode_as_tuple(response[0][1])
1981
1884
if response_tuple[0] != 'ok':
1982
1885
raise errors.UnexpectedSmartServerResponse(response_tuple)
1983
1886
byte_stream = response_handler.read_streamed_body()
1984
src_format, stream = smart_repo._byte_stream_to_stream(byte_stream,
1985
self._record_counter)
1887
src_format, stream = smart_repo._byte_stream_to_stream(byte_stream)
1986
1888
if src_format.network_name() != repo._format.network_name():
1987
1889
raise AssertionError(
1988
1890
"Mismatched RemoteRepository and stream src %r, %r" % (
2018
1920
def missing_parents_rev_handler(self, substream):
2019
1921
for content in substream:
2020
1922
revision_bytes = content.get_bytes_as('fulltext')
2021
revision = self.from_serialiser.read_revision_from_string(
1923
revision = self.serialiser.read_revision_from_string(revision_bytes)
2023
1924
self.seen_revs.add(content.key[-1])
2024
1925
self.referenced_revs.update(revision.parent_ids)
2064
1965
self._network_name)
2066
1967
def get_format_description(self):
2068
return 'Remote: ' + self._custom_format.get_format_description()
1968
return 'Remote BZR Branch'
2070
1970
def network_name(self):
2071
1971
return self._network_name
2073
def open(self, a_bzrdir, name=None, ignore_fallbacks=False):
2074
return a_bzrdir.open_branch(name=name,
2075
ignore_fallbacks=ignore_fallbacks)
1973
def open(self, a_bzrdir, ignore_fallbacks=False):
1974
return a_bzrdir.open_branch(ignore_fallbacks=ignore_fallbacks)
2077
def _vfs_initialize(self, a_bzrdir, name):
1976
def _vfs_initialize(self, a_bzrdir):
2078
1977
# Initialisation when using a local bzrdir object, or a non-vfs init
2079
1978
# method is not available on the server.
2080
1979
# self._custom_format is always set - the start of initialize ensures
2082
1981
if isinstance(a_bzrdir, RemoteBzrDir):
2083
1982
a_bzrdir._ensure_real()
2084
result = self._custom_format.initialize(a_bzrdir._real_bzrdir,
1983
result = self._custom_format.initialize(a_bzrdir._real_bzrdir)
2087
1985
# We assume the bzrdir is parameterised; it may not be.
2088
result = self._custom_format.initialize(a_bzrdir, name)
1986
result = self._custom_format.initialize(a_bzrdir)
2089
1987
if (isinstance(a_bzrdir, RemoteBzrDir) and
2090
1988
not isinstance(result, RemoteBranch)):
2091
result = RemoteBranch(a_bzrdir, a_bzrdir.find_repository(), result,
1989
result = RemoteBranch(a_bzrdir, a_bzrdir.find_repository(), result)
2095
def initialize(self, a_bzrdir, name=None):
1992
def initialize(self, a_bzrdir):
2096
1993
# 1) get the network name to use.
2097
1994
if self._custom_format:
2098
1995
network_name = self._custom_format.network_name()
2104
2001
network_name = reference_format.network_name()
2105
2002
# Being asked to create on a non RemoteBzrDir:
2106
2003
if not isinstance(a_bzrdir, RemoteBzrDir):
2107
return self._vfs_initialize(a_bzrdir, name=name)
2004
return self._vfs_initialize(a_bzrdir)
2108
2005
medium = a_bzrdir._client._medium
2109
2006
if medium._is_remote_before((1, 13)):
2110
return self._vfs_initialize(a_bzrdir, name=name)
2007
return self._vfs_initialize(a_bzrdir)
2111
2008
# Creating on a remote bzr dir.
2112
2009
# 2) try direct creation via RPC
2113
2010
path = a_bzrdir._path_for_remote_call(a_bzrdir._client)
2114
if name is not None:
2115
# XXX JRV20100304: Support creating colocated branches
2116
raise errors.NoColocatedBranchSupport(self)
2117
2011
verb = 'BzrDir.create_branch'
2119
2013
response = a_bzrdir._call(verb, path, network_name)
2120
2014
except errors.UnknownSmartMethod:
2121
2015
# Fallback - use vfs methods
2122
2016
medium._remember_remote_is_before((1, 13))
2123
return self._vfs_initialize(a_bzrdir, name=name)
2017
return self._vfs_initialize(a_bzrdir)
2124
2018
if response[0] != 'ok':
2125
2019
raise errors.UnexpectedSmartServerResponse(response)
2126
2020
# Turn the response into a RemoteRepository object.
2134
2028
a_bzrdir._client)
2135
2029
remote_repo = RemoteRepository(repo_bzrdir, repo_format)
2136
2030
remote_branch = RemoteBranch(a_bzrdir, remote_repo,
2137
format=format, setup_stacking=False, name=name)
2031
format=format, setup_stacking=False)
2138
2032
# XXX: We know this is a new branch, so it must have revno 0, revid
2139
2033
# NULL_REVISION. Creating the branch locked would make this be unable
2140
2034
# to be wrong; here its simply very unlikely to be wrong. RBC 20090225
2160
2054
return self._custom_format.supports_set_append_revisions_only()
2163
class RemoteBranch(branch.Branch, _RpcHelper, lock._RelockDebugMixin):
2057
class RemoteBranch(branch.Branch, _RpcHelper):
2164
2058
"""Branch stored on a server accessed by HPSS RPC.
2166
2060
At the moment most operations are mapped down to simple file operations.
2169
2063
def __init__(self, remote_bzrdir, remote_repository, real_branch=None,
2170
_client=None, format=None, setup_stacking=True, name=None):
2064
_client=None, format=None, setup_stacking=True):
2171
2065
"""Create a RemoteBranch instance.
2173
2067
:param real_branch: An optional local implementation of the branch
2277
2168
'to use vfs implementation')
2278
2169
self.bzrdir._ensure_real()
2279
2170
self._real_branch = self.bzrdir._real_bzrdir.open_branch(
2280
ignore_fallbacks=self._real_ignore_fallbacks, name=self._name)
2171
ignore_fallbacks=self._real_ignore_fallbacks)
2281
2172
if self.repository._real_repository is None:
2282
2173
# Give the remote repository the matching real repo.
2283
2174
real_repo = self._real_branch.repository
2398
2288
self._vfs_set_tags_bytes(bytes)
2400
2290
def lock_read(self):
2401
"""Lock the branch for read operations.
2403
:return: A bzrlib.lock.LogicalLockResult.
2405
2291
self.repository.lock_read()
2406
2292
if not self._lock_mode:
2407
self._note_lock('r')
2408
2293
self._lock_mode = 'r'
2409
2294
self._lock_count = 1
2410
2295
if self._real_branch is not None:
2411
2296
self._real_branch.lock_read()
2413
2298
self._lock_count += 1
2414
return lock.LogicalLockResult(self.unlock)
2416
2300
def _remote_lock_write(self, token):
2417
2301
if token is None:
2418
2302
branch_token = repo_token = ''
2420
2304
branch_token = token
2421
repo_token = self.repository.lock_write().repository_token
2305
repo_token = self.repository.lock_write()
2422
2306
self.repository.unlock()
2423
2307
err_context = {'token': token}
2425
response = self._call(
2426
'Branch.lock_write', self._remote_path(), branch_token,
2427
repo_token or '', **err_context)
2428
except errors.LockContention, e:
2429
# The LockContention from the server doesn't have any
2430
# information about the lock_url. We re-raise LockContention
2431
# with valid lock_url.
2432
raise errors.LockContention('(remote lock)',
2433
self.repository.base.split('.bzr/')[0])
2308
response = self._call(
2309
'Branch.lock_write', self._remote_path(), branch_token,
2310
repo_token or '', **err_context)
2434
2311
if response[0] != 'ok':
2435
2312
raise errors.UnexpectedSmartServerResponse(response)
2436
2313
ok, branch_token, repo_token = response
2468
2344
self._lock_count += 1
2469
2345
# Re-lock the repository too.
2470
2346
self.repository.lock_write(self._repo_lock_token)
2471
return BranchWriteLockResult(self.unlock, self._lock_token or None)
2347
return self._lock_token or None
2473
2349
def _unlock(self, branch_token, repo_token):
2474
2350
err_context = {'token': str((branch_token, repo_token))}
2797
2671
medium = self._branch._client._medium
2798
2672
if medium._is_remote_before((1, 14)):
2799
2673
return self._vfs_set_option(value, name, section)
2800
if isinstance(value, dict):
2801
if medium._is_remote_before((2, 2)):
2802
return self._vfs_set_option(value, name, section)
2803
return self._set_config_option_dict(value, name, section)
2805
return self._set_config_option(value, name, section)
2807
def _set_config_option(self, value, name, section):
2809
2675
path = self._branch._remote_path()
2810
2676
response = self._branch._client.call('Branch.set_config_option',
2811
2677
path, self._branch._lock_token, self._branch._repo_lock_token,
2812
2678
value.encode('utf8'), name, section or '')
2813
2679
except errors.UnknownSmartMethod:
2814
medium = self._branch._client._medium
2815
2680
medium._remember_remote_is_before((1, 14))
2816
2681
return self._vfs_set_option(value, name, section)
2817
2682
if response != ():
2818
2683
raise errors.UnexpectedSmartServerResponse(response)
2820
def _serialize_option_dict(self, option_dict):
2822
for key, value in option_dict.items():
2823
if isinstance(key, unicode):
2824
key = key.encode('utf8')
2825
if isinstance(value, unicode):
2826
value = value.encode('utf8')
2827
utf8_dict[key] = value
2828
return bencode.bencode(utf8_dict)
2830
def _set_config_option_dict(self, value, name, section):
2832
path = self._branch._remote_path()
2833
serialised_dict = self._serialize_option_dict(value)
2834
response = self._branch._client.call(
2835
'Branch.set_config_option_dict',
2836
path, self._branch._lock_token, self._branch._repo_lock_token,
2837
serialised_dict, name, section or '')
2838
except errors.UnknownSmartMethod:
2839
medium = self._branch._client._medium
2840
medium._remember_remote_is_before((2, 2))
2841
return self._vfs_set_option(value, name, section)
2843
raise errors.UnexpectedSmartServerResponse(response)
2845
2685
def _real_object(self):
2846
2686
self._branch._ensure_real()
2847
2687
return self._branch._real_branch
2930
2770
'Missing key %r in context %r', key_err.args[0], context)
2933
if err.error_verb == 'IncompatibleRepositories':
2934
raise errors.IncompatibleRepositories(err.error_args[0],
2935
err.error_args[1], err.error_args[2])
2936
elif err.error_verb == 'NoSuchRevision':
2773
if err.error_verb == 'NoSuchRevision':
2937
2774
raise NoSuchRevision(find('branch'), err.error_args[0])
2938
2775
elif err.error_verb == 'nosuchrevision':
2939
2776
raise NoSuchRevision(find('repository'), err.error_args[0])
2940
elif err.error_verb == 'nobranch':
2941
if len(err.error_args) >= 1:
2942
extra = err.error_args[0]
2945
raise errors.NotBranchError(path=find('bzrdir').root_transport.base,
2777
elif err.error_tuple == ('nobranch',):
2778
raise errors.NotBranchError(path=find('bzrdir').root_transport.base)
2947
2779
elif err.error_verb == 'norepository':
2948
2780
raise errors.NoRepositoryPresent(find('bzrdir'))
2949
2781
elif err.error_verb == 'LockContention':