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.
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'
625
549
return self._custom_format._fetch_reconcile
627
551
def get_format_description(self):
629
return 'Remote: ' + self._custom_format.get_format_description()
552
return 'bzr remote repository'
631
554
def __eq__(self, other):
632
555
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)
634
566
def network_name(self):
635
567
if self._network_name:
636
568
return self._network_name
922
842
parents_provider = self._make_parents_provider(other_repository)
923
843
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
845
def gather_stats(self, revid=None, committers=None):
935
846
"""See Repository.gather_stats()."""
936
847
path = self.bzrdir._path_for_remote_call(self._client)
1250
1148
# state, so always add a lock here. If a caller passes us a locked
1251
1149
# repository, they are responsible for unlocking it later.
1252
1150
repository.lock_read()
1253
self._check_fallback_repository(repository)
1254
1151
self._fallback_repositories.append(repository)
1255
1152
# If self._real_repository was parameterised already (e.g. because a
1256
1153
# _real_branch had its get_stacked_on_url method called), then the
1257
1154
# repository to be added may already be in the _real_repositories list.
1258
1155
if self._real_repository is not None:
1259
fallback_locations = [repo.user_url for repo in
1156
fallback_locations = [repo.bzrdir.root_transport.base for repo in
1260
1157
self._real_repository._fallback_repositories]
1261
if repository.user_url not in fallback_locations:
1158
if repository.bzrdir.root_transport.base not in fallback_locations:
1262
1159
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
1161
def add_inventory(self, revid, inv, parents):
1275
1162
self._ensure_real()
1276
1163
return self._real_repository.add_inventory(revid, inv, parents)
1278
1165
def add_inventory_by_delta(self, basis_revision_id, delta, new_revision_id,
1279
parents, basis_inv=None, propagate_caches=False):
1280
1167
self._ensure_real()
1281
1168
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)
1169
delta, new_revision_id, parents)
1285
1171
def add_revision(self, rev_id, rev, inv=None, config=None):
1286
1172
self._ensure_real()
1316
1202
return self._real_repository.make_working_trees()
1318
1204
def refresh_data(self):
1319
"""Re-read any data needed to synchronise with disk.
1205
"""Re-read any data needed to to synchronise with disk.
1321
1207
This method is intended to be called after another repository instance
1322
1208
(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.
1209
repository. It may not be called during a write group, but may be
1210
called at any other time.
1212
if self.is_in_write_group():
1213
raise errors.InternalBzrError(
1214
"May not refresh_data while in a write group.")
1329
1215
if self._real_repository is not None:
1330
1216
self._real_repository.refresh_data()
1792
1682
def insert_stream(self, stream, src_format, resume_tokens):
1793
1683
target = self.target_repo
1794
1684
target._unstacked_provider.missing_keys.clear()
1795
candidate_calls = [('Repository.insert_stream_1.19', (1, 19))]
1796
1685
if target._lock_token:
1797
candidate_calls.append(('Repository.insert_stream_locked', (1, 14)))
1798
lock_args = (target._lock_token or '',)
1686
verb = 'Repository.insert_stream_locked'
1687
extra_args = (target._lock_token or '',)
1688
required_version = (1, 14)
1800
candidate_calls.append(('Repository.insert_stream', (1, 13)))
1690
verb = 'Repository.insert_stream'
1692
required_version = (1, 13)
1802
1693
client = target._client
1803
1694
medium = client._medium
1695
if medium._is_remote_before(required_version):
1696
# No possible way this can work.
1697
return self._insert_real(stream, src_format, resume_tokens)
1804
1698
path = target.bzrdir._path_for_remote_call(client)
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.
1699
if not resume_tokens:
1700
# XXX: Ugly but important for correctness, *will* be fixed during
1701
# 1.13 cycle. Pushing a stream that is interrupted results in a
1702
# fallback to the _real_repositories sink *with a partial stream*.
1703
# Thats bad because we insert less data than bzr expected. To avoid
1704
# this we do a trial push to make sure the verb is accessible, and
1705
# do not fallback when actually pushing the stream. A cleanup patch
1706
# is going to look at rewinding/restarting the stream/partial
1818
1708
byte_stream = smart_repo._stream_to_byte_stream([], src_format)
1820
1710
response = client.call_with_body_stream(
1821
(verb, path, '') + lock_args, byte_stream)
1711
(verb, path, '') + extra_args, byte_stream)
1822
1712
except errors.UnknownSmartMethod:
1823
1713
medium._remember_remote_is_before(required_version)
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)
1714
return self._insert_real(stream, src_format, resume_tokens)
1838
1715
byte_stream = smart_repo._stream_to_byte_stream(
1839
1716
stream, src_format)
1840
1717
resume_tokens = ' '.join(resume_tokens)
1841
1718
response = client.call_with_body_stream(
1842
(verb, path, resume_tokens) + lock_args, byte_stream)
1719
(verb, path, resume_tokens) + extra_args, byte_stream)
1843
1720
if response[0][0] not in ('ok', 'missing-basis'):
1844
1721
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)
1851
1722
if response[0][0] == 'missing-basis':
1852
1723
tokens, missing_keys = bencode.bdecode_as_tuple(response[0][1])
1853
1724
resume_tokens = tokens
1856
1727
self.target_repo.refresh_data()
1857
1728
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
1900
1731
class RemoteStreamSource(repository.StreamSource):
1901
1732
"""Stream data from a remote server."""
1957
1782
return self._real_stream(repo, search)
1958
1783
client = repo._client
1959
1784
medium = client._medium
1785
if medium._is_remote_before((1, 13)):
1786
# streaming was added in 1.13
1787
return self._real_stream(repo, search)
1960
1788
path = repo.bzrdir._path_for_remote_call(client)
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
1790
search_bytes = repo._serialise_search_result(search)
1791
response = repo._call_with_body_bytes_expecting_body(
1792
'Repository.get_stream',
1793
(path, self.to_format.network_name()), search_bytes)
1794
response_tuple, response_handler = response
1795
except errors.UnknownSmartMethod:
1796
medium._remember_remote_is_before((1,13))
1980
1797
return self._real_stream(repo, search)
1981
1798
if response_tuple[0] != 'ok':
1982
1799
raise errors.UnexpectedSmartServerResponse(response_tuple)
1983
1800
byte_stream = response_handler.read_streamed_body()
1984
src_format, stream = smart_repo._byte_stream_to_stream(byte_stream,
1985
self._record_counter)
1801
src_format, stream = smart_repo._byte_stream_to_stream(byte_stream)
1986
1802
if src_format.network_name() != repo._format.network_name():
1987
1803
raise AssertionError(
1988
1804
"Mismatched RemoteRepository and stream src %r, %r" % (
2064
1879
self._network_name)
2066
1881
def get_format_description(self):
2068
return 'Remote: ' + self._custom_format.get_format_description()
1882
return 'Remote BZR Branch'
2070
1884
def network_name(self):
2071
1885
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)
1887
def open(self, a_bzrdir, ignore_fallbacks=False):
1888
return a_bzrdir.open_branch(ignore_fallbacks=ignore_fallbacks)
2077
def _vfs_initialize(self, a_bzrdir, name):
1890
def _vfs_initialize(self, a_bzrdir):
2078
1891
# Initialisation when using a local bzrdir object, or a non-vfs init
2079
1892
# method is not available on the server.
2080
1893
# self._custom_format is always set - the start of initialize ensures
2082
1895
if isinstance(a_bzrdir, RemoteBzrDir):
2083
1896
a_bzrdir._ensure_real()
2084
result = self._custom_format.initialize(a_bzrdir._real_bzrdir,
1897
result = self._custom_format.initialize(a_bzrdir._real_bzrdir)
2087
1899
# We assume the bzrdir is parameterised; it may not be.
2088
result = self._custom_format.initialize(a_bzrdir, name)
1900
result = self._custom_format.initialize(a_bzrdir)
2089
1901
if (isinstance(a_bzrdir, RemoteBzrDir) and
2090
1902
not isinstance(result, RemoteBranch)):
2091
result = RemoteBranch(a_bzrdir, a_bzrdir.find_repository(), result,
1903
result = RemoteBranch(a_bzrdir, a_bzrdir.find_repository(), result)
2095
def initialize(self, a_bzrdir, name=None):
1906
def initialize(self, a_bzrdir):
2096
1907
# 1) get the network name to use.
2097
1908
if self._custom_format:
2098
1909
network_name = self._custom_format.network_name()
2104
1915
network_name = reference_format.network_name()
2105
1916
# Being asked to create on a non RemoteBzrDir:
2106
1917
if not isinstance(a_bzrdir, RemoteBzrDir):
2107
return self._vfs_initialize(a_bzrdir, name=name)
1918
return self._vfs_initialize(a_bzrdir)
2108
1919
medium = a_bzrdir._client._medium
2109
1920
if medium._is_remote_before((1, 13)):
2110
return self._vfs_initialize(a_bzrdir, name=name)
1921
return self._vfs_initialize(a_bzrdir)
2111
1922
# Creating on a remote bzr dir.
2112
1923
# 2) try direct creation via RPC
2113
1924
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
1925
verb = 'BzrDir.create_branch'
2119
1927
response = a_bzrdir._call(verb, path, network_name)
2120
1928
except errors.UnknownSmartMethod:
2121
1929
# Fallback - use vfs methods
2122
1930
medium._remember_remote_is_before((1, 13))
2123
return self._vfs_initialize(a_bzrdir, name=name)
1931
return self._vfs_initialize(a_bzrdir)
2124
1932
if response[0] != 'ok':
2125
1933
raise errors.UnexpectedSmartServerResponse(response)
2126
1934
# Turn the response into a RemoteRepository object.
2160
1968
return self._custom_format.supports_set_append_revisions_only()
2163
class RemoteBranch(branch.Branch, _RpcHelper, lock._RelockDebugMixin):
1971
class RemoteBranch(branch.Branch, _RpcHelper):
2164
1972
"""Branch stored on a server accessed by HPSS RPC.
2166
1974
At the moment most operations are mapped down to simple file operations.
2169
1977
def __init__(self, remote_bzrdir, remote_repository, real_branch=None,
2170
_client=None, format=None, setup_stacking=True, name=None):
1978
_client=None, format=None, setup_stacking=True):
2171
1979
"""Create a RemoteBranch instance.
2173
1981
:param real_branch: An optional local implementation of the branch
2398
2198
self._vfs_set_tags_bytes(bytes)
2400
2200
def lock_read(self):
2401
"""Lock the branch for read operations.
2403
:return: A bzrlib.lock.LogicalLockResult.
2405
2201
self.repository.lock_read()
2406
2202
if not self._lock_mode:
2407
self._note_lock('r')
2408
2203
self._lock_mode = 'r'
2409
2204
self._lock_count = 1
2410
2205
if self._real_branch is not None:
2411
2206
self._real_branch.lock_read()
2413
2208
self._lock_count += 1
2414
return lock.LogicalLockResult(self.unlock)
2416
2210
def _remote_lock_write(self, token):
2417
2211
if token is None:
2418
2212
branch_token = repo_token = ''
2420
2214
branch_token = token
2421
repo_token = self.repository.lock_write().repository_token
2215
repo_token = self.repository.lock_write()
2422
2216
self.repository.unlock()
2423
2217
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])
2218
response = self._call(
2219
'Branch.lock_write', self._remote_path(), branch_token,
2220
repo_token or '', **err_context)
2434
2221
if response[0] != 'ok':
2435
2222
raise errors.UnexpectedSmartServerResponse(response)
2436
2223
ok, branch_token, repo_token = response
2797
2581
medium = self._branch._client._medium
2798
2582
if medium._is_remote_before((1, 14)):
2799
2583
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
2585
path = self._branch._remote_path()
2810
2586
response = self._branch._client.call('Branch.set_config_option',
2811
2587
path, self._branch._lock_token, self._branch._repo_lock_token,
2812
2588
value.encode('utf8'), name, section or '')
2813
2589
except errors.UnknownSmartMethod:
2814
medium = self._branch._client._medium
2815
2590
medium._remember_remote_is_before((1, 14))
2816
2591
return self._vfs_set_option(value, name, section)
2817
2592
if response != ():
2818
2593
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
2595
def _real_object(self):
2846
2596
self._branch._ensure_real()
2847
2597
return self._branch._real_branch
2930
2680
'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':
2683
if err.error_verb == 'NoSuchRevision':
2937
2684
raise NoSuchRevision(find('branch'), err.error_args[0])
2938
2685
elif err.error_verb == 'nosuchrevision':
2939
2686
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,
2687
elif err.error_tuple == ('nobranch',):
2688
raise errors.NotBranchError(path=find('bzrdir').root_transport.base)
2947
2689
elif err.error_verb == 'norepository':
2948
2690
raise errors.NoRepositoryPresent(find('bzrdir'))
2949
2691
elif err.error_verb == 'LockContention':