32
33
revision as _mod_revision,
36
from bzrlib.branch import BranchReferenceFormat
38
from bzrlib.branch import BranchReferenceFormat, BranchWriteLockResult
37
39
from bzrlib.bzrdir import BzrDir, RemoteBzrDirFormat
38
40
from bzrlib.decorators import needs_read_lock, needs_write_lock, only_raises
39
41
from bzrlib.errors import (
244
247
self._ensure_real()
245
248
self._real_bzrdir.destroy_repository()
247
def create_branch(self, name=None):
250
def create_branch(self, name=None, repository=None):
248
251
# as per meta1 formats - just delegate to the format object which may
249
252
# be parameterised.
250
253
real_branch = self._format.get_branch_format().initialize(self,
254
name=name, repository=repository)
252
255
if not isinstance(real_branch, RemoteBranch):
253
result = RemoteBranch(self, self.find_repository(), real_branch,
256
if not isinstance(repository, RemoteRepository):
257
raise AssertionError(
258
'need a RemoteRepository to use with RemoteBranch, got %r'
260
result = RemoteBranch(self, repository, real_branch, name=name)
256
262
result = real_branch
257
263
# BzrDir.clone_on_transport() uses the result of create_branch but does
269
275
self._real_bzrdir.destroy_branch(name=name)
270
276
self._next_open_branch_result = None
272
def create_workingtree(self, revision_id=None, from_branch=None):
278
def create_workingtree(self, revision_id=None, from_branch=None,
279
accelerator_tree=None, hardlink=False):
273
280
raise errors.NotLocalUrl(self.transport.base)
275
def find_branch_format(self):
282
def find_branch_format(self, name=None):
276
283
"""Find the branch 'format' for this bzrdir.
278
285
This might be a synthetic object for e.g. RemoteBranch and SVN.
280
b = self.open_branch()
287
b = self.open_branch(name=name)
283
def get_branch_reference(self):
290
def get_branch_reference(self, name=None):
284
291
"""See BzrDir.get_branch_reference()."""
293
# XXX JRV20100304: Support opening colocated branches
294
raise errors.NoColocatedBranchSupport(self)
285
295
response = self._get_branch_reference()
286
296
if response[0] == 'ref':
287
297
return response[1]
318
328
raise errors.UnexpectedSmartServerResponse(response)
321
def _get_tree_branch(self):
331
def _get_tree_branch(self, name=None):
322
332
"""See BzrDir._get_tree_branch()."""
323
return None, self.open_branch()
333
return None, self.open_branch(name=name)
325
335
def open_branch(self, name=None, unsupported=False,
326
336
ignore_fallbacks=False):
895
905
def _has_same_fallbacks(self, other_repo):
896
906
"""Returns true if the repositories have the same fallbacks."""
897
907
# XXX: copied from Repository; it should be unified into a base class
898
# <https://bugs.edge.launchpad.net/bzr/+bug/401622>
908
# <https://bugs.launchpad.net/bzr/+bug/401622>
899
909
my_fb = self._fallback_repositories
900
910
other_fb = other_repo._fallback_repositories
901
911
if len(my_fb) != len(other_fb):
1306
1321
return self._real_repository.make_working_trees()
1308
1323
def refresh_data(self):
1309
"""Re-read any data needed to to synchronise with disk.
1324
"""Re-read any data needed to synchronise with disk.
1311
1326
This method is intended to be called after another repository instance
1312
1327
(such as one used by a smart server) has inserted data into the
1313
repository. It may not be called during a write group, but may be
1314
called at any other time.
1328
repository. On all repositories this will work outside of write groups.
1329
Some repository formats (pack and newer for bzrlib native formats)
1330
support refresh_data inside write groups. If called inside a write
1331
group on a repository that does not support refreshing in a write group
1332
IsInWriteGroupError will be raised.
1316
if self.is_in_write_group():
1317
raise errors.InternalBzrError(
1318
"May not refresh_data while in a write group.")
1319
1334
if self._real_repository is not None:
1320
1335
self._real_repository.refresh_data()
1971
1986
if response_tuple[0] != 'ok':
1972
1987
raise errors.UnexpectedSmartServerResponse(response_tuple)
1973
1988
byte_stream = response_handler.read_streamed_body()
1974
src_format, stream = smart_repo._byte_stream_to_stream(byte_stream)
1989
src_format, stream = smart_repo._byte_stream_to_stream(byte_stream,
1990
self._record_counter)
1975
1991
if src_format.network_name() != repo._format.network_name():
1976
1992
raise AssertionError(
1977
1993
"Mismatched RemoteRepository and stream src %r, %r" % (
2115
2131
# Turn the response into a RemoteRepository object.
2116
2132
format = RemoteBranchFormat(network_name=response[1])
2117
2133
repo_format = response_tuple_to_repo_format(response[3:])
2118
if response[2] == '':
2119
repo_bzrdir = a_bzrdir
2134
repo_path = response[2]
2135
if repository is not None:
2136
remote_repo_url = urlutils.join(medium.base, repo_path)
2137
url_diff = urlutils.relative_url(repository.user_url,
2140
raise AssertionError(
2141
'repository.user_url %r does not match URL from server '
2142
'response (%r + %r)'
2143
% (repository.user_url, medium.base, repo_path))
2144
remote_repo = repository
2121
repo_bzrdir = RemoteBzrDir(
2122
a_bzrdir.root_transport.clone(response[2]), a_bzrdir._format,
2124
remote_repo = RemoteRepository(repo_bzrdir, repo_format)
2147
repo_bzrdir = a_bzrdir
2149
repo_bzrdir = RemoteBzrDir(
2150
a_bzrdir.root_transport.clone(repo_path), a_bzrdir._format,
2152
remote_repo = RemoteRepository(repo_bzrdir, repo_format)
2125
2153
remote_branch = RemoteBranch(a_bzrdir, remote_repo,
2126
2154
format=format, setup_stacking=False, name=name)
2127
2155
# XXX: We know this is a new branch, so it must have revno 0, revid
2357
2385
self._ensure_real()
2358
2386
return self._real_branch._get_tags_bytes()
2360
2389
def _get_tags_bytes(self):
2390
if self._tags_bytes is None:
2391
self._tags_bytes = self._get_tags_bytes_via_hpss()
2392
return self._tags_bytes
2394
def _get_tags_bytes_via_hpss(self):
2361
2395
medium = self._client._medium
2362
2396
if medium._is_remote_before((1, 13)):
2363
2397
return self._vfs_get_tags_bytes()
2396
2436
self._real_branch.lock_read()
2398
2438
self._lock_count += 1
2439
return lock.LogicalLockResult(self.unlock)
2400
2441
def _remote_lock_write(self, token):
2401
2442
if token is None:
2402
2443
branch_token = repo_token = ''
2404
2445
branch_token = token
2405
repo_token = self.repository.lock_write()
2446
repo_token = self.repository.lock_write().repository_token
2406
2447
self.repository.unlock()
2407
2448
err_context = {'token': token}
2408
response = self._call(
2409
'Branch.lock_write', self._remote_path(), branch_token,
2410
repo_token or '', **err_context)
2450
response = self._call(
2451
'Branch.lock_write', self._remote_path(), branch_token,
2452
repo_token or '', **err_context)
2453
except errors.LockContention, e:
2454
# The LockContention from the server doesn't have any
2455
# information about the lock_url. We re-raise LockContention
2456
# with valid lock_url.
2457
raise errors.LockContention('(remote lock)',
2458
self.repository.base.split('.bzr/')[0])
2411
2459
if response[0] != 'ok':
2412
2460
raise errors.UnexpectedSmartServerResponse(response)
2413
2461
ok, branch_token, repo_token = response
2445
2493
self._lock_count += 1
2446
2494
# Re-lock the repository too.
2447
2495
self.repository.lock_write(self._repo_lock_token)
2448
return self._lock_token or None
2496
return BranchWriteLockResult(self.unlock, self._lock_token or None)
2450
2498
def _unlock(self, branch_token, repo_token):
2451
2499
err_context = {'token': str((branch_token, repo_token))}
2774
2822
medium = self._branch._client._medium
2775
2823
if medium._is_remote_before((1, 14)):
2776
2824
return self._vfs_set_option(value, name, section)
2825
if isinstance(value, dict):
2826
if medium._is_remote_before((2, 2)):
2827
return self._vfs_set_option(value, name, section)
2828
return self._set_config_option_dict(value, name, section)
2830
return self._set_config_option(value, name, section)
2832
def _set_config_option(self, value, name, section):
2778
2834
path = self._branch._remote_path()
2779
2835
response = self._branch._client.call('Branch.set_config_option',
2780
2836
path, self._branch._lock_token, self._branch._repo_lock_token,
2781
2837
value.encode('utf8'), name, section or '')
2782
2838
except errors.UnknownSmartMethod:
2839
medium = self._branch._client._medium
2783
2840
medium._remember_remote_is_before((1, 14))
2784
2841
return self._vfs_set_option(value, name, section)
2785
2842
if response != ():
2786
2843
raise errors.UnexpectedSmartServerResponse(response)
2845
def _serialize_option_dict(self, option_dict):
2847
for key, value in option_dict.items():
2848
if isinstance(key, unicode):
2849
key = key.encode('utf8')
2850
if isinstance(value, unicode):
2851
value = value.encode('utf8')
2852
utf8_dict[key] = value
2853
return bencode.bencode(utf8_dict)
2855
def _set_config_option_dict(self, value, name, section):
2857
path = self._branch._remote_path()
2858
serialised_dict = self._serialize_option_dict(value)
2859
response = self._branch._client.call(
2860
'Branch.set_config_option_dict',
2861
path, self._branch._lock_token, self._branch._repo_lock_token,
2862
serialised_dict, name, section or '')
2863
except errors.UnknownSmartMethod:
2864
medium = self._branch._client._medium
2865
medium._remember_remote_is_before((2, 2))
2866
return self._vfs_set_option(value, name, section)
2868
raise errors.UnexpectedSmartServerResponse(response)
2788
2870
def _real_object(self):
2789
2871
self._branch._ensure_real()
2790
2872
return self._branch._real_branch