88
88
self._real_bzrdir = BzrDir.open_from_transport(
89
89
self.root_transport, _server_formats=False)
91
def cloning_metadir(self):
93
return self._real_bzrdir.cloning_metadir()
95
def _translate_error(self, err, **context):
96
_translate_error(err, bzrdir=self, **context)
91
98
def create_repository(self, shared=False):
92
99
self._ensure_real()
93
100
self._real_bzrdir.create_repository(shared=shared)
126
133
response = self._client.call('BzrDir.open_branch', path)
127
134
except errors.ErrorFromSmartServer, err:
128
if err.error_tuple == ('nobranch',):
129
raise errors.NotBranchError(path=self.root_transport.base)
135
self._translate_error(err)
131
136
if response[0] == 'ok':
132
137
if response[1] == '':
133
138
# branch at this location.
164
169
verb = 'BzrDir.find_repository'
165
170
response = self._client.call(verb, path)
166
171
except errors.ErrorFromSmartServer, err:
167
if err.error_verb == 'norepository':
168
raise errors.NoRepositoryPresent(self)
172
self._translate_error(err)
170
173
if response[0] != 'ok':
171
174
raise errors.UnexpectedSmartServerResponse(response)
172
175
if verb == 'BzrDir.find_repository':
181
184
format.supports_tree_reference = (response[3] == 'yes')
182
185
# No wire format to check this yet.
183
186
format.supports_external_lookups = (response[4] == 'yes')
187
# Used to support creating a real format instance when needed.
188
format._creating_bzrdir = self
184
189
return RemoteRepository(self, format)
186
191
raise errors.NoRepositoryPresent(self)
216
221
"""Upgrading of remote bzrdirs is not supported yet."""
219
def clone(self, url, revision_id=None, force_new_repo=False):
224
def clone(self, url, revision_id=None, force_new_repo=False,
225
preserve_stacking=False):
220
226
self._ensure_real()
221
227
return self._real_bzrdir.clone(url, revision_id=revision_id,
222
force_new_repo=force_new_repo)
228
force_new_repo=force_new_repo, preserve_stacking=preserve_stacking)
230
def get_config(self):
232
return self._real_bzrdir.get_config()
225
235
class RemoteRepositoryFormat(repository.RepositoryFormat):
238
_matchingbzrdir = RemoteBzrDirFormat
248
_matchingbzrdir = RemoteBzrDirFormat()
240
250
def initialize(self, a_bzrdir, shared=False):
241
251
if not isinstance(a_bzrdir, RemoteBzrDir):
242
raise AssertionError('%r is not a RemoteBzrDir' % (a_bzrdir,))
252
prior_repo = self._creating_bzrdir.open_repository()
253
prior_repo._ensure_real()
254
return prior_repo._real_repository._format.initialize(
255
a_bzrdir, shared=shared)
243
256
return a_bzrdir.create_repository(shared=shared)
245
258
def open(self, a_bzrdir):
308
321
self._reconcile_fixes_text_parents = False
309
322
self._reconcile_backsup_inventory = False
310
323
self.base = self.bzrdir.transport.base
324
# Additional places to query for data.
325
self._fallback_repositories = []
312
327
def __str__(self):
313
328
return "%s(%s)" % (self.__class__.__name__, self.base)
346
361
#self._real_repository = self.bzrdir._real_bzrdir.open_repository()
347
362
self._set_real_repository(self.bzrdir._real_bzrdir.open_repository())
364
def _translate_error(self, err, **context):
365
self.bzrdir._translate_error(err, repository=self, **context)
349
367
def find_text_key_references(self):
350
368
"""Find the text key references within the repository.
388
406
response = self._client.call_expecting_body(
389
407
'Repository.get_revision_graph', path, revision_id)
390
408
except errors.ErrorFromSmartServer, err:
391
if err.error_verb == 'nosuchrevision':
392
raise NoSuchRevision(self, revision_id)
409
self._translate_error(err)
394
410
response_tuple, response_handler = response
395
411
if response_tuple[0] != 'ok':
396
412
raise errors.UnexpectedSmartServerResponse(response_tuple)
526
542
response = self._client.call('Repository.lock_write', path, token)
527
543
except errors.ErrorFromSmartServer, err:
528
if err.error_verb == 'LockContention':
529
raise errors.LockContention('(remote lock)')
530
elif err.error_verb == 'UnlockableTransport':
531
raise errors.UnlockableTransport(self.bzrdir.root_transport)
532
elif err.error_verb == 'LockFailed':
533
raise errors.LockFailed(err.error_args[0], err.error_args[1])
544
self._translate_error(err, token=token)
536
546
if response[0] == 'ok':
537
547
ok, token = response
609
619
response = self._client.call('Repository.unlock', path, token)
610
620
except errors.ErrorFromSmartServer, err:
611
if err.error_verb == 'TokenMismatch':
612
raise errors.TokenMismatch(token, '(remote token)')
621
self._translate_error(err, token=token)
614
622
if response == ('ok',):
700
708
committer=committer, revprops=revprops, revision_id=revision_id)
711
def add_fallback_repository(self, repository):
712
"""Add a repository to use for looking up data not held locally.
714
:param repository: A repository.
716
if not self._format.supports_external_lookups:
717
raise errors.UnstackableRepositoryFormat(self._format, self.base)
718
# We need to accumulate additional repositories here, to pass them in
720
self._fallback_repositories.append(repository)
703
722
def add_inventory(self, revid, inv, parents):
704
723
self._ensure_real()
705
724
return self._real_repository.add_inventory(revid, inv, parents)
1265
1284
if self._lock_mode == 'r':
1266
1285
self._real_branch.lock_read()
1287
def _translate_error(self, err, **context):
1288
self.repository._translate_error(err, branch=self, **context)
1268
1290
def _clear_cached_state(self):
1269
1291
super(RemoteBranch, self)._clear_cached_state()
1270
1292
if self._real_branch is not None:
1301
1323
self._ensure_real()
1302
1324
return self._real_branch.get_physical_lock_status()
1326
def get_stacked_on_url(self):
1327
"""Get the URL this branch is stacked against.
1329
:raises NotStacked: If the branch is not stacked.
1330
:raises UnstackableBranchFormat: If the branch does not support
1332
:raises UnstackableRepositoryFormat: If the repository does not support
1336
return self._real_branch.get_stacked_on_url()
1304
1338
def lock_read(self):
1305
1339
if not self._lock_mode:
1306
1340
self._lock_mode = 'r'
1322
1356
response = self._client.call(
1323
1357
'Branch.lock_write', path, branch_token, repo_token or '')
1324
1358
except errors.ErrorFromSmartServer, err:
1325
if err.error_verb == 'LockContention':
1326
raise errors.LockContention('(remote lock)')
1327
elif err.error_verb == 'TokenMismatch':
1328
raise errors.TokenMismatch(token, '(remote token)')
1329
elif err.error_verb == 'UnlockableTransport':
1330
raise errors.UnlockableTransport(self.bzrdir.root_transport)
1331
elif err.error_verb == 'ReadOnlyError':
1332
raise errors.ReadOnlyError(self)
1333
elif err.error_verb == 'LockFailed':
1334
raise errors.LockFailed(err.error_args[0], err.error_args[1])
1359
self._translate_error(err, token=token)
1336
1360
if response[0] != 'ok':
1337
1361
raise errors.UnexpectedSmartServerResponse(response)
1338
1362
ok, branch_token, repo_token = response
1383
1407
response = self._client.call('Branch.unlock', path, branch_token,
1384
1408
repo_token or '')
1385
1409
except errors.ErrorFromSmartServer, err:
1386
if err.error_verb == 'TokenMismatch':
1387
raise errors.TokenMismatch(
1388
str((branch_token, repo_token)), '(remote tokens)')
1410
self._translate_error(err, token=str((branch_token, repo_token)))
1390
1411
if response == ('ok',):
1392
1413
raise errors.UnexpectedSmartServerResponse(response)
1462
1483
path, self._lock_token, self._repo_lock_token, revision_id,
1463
1484
int(allow_diverged), int(allow_overwrite_descendant))
1464
1485
except errors.ErrorFromSmartServer, err:
1465
if err.error_verb == 'NoSuchRevision':
1466
raise NoSuchRevision(self, revision_id)
1467
elif err.error_verb == 'Diverged':
1468
raise errors.DivergedBranches(self, other_branch)
1486
self._translate_error(err, other_branch=other_branch)
1470
1487
self._clear_cached_state()
1471
1488
if len(response) != 3 and response[0] != 'ok':
1472
1489
raise errors.UnexpectedSmartServerResponse(response)
1481
1498
response = self._client.call('Branch.set_last_revision',
1482
1499
path, self._lock_token, self._repo_lock_token, revision_id)
1483
1500
except errors.ErrorFromSmartServer, err:
1484
if err.error_verb == 'NoSuchRevision':
1485
raise NoSuchRevision(self, revision_id)
1501
self._translate_error(err)
1487
1502
if response != ('ok',):
1488
1503
raise errors.UnexpectedSmartServerResponse(response)
1507
1522
self._ensure_real()
1508
1523
return self._real_branch.set_parent(url)
1525
def set_stacked_on_url(self, stacked_location):
1526
"""Set the URL this branch is stacked against.
1528
:raises UnstackableBranchFormat: If the branch does not support
1530
:raises UnstackableRepositoryFormat: If the repository does not support
1534
return self._real_branch.set_stacked_on_url(stacked_location)
1510
1536
def sprout(self, to_bzrdir, revision_id=None):
1511
1537
# Like Branch.sprout, except that it sprouts a branch in the default
1512
1538
# format, because RemoteBranches can't be created at arbitrary URLs.
1551
1577
self._last_revision_info_cache = revno, revision_id
1553
1579
except errors.ErrorFromSmartServer, err:
1554
if err.error_verb == 'NoSuchRevision':
1555
raise NoSuchRevision(self, err.error_args[0])
1580
self._translate_error(err)
1557
1581
if response == ('ok',):
1558
1582
self._clear_cached_state()
1559
1583
self._last_revision_info_cache = revno, revision_id
1637
1661
for tarinfo in tar:
1638
1662
tar.extract(tarinfo, to_dir)
1665
def _translate_error(err, **context):
1666
"""Translate an ErrorFromSmartServer into a more useful error.
1668
Possible context keys:
1677
return context[name]
1678
except KeyError, keyErr:
1679
mutter('Missing key %r in context %r', keyErr.args[0], context)
1681
if err.error_verb == 'NoSuchRevision':
1682
raise NoSuchRevision(find('branch'), err.error_args[0])
1683
elif err.error_verb == 'nosuchrevision':
1684
raise NoSuchRevision(find('repository'), err.error_args[0])
1685
elif err.error_tuple == ('nobranch',):
1686
raise errors.NotBranchError(path=find('bzrdir').root_transport.base)
1687
elif err.error_verb == 'norepository':
1688
raise errors.NoRepositoryPresent(find('bzrdir'))
1689
elif err.error_verb == 'LockContention':
1690
raise errors.LockContention('(remote lock)')
1691
elif err.error_verb == 'UnlockableTransport':
1692
raise errors.UnlockableTransport(find('bzrdir').root_transport)
1693
elif err.error_verb == 'LockFailed':
1694
raise errors.LockFailed(err.error_args[0], err.error_args[1])
1695
elif err.error_verb == 'TokenMismatch':
1696
raise errors.TokenMismatch(find('token'), '(remote token)')
1697
elif err.error_verb == 'Diverged':
1698
raise errors.DivergedBranches(find('branch'), find('other_branch'))
1699
elif err.error_verb == 'TipChangeRejected':
1700
raise errors.TipChangeRejected(err.error_args[0].decode('utf8'))