108
113
self._client = client._SmartClient(medium)
110
115
self._client = _client
122
return '%s(%r)' % (self.__class__.__name__, self._client)
124
def _probe_bzrdir(self):
125
medium = self._client._medium
113
126
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):
114
152
response = self._call('BzrDir.open', path)
115
153
if response not in [('yes',), ('no',)]:
116
154
raise errors.UnexpectedSmartServerResponse(response)
117
155
if response == ('no',):
118
raise errors.NotBranchError(path=transport.base)
156
raise errors.NotBranchError(path=self.root_transport.base)
120
158
def _ensure_real(self):
121
159
"""Ensure that there is a _real_bzrdir set.
204
246
self._ensure_real()
205
247
self._real_bzrdir.destroy_repository()
207
def create_branch(self):
249
def create_branch(self, name=None):
208
250
# as per meta1 formats - just delegate to the format object which may
209
251
# be parameterised.
210
real_branch = self._format.get_branch_format().initialize(self)
252
real_branch = self._format.get_branch_format().initialize(self,
211
254
if not isinstance(real_branch, RemoteBranch):
212
result = RemoteBranch(self, self.find_repository(), real_branch)
255
result = RemoteBranch(self, self.find_repository(), real_branch,
214
258
result = real_branch
215
259
# BzrDir.clone_on_transport() uses the result of create_branch but does
221
265
self._next_open_branch_result = result
224
def destroy_branch(self):
268
def destroy_branch(self, name=None):
225
269
"""See BzrDir.destroy_branch"""
226
270
self._ensure_real()
227
self._real_bzrdir.destroy_branch()
271
self._real_bzrdir.destroy_branch(name=name)
228
272
self._next_open_branch_result = None
230
274
def create_workingtree(self, revision_id=None, from_branch=None):
231
275
raise errors.NotLocalUrl(self.transport.base)
233
def find_branch_format(self):
277
def find_branch_format(self, name=None):
234
278
"""Find the branch 'format' for this bzrdir.
236
280
This might be a synthetic object for e.g. RemoteBranch and SVN.
238
b = self.open_branch()
282
b = self.open_branch(name=name)
241
def get_branch_reference(self):
285
def get_branch_reference(self, name=None):
242
286
"""See BzrDir.get_branch_reference()."""
288
# XXX JRV20100304: Support opening colocated branches
289
raise errors.NoColocatedBranchSupport(self)
243
290
response = self._get_branch_reference()
244
291
if response[0] == 'ref':
245
292
return response[1]
249
296
def _get_branch_reference(self):
250
297
path = self._path_for_remote_call(self._client)
251
298
medium = self._client._medium
252
if not medium._is_remote_before((1, 13)):
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):
254
response = self._call('BzrDir.open_branchV2', path)
255
if response[0] not in ('ref', 'branch'):
256
raise errors.UnexpectedSmartServerResponse(response)
308
response = self._call(verb, path)
258
309
except errors.UnknownSmartMethod:
259
medium._remember_remote_is_before((1, 13))
260
response = self._call('BzrDir.open_branch', path)
261
if response[0] != 'ok':
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'):
262
323
raise errors.UnexpectedSmartServerResponse(response)
263
if response[1] != '':
264
return ('ref', response[1])
266
return ('branch', '')
268
def _get_tree_branch(self):
326
def _get_tree_branch(self, name=None):
269
327
"""See BzrDir._get_tree_branch()."""
270
return None, self.open_branch()
328
return None, self.open_branch(name=name)
272
def open_branch(self, _unsupported=False, ignore_fallbacks=False):
330
def open_branch(self, name=None, unsupported=False,
331
ignore_fallbacks=False):
274
333
raise NotImplementedError('unsupported flag support not implemented yet.')
275
334
if self._next_open_branch_result is not None:
276
335
# See create_branch for details.
281
340
if response[0] == 'ref':
282
341
# a branch reference, use the existing BranchReference logic.
283
342
format = BranchReferenceFormat()
284
return format.open(self, _found=True, location=response[1],
285
ignore_fallbacks=ignore_fallbacks)
343
return format.open(self, name=name, _found=True,
344
location=response[1], ignore_fallbacks=ignore_fallbacks)
286
345
branch_format_name = response[1]
287
346
if not branch_format_name:
288
347
branch_format_name = None
289
348
format = RemoteBranchFormat(network_name=branch_format_name)
290
349
return RemoteBranch(self, self.find_repository(), format=format,
291
setup_stacking=not ignore_fallbacks)
350
setup_stacking=not ignore_fallbacks, name=name)
293
352
def _open_repo_v1(self, path):
294
353
verb = 'BzrDir.find_repository'
549
625
return self._custom_format._fetch_reconcile
551
627
def get_format_description(self):
552
return 'bzr remote repository'
629
return 'Remote: ' + self._custom_format.get_format_description()
554
631
def __eq__(self, other):
555
632
return self.__class__ is other.__class__
557
def check_conversion_target(self, target_format):
558
if self.rich_root_data and not target_format.rich_root_data:
559
raise errors.BadConversionTarget(
560
'Does not support rich root data.', target_format)
561
if (self.supports_tree_reference and
562
not getattr(target_format, 'supports_tree_reference', False)):
563
raise errors.BadConversionTarget(
564
'Does not support nested trees', target_format)
566
634
def network_name(self):
567
635
if self._network_name:
568
636
return self._network_name
842
922
parents_provider = self._make_parents_provider(other_repository)
843
923
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)
845
934
def gather_stats(self, revid=None, committers=None):
846
935
"""See Repository.gather_stats()."""
847
936
path = self.bzrdir._path_for_remote_call(self._client)
1148
1250
# state, so always add a lock here. If a caller passes us a locked
1149
1251
# repository, they are responsible for unlocking it later.
1150
1252
repository.lock_read()
1253
self._check_fallback_repository(repository)
1151
1254
self._fallback_repositories.append(repository)
1152
1255
# If self._real_repository was parameterised already (e.g. because a
1153
1256
# _real_branch had its get_stacked_on_url method called), then the
1154
1257
# repository to be added may already be in the _real_repositories list.
1155
1258
if self._real_repository is not None:
1156
fallback_locations = [repo.bzrdir.root_transport.base for repo in
1259
fallback_locations = [repo.user_url for repo in
1157
1260
self._real_repository._fallback_repositories]
1158
if repository.bzrdir.root_transport.base not in fallback_locations:
1261
if repository.user_url not in fallback_locations:
1159
1262
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(
1161
1274
def add_inventory(self, revid, inv, parents):
1162
1275
self._ensure_real()
1163
1276
return self._real_repository.add_inventory(revid, inv, parents)
1165
1278
def add_inventory_by_delta(self, basis_revision_id, delta, new_revision_id,
1279
parents, basis_inv=None, propagate_caches=False):
1167
1280
self._ensure_real()
1168
1281
return self._real_repository.add_inventory_by_delta(basis_revision_id,
1169
delta, new_revision_id, parents)
1282
delta, new_revision_id, parents, basis_inv=basis_inv,
1283
propagate_caches=propagate_caches)
1171
1285
def add_revision(self, rev_id, rev, inv=None, config=None):
1172
1286
self._ensure_real()
1202
1316
return self._real_repository.make_working_trees()
1204
1318
def refresh_data(self):
1205
"""Re-read any data needed to to synchronise with disk.
1319
"""Re-read any data needed to synchronise with disk.
1207
1321
This method is intended to be called after another repository instance
1208
1322
(such as one used by a smart server) has inserted data into the
1209
repository. It may not be called during a write group, but may be
1210
called at any other time.
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.
1212
if self.is_in_write_group():
1213
raise errors.InternalBzrError(
1214
"May not refresh_data while in a write group.")
1215
1329
if self._real_repository is not None:
1216
1330
self._real_repository.refresh_data()
1680
1792
def insert_stream(self, stream, src_format, resume_tokens):
1681
1793
target = self.target_repo
1682
1794
target._unstacked_provider.missing_keys.clear()
1795
candidate_calls = [('Repository.insert_stream_1.19', (1, 19))]
1683
1796
if target._lock_token:
1684
verb = 'Repository.insert_stream_locked'
1685
extra_args = (target._lock_token or '',)
1686
required_version = (1, 14)
1797
candidate_calls.append(('Repository.insert_stream_locked', (1, 14)))
1798
lock_args = (target._lock_token or '',)
1688
verb = 'Repository.insert_stream'
1690
required_version = (1, 13)
1800
candidate_calls.append(('Repository.insert_stream', (1, 13)))
1691
1802
client = target._client
1692
1803
medium = client._medium
1693
if medium._is_remote_before(required_version):
1694
# No possible way this can work.
1695
return self._insert_real(stream, src_format, resume_tokens)
1696
1804
path = target.bzrdir._path_for_remote_call(client)
1697
if not resume_tokens:
1698
# XXX: Ugly but important for correctness, *will* be fixed during
1699
# 1.13 cycle. Pushing a stream that is interrupted results in a
1700
# fallback to the _real_repositories sink *with a partial stream*.
1701
# Thats bad because we insert less data than bzr expected. To avoid
1702
# this we do a trial push to make sure the verb is accessible, and
1703
# do not fallback when actually pushing the stream. A cleanup patch
1704
# is going to look at rewinding/restarting the stream/partial
1805
# Probe for the verb to use with an empty stream before sending the
1806
# real stream to it. We do this both to avoid the risk of sending a
1807
# large request that is then rejected, and because we don't want to
1808
# implement a way to buffer, rewind, or restart the stream.
1810
for verb, required_version in candidate_calls:
1811
if medium._is_remote_before(required_version):
1814
# We've already done the probing (and set _is_remote_before) on
1815
# a previous insert.
1706
1818
byte_stream = smart_repo._stream_to_byte_stream([], src_format)
1708
1820
response = client.call_with_body_stream(
1709
(verb, path, '') + extra_args, byte_stream)
1821
(verb, path, '') + lock_args, byte_stream)
1710
1822
except errors.UnknownSmartMethod:
1711
1823
medium._remember_remote_is_before(required_version)
1712
return self._insert_real(stream, src_format, resume_tokens)
1829
return self._insert_real(stream, src_format, resume_tokens)
1830
self._last_inv_record = None
1831
self._last_substream = None
1832
if required_version < (1, 19):
1833
# Remote side doesn't support inventory deltas. Wrap the stream to
1834
# make sure we don't send any. If the stream contains inventory
1835
# deltas we'll interrupt the smart insert_stream request and
1837
stream = self._stop_stream_if_inventory_delta(stream)
1713
1838
byte_stream = smart_repo._stream_to_byte_stream(
1714
1839
stream, src_format)
1715
1840
resume_tokens = ' '.join(resume_tokens)
1716
1841
response = client.call_with_body_stream(
1717
(verb, path, resume_tokens) + extra_args, byte_stream)
1842
(verb, path, resume_tokens) + lock_args, byte_stream)
1718
1843
if response[0][0] not in ('ok', 'missing-basis'):
1719
1844
raise errors.UnexpectedSmartServerResponse(response)
1845
if self._last_substream is not None:
1846
# The stream included an inventory-delta record, but the remote
1847
# side isn't new enough to support them. So we need to send the
1848
# rest of the stream via VFS.
1849
self.target_repo.refresh_data()
1850
return self._resume_stream_with_vfs(response, src_format)
1720
1851
if response[0][0] == 'missing-basis':
1721
1852
tokens, missing_keys = bencode.bdecode_as_tuple(response[0][1])
1722
1853
resume_tokens = tokens
1725
1856
self.target_repo.refresh_data()
1726
1857
return [], set()
1859
def _resume_stream_with_vfs(self, response, src_format):
1860
"""Resume sending a stream via VFS, first resending the record and
1861
substream that couldn't be sent via an insert_stream verb.
1863
if response[0][0] == 'missing-basis':
1864
tokens, missing_keys = bencode.bdecode_as_tuple(response[0][1])
1865
# Ignore missing_keys, we haven't finished inserting yet
1868
def resume_substream():
1869
# Yield the substream that was interrupted.
1870
for record in self._last_substream:
1872
self._last_substream = None
1873
def resume_stream():
1874
# Finish sending the interrupted substream
1875
yield ('inventory-deltas', resume_substream())
1876
# Then simply continue sending the rest of the stream.
1877
for substream_kind, substream in self._last_stream:
1878
yield substream_kind, substream
1879
return self._insert_real(resume_stream(), src_format, tokens)
1881
def _stop_stream_if_inventory_delta(self, stream):
1882
"""Normally this just lets the original stream pass-through unchanged.
1884
However if any 'inventory-deltas' substream occurs it will stop
1885
streaming, and store the interrupted substream and stream in
1886
self._last_substream and self._last_stream so that the stream can be
1887
resumed by _resume_stream_with_vfs.
1890
stream_iter = iter(stream)
1891
for substream_kind, substream in stream_iter:
1892
if substream_kind == 'inventory-deltas':
1893
self._last_substream = substream
1894
self._last_stream = stream_iter
1897
yield substream_kind, substream
1729
1900
class RemoteStreamSource(repository.StreamSource):
1730
1901
"""Stream data from a remote server."""
1733
1904
if (self.from_repository._fallback_repositories and
1734
1905
self.to_format._fetch_order == 'topological'):
1735
1906
return self._real_stream(self.from_repository, search)
1736
return self.missing_parents_chain(search, [self.from_repository] +
1737
self.from_repository._fallback_repositories)
1909
repos = [self.from_repository]
1915
repos.extend(repo._fallback_repositories)
1916
sources.append(repo)
1917
return self.missing_parents_chain(search, sources)
1919
def get_stream_for_missing_keys(self, missing_keys):
1920
self.from_repository._ensure_real()
1921
real_repo = self.from_repository._real_repository
1922
real_source = real_repo._get_source(self.to_format)
1923
return real_source.get_stream_for_missing_keys(missing_keys)
1739
1925
def _real_stream(self, repo, search):
1740
1926
"""Get a stream for search from repo.
1770
1957
return self._real_stream(repo, search)
1771
1958
client = repo._client
1772
1959
medium = client._medium
1773
if medium._is_remote_before((1, 13)):
1774
# streaming was added in 1.13
1775
return self._real_stream(repo, search)
1776
1960
path = repo.bzrdir._path_for_remote_call(client)
1778
search_bytes = repo._serialise_search_result(search)
1779
response = repo._call_with_body_bytes_expecting_body(
1780
'Repository.get_stream',
1781
(path, self.to_format.network_name()), search_bytes)
1782
response_tuple, response_handler = response
1783
except errors.UnknownSmartMethod:
1784
medium._remember_remote_is_before((1,13))
1961
search_bytes = repo._serialise_search_result(search)
1962
args = (path, self.to_format.network_name())
1964
('Repository.get_stream_1.19', (1, 19)),
1965
('Repository.get_stream', (1, 13))]
1967
for verb, version in candidate_verbs:
1968
if medium._is_remote_before(version):
1971
response = repo._call_with_body_bytes_expecting_body(
1972
verb, args, search_bytes)
1973
except errors.UnknownSmartMethod:
1974
medium._remember_remote_is_before(version)
1976
response_tuple, response_handler = response
1785
1980
return self._real_stream(repo, search)
1786
1981
if response_tuple[0] != 'ok':
1787
1982
raise errors.UnexpectedSmartServerResponse(response_tuple)
1788
1983
byte_stream = response_handler.read_streamed_body()
1789
src_format, stream = smart_repo._byte_stream_to_stream(byte_stream)
1984
src_format, stream = smart_repo._byte_stream_to_stream(byte_stream,
1985
self._record_counter)
1790
1986
if src_format.network_name() != repo._format.network_name():
1791
1987
raise AssertionError(
1792
1988
"Mismatched RemoteRepository and stream src %r, %r" % (
1867
2064
self._network_name)
1869
2066
def get_format_description(self):
1870
return 'Remote BZR Branch'
2068
return 'Remote: ' + self._custom_format.get_format_description()
1872
2070
def network_name(self):
1873
2071
return self._network_name
1875
def open(self, a_bzrdir, ignore_fallbacks=False):
1876
return a_bzrdir.open_branch(ignore_fallbacks=ignore_fallbacks)
2073
def open(self, a_bzrdir, name=None, ignore_fallbacks=False):
2074
return a_bzrdir.open_branch(name=name,
2075
ignore_fallbacks=ignore_fallbacks)
1878
def _vfs_initialize(self, a_bzrdir):
2077
def _vfs_initialize(self, a_bzrdir, name):
1879
2078
# Initialisation when using a local bzrdir object, or a non-vfs init
1880
2079
# method is not available on the server.
1881
2080
# self._custom_format is always set - the start of initialize ensures
1883
2082
if isinstance(a_bzrdir, RemoteBzrDir):
1884
2083
a_bzrdir._ensure_real()
1885
result = self._custom_format.initialize(a_bzrdir._real_bzrdir)
2084
result = self._custom_format.initialize(a_bzrdir._real_bzrdir,
1887
2087
# We assume the bzrdir is parameterised; it may not be.
1888
result = self._custom_format.initialize(a_bzrdir)
2088
result = self._custom_format.initialize(a_bzrdir, name)
1889
2089
if (isinstance(a_bzrdir, RemoteBzrDir) and
1890
2090
not isinstance(result, RemoteBranch)):
1891
result = RemoteBranch(a_bzrdir, a_bzrdir.find_repository(), result)
2091
result = RemoteBranch(a_bzrdir, a_bzrdir.find_repository(), result,
1894
def initialize(self, a_bzrdir):
2095
def initialize(self, a_bzrdir, name=None):
1895
2096
# 1) get the network name to use.
1896
2097
if self._custom_format:
1897
2098
network_name = self._custom_format.network_name()
1903
2104
network_name = reference_format.network_name()
1904
2105
# Being asked to create on a non RemoteBzrDir:
1905
2106
if not isinstance(a_bzrdir, RemoteBzrDir):
1906
return self._vfs_initialize(a_bzrdir)
2107
return self._vfs_initialize(a_bzrdir, name=name)
1907
2108
medium = a_bzrdir._client._medium
1908
2109
if medium._is_remote_before((1, 13)):
1909
return self._vfs_initialize(a_bzrdir)
2110
return self._vfs_initialize(a_bzrdir, name=name)
1910
2111
# Creating on a remote bzr dir.
1911
2112
# 2) try direct creation via RPC
1912
2113
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)
1913
2117
verb = 'BzrDir.create_branch'
1915
2119
response = a_bzrdir._call(verb, path, network_name)
1916
2120
except errors.UnknownSmartMethod:
1917
2121
# Fallback - use vfs methods
1918
2122
medium._remember_remote_is_before((1, 13))
1919
return self._vfs_initialize(a_bzrdir)
2123
return self._vfs_initialize(a_bzrdir, name=name)
1920
2124
if response[0] != 'ok':
1921
2125
raise errors.UnexpectedSmartServerResponse(response)
1922
2126
# Turn the response into a RemoteRepository object.
1956
2160
return self._custom_format.supports_set_append_revisions_only()
1959
class RemoteBranch(branch.Branch, _RpcHelper):
2163
class RemoteBranch(branch.Branch, _RpcHelper, lock._RelockDebugMixin):
1960
2164
"""Branch stored on a server accessed by HPSS RPC.
1962
2166
At the moment most operations are mapped down to simple file operations.
1965
2169
def __init__(self, remote_bzrdir, remote_repository, real_branch=None,
1966
_client=None, format=None, setup_stacking=True):
2170
_client=None, format=None, setup_stacking=True, name=None):
1967
2171
"""Create a RemoteBranch instance.
1969
2173
:param real_branch: An optional local implementation of the branch
2186
2398
self._vfs_set_tags_bytes(bytes)
2188
2400
def lock_read(self):
2401
"""Lock the branch for read operations.
2403
:return: A bzrlib.lock.LogicalLockResult.
2189
2405
self.repository.lock_read()
2190
2406
if not self._lock_mode:
2407
self._note_lock('r')
2191
2408
self._lock_mode = 'r'
2192
2409
self._lock_count = 1
2193
2410
if self._real_branch is not None:
2194
2411
self._real_branch.lock_read()
2196
2413
self._lock_count += 1
2414
return lock.LogicalLockResult(self.unlock)
2198
2416
def _remote_lock_write(self, token):
2199
2417
if token is None:
2200
2418
branch_token = repo_token = ''
2202
2420
branch_token = token
2203
repo_token = self.repository.lock_write()
2421
repo_token = self.repository.lock_write().repository_token
2204
2422
self.repository.unlock()
2205
2423
err_context = {'token': token}
2206
response = self._call(
2207
'Branch.lock_write', self._remote_path(), branch_token,
2208
repo_token or '', **err_context)
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])
2209
2434
if response[0] != 'ok':
2210
2435
raise errors.UnexpectedSmartServerResponse(response)
2211
2436
ok, branch_token, repo_token = response
2569
2797
medium = self._branch._client._medium
2570
2798
if medium._is_remote_before((1, 14)):
2571
2799
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):
2573
2809
path = self._branch._remote_path()
2574
2810
response = self._branch._client.call('Branch.set_config_option',
2575
2811
path, self._branch._lock_token, self._branch._repo_lock_token,
2576
2812
value.encode('utf8'), name, section or '')
2577
2813
except errors.UnknownSmartMethod:
2814
medium = self._branch._client._medium
2578
2815
medium._remember_remote_is_before((1, 14))
2579
2816
return self._vfs_set_option(value, name, section)
2580
2817
if response != ():
2581
2818
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)
2583
2845
def _real_object(self):
2584
2846
self._branch._ensure_real()
2585
2847
return self._branch._real_branch
2668
2930
'Missing key %r in context %r', key_err.args[0], context)
2671
if err.error_verb == 'NoSuchRevision':
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':
2672
2937
raise NoSuchRevision(find('branch'), err.error_args[0])
2673
2938
elif err.error_verb == 'nosuchrevision':
2674
2939
raise NoSuchRevision(find('repository'), err.error_args[0])
2675
elif err.error_tuple == ('nobranch',):
2676
raise errors.NotBranchError(path=find('bzrdir').root_transport.base)
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,
2677
2947
elif err.error_verb == 'norepository':
2678
2948
raise errors.NoRepositoryPresent(find('bzrdir'))
2679
2949
elif err.error_verb == 'LockContention':