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
36
from bzrlib.decorators import needs_read_lock, needs_write_lock, only_raises
39
37
from bzrlib.errors import (
273
270
def create_workingtree(self, revision_id=None, from_branch=None):
274
271
raise errors.NotLocalUrl(self.transport.base)
276
def find_branch_format(self, name=None):
273
def find_branch_format(self):
277
274
"""Find the branch 'format' for this bzrdir.
279
276
This might be a synthetic object for e.g. RemoteBranch and SVN.
281
b = self.open_branch(name=name)
278
b = self.open_branch()
284
def get_branch_reference(self, name=None):
281
def get_branch_reference(self):
285
282
"""See BzrDir.get_branch_reference()."""
287
# XXX JRV20100304: Support opening colocated branches
288
raise errors.NoColocatedBranchSupport(self)
289
283
response = self._get_branch_reference()
290
284
if response[0] == 'ref':
291
285
return response[1]
322
316
raise errors.UnexpectedSmartServerResponse(response)
325
def _get_tree_branch(self, name=None):
319
def _get_tree_branch(self):
326
320
"""See BzrDir._get_tree_branch()."""
327
return None, self.open_branch(name=name)
321
return None, self.open_branch()
329
323
def open_branch(self, name=None, unsupported=False,
330
324
ignore_fallbacks=False):
697
690
# Additional places to query for data.
698
691
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
693
def __str__(self):
712
694
return "%s(%s)" % (self.__class__.__name__, self.base)
899
881
def _has_same_fallbacks(self, other_repo):
900
882
"""Returns true if the repositories have the same fallbacks."""
901
883
# XXX: copied from Repository; it should be unified into a base class
902
# <https://bugs.launchpad.net/bzr/+bug/401622>
884
# <https://bugs.edge.launchpad.net/bzr/+bug/401622>
903
885
my_fb = self._fallback_repositories
904
886
other_fb = other_repo._fallback_repositories
905
887
if len(my_fb) != len(other_fb):
921
903
parents_provider = self._make_parents_provider(other_repository)
922
904
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
906
def gather_stats(self, revid=None, committers=None):
934
907
"""See Repository.gather_stats()."""
935
908
path = self.bzrdir._path_for_remote_call(self._client)
1249
1217
# state, so always add a lock here. If a caller passes us a locked
1250
1218
# repository, they are responsible for unlocking it later.
1251
1219
repository.lock_read()
1252
self._check_fallback_repository(repository)
1253
1220
self._fallback_repositories.append(repository)
1254
1221
# If self._real_repository was parameterised already (e.g. because a
1255
1222
# _real_branch had its get_stacked_on_url method called), then the
1256
1223
# repository to be added may already be in the _real_repositories list.
1257
1224
if self._real_repository is not None:
1258
fallback_locations = [repo.user_url for repo in
1225
fallback_locations = [repo.bzrdir.root_transport.base for repo in
1259
1226
self._real_repository._fallback_repositories]
1260
if repository.user_url not in fallback_locations:
1227
if repository.bzrdir.root_transport.base not in fallback_locations:
1261
1228
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
1230
def add_inventory(self, revid, inv, parents):
1274
1231
self._ensure_real()
1275
1232
return self._real_repository.add_inventory(revid, inv, parents)
1315
1272
return self._real_repository.make_working_trees()
1317
1274
def refresh_data(self):
1318
"""Re-read any data needed to synchronise with disk.
1275
"""Re-read any data needed to to synchronise with disk.
1320
1277
This method is intended to be called after another repository instance
1321
1278
(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.
1279
repository. It may not be called during a write group, but may be
1280
called at any other time.
1282
if self.is_in_write_group():
1283
raise errors.InternalBzrError(
1284
"May not refresh_data while in a write group.")
1328
1285
if self._real_repository is not None:
1329
1286
self._real_repository.refresh_data()
1628
1585
return self._real_repository.inventories
1630
1587
@needs_write_lock
1631
def pack(self, hint=None, clean_obsolete_packs=False):
1588
def pack(self, hint=None):
1632
1589
"""Compress the data within the repository.
1634
1591
This is not currently implemented within the smart server.
1636
1593
self._ensure_real()
1637
return self._real_repository.pack(hint=hint, clean_obsolete_packs=clean_obsolete_packs)
1594
return self._real_repository.pack(hint=hint)
1640
1597
def revisions(self):
1980
1937
if response_tuple[0] != 'ok':
1981
1938
raise errors.UnexpectedSmartServerResponse(response_tuple)
1982
1939
byte_stream = response_handler.read_streamed_body()
1983
src_format, stream = smart_repo._byte_stream_to_stream(byte_stream,
1984
self._record_counter)
1940
src_format, stream = smart_repo._byte_stream_to_stream(byte_stream)
1985
1941
if src_format.network_name() != repo._format.network_name():
1986
1942
raise AssertionError(
1987
1943
"Mismatched RemoteRepository and stream src %r, %r" % (
2410
2361
self._real_branch.lock_read()
2412
2363
self._lock_count += 1
2413
return lock.LogicalLockResult(self.unlock)
2415
2365
def _remote_lock_write(self, token):
2416
2366
if token is None:
2417
2367
branch_token = repo_token = ''
2419
2369
branch_token = token
2420
repo_token = self.repository.lock_write().repository_token
2370
repo_token = self.repository.lock_write()
2421
2371
self.repository.unlock()
2422
2372
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])
2373
response = self._call(
2374
'Branch.lock_write', self._remote_path(), branch_token,
2375
repo_token or '', **err_context)
2433
2376
if response[0] != 'ok':
2434
2377
raise errors.UnexpectedSmartServerResponse(response)
2435
2378
ok, branch_token, repo_token = response
2467
2410
self._lock_count += 1
2468
2411
# Re-lock the repository too.
2469
2412
self.repository.lock_write(self._repo_lock_token)
2470
return BranchWriteLockResult(self.unlock, self._lock_token or None)
2413
return self._lock_token or None
2472
2415
def _unlock(self, branch_token, repo_token):
2473
2416
err_context = {'token': str((branch_token, repo_token))}
2796
2739
medium = self._branch._client._medium
2797
2740
if medium._is_remote_before((1, 14)):
2798
2741
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
2743
path = self._branch._remote_path()
2809
2744
response = self._branch._client.call('Branch.set_config_option',
2810
2745
path, self._branch._lock_token, self._branch._repo_lock_token,
2811
2746
value.encode('utf8'), name, section or '')
2812
2747
except errors.UnknownSmartMethod:
2813
medium = self._branch._client._medium
2814
2748
medium._remember_remote_is_before((1, 14))
2815
2749
return self._vfs_set_option(value, name, section)
2816
2750
if response != ():
2817
2751
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
2753
def _real_object(self):
2845
2754
self._branch._ensure_real()
2846
2755
return self._branch._real_branch