245
247
self._ensure_real()
246
248
self._real_bzrdir.destroy_repository()
248
def create_branch(self, name=None):
250
def create_branch(self, name=None, repository=None):
249
251
# as per meta1 formats - just delegate to the format object which may
250
252
# be parameterised.
251
253
real_branch = self._format.get_branch_format().initialize(self,
254
name=name, repository=repository)
253
255
if not isinstance(real_branch, RemoteBranch):
254
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)
257
262
result = real_branch
258
263
# BzrDir.clone_on_transport() uses the result of create_branch but does
270
275
self._real_bzrdir.destroy_branch(name=name)
271
276
self._next_open_branch_result = None
273
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):
274
280
raise errors.NotLocalUrl(self.transport.base)
276
def find_branch_format(self):
282
def find_branch_format(self, name=None):
277
283
"""Find the branch 'format' for this bzrdir.
279
285
This might be a synthetic object for e.g. RemoteBranch and SVN.
281
b = self.open_branch()
287
b = self.open_branch(name=name)
284
def get_branch_reference(self):
290
def get_branch_reference(self, name=None):
285
291
"""See BzrDir.get_branch_reference()."""
293
# XXX JRV20100304: Support opening colocated branches
294
raise errors.NoColocatedBranchSupport(self)
286
295
response = self._get_branch_reference()
287
296
if response[0] == 'ref':
288
297
return response[1]
319
328
raise errors.UnexpectedSmartServerResponse(response)
322
def _get_tree_branch(self):
331
def _get_tree_branch(self, name=None):
323
332
"""See BzrDir._get_tree_branch()."""
324
return None, self.open_branch()
333
return None, self.open_branch(name=name)
326
335
def open_branch(self, name=None, unsupported=False,
327
336
ignore_fallbacks=False):
896
905
def _has_same_fallbacks(self, other_repo):
897
906
"""Returns true if the repositories have the same fallbacks."""
898
907
# XXX: copied from Repository; it should be unified into a base class
899
# <https://bugs.edge.launchpad.net/bzr/+bug/401622>
908
# <https://bugs.launchpad.net/bzr/+bug/401622>
900
909
my_fb = self._fallback_repositories
901
910
other_fb = other_repo._fallback_repositories
902
911
if len(my_fb) != len(other_fb):
1313
1321
return self._real_repository.make_working_trees()
1315
1323
def refresh_data(self):
1316
"""Re-read any data needed to to synchronise with disk.
1324
"""Re-read any data needed to synchronise with disk.
1318
1326
This method is intended to be called after another repository instance
1319
1327
(such as one used by a smart server) has inserted data into the
1320
repository. It may not be called during a write group, but may be
1321
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.
1323
if self.is_in_write_group():
1324
raise errors.InternalBzrError(
1325
"May not refresh_data while in a write group.")
1326
1334
if self._real_repository is not None:
1327
1335
self._real_repository.refresh_data()
1342
1350
@needs_read_lock
1343
def search_missing_revision_ids(self, other, revision_id=None, find_ghosts=True):
1351
def search_missing_revision_ids(self, other,
1352
revision_id=symbol_versioning.DEPRECATED_PARAMETER,
1353
find_ghosts=True, revision_ids=None, if_present_ids=None):
1344
1354
"""Return the revision ids that other has that this does not.
1346
1356
These are returned in topological order.
1348
1358
revision_id: only return revision ids included by revision_id.
1350
return repository.InterRepository.get(
1351
other, self).search_missing_revision_ids(revision_id, find_ghosts)
1360
if symbol_versioning.deprecated_passed(revision_id):
1361
symbol_versioning.warn(
1362
'search_missing_revision_ids(revision_id=...) was '
1363
'deprecated in 2.3. Use revision_ids=[...] instead.',
1364
DeprecationWarning, stacklevel=2)
1365
if revision_ids is not None:
1366
raise AssertionError(
1367
'revision_ids is mutually exclusive with revision_id')
1368
if revision_id is not None:
1369
revision_ids = [revision_id]
1370
inter_repo = repository.InterRepository.get(other, self)
1371
return inter_repo.search_missing_revision_ids(
1372
find_ghosts=find_ghosts, revision_ids=revision_ids,
1373
if_present_ids=if_present_ids)
1353
1375
def fetch(self, source, revision_id=None, pb=None, find_ghosts=False,
1354
1376
fetch_spec=None):
1755
1777
return '\n'.join((start_keys, stop_keys, count))
1757
1779
def _serialise_search_result(self, search_result):
1758
if isinstance(search_result, graph.PendingAncestryResult):
1759
parts = ['ancestry-of']
1760
parts.extend(search_result.heads)
1762
recipe = search_result.get_recipe()
1763
parts = [recipe[0], self._serialise_search_recipe(recipe)]
1780
parts = search_result.get_network_struct()
1764
1781
return '\n'.join(parts)
1766
1783
def autopack(self):
1969
1987
verb, args, search_bytes)
1970
1988
except errors.UnknownSmartMethod:
1971
1989
medium._remember_remote_is_before(version)
1990
except errors.UnknownErrorFromSmartServer, e:
1991
if isinstance(search, graph.EverythingResult):
1992
error_verb = e.error_from_smart_server.error_verb
1993
if error_verb == 'BadSearch':
1994
# Pre-2.3 servers don't support this sort of search.
1995
# XXX: perhaps falling back to VFS on BadSearch is a
1996
# good idea in general? It might provide a little bit
1997
# of protection against client-side bugs.
1998
medium._remember_remote_is_before((2, 3))
1973
2002
response_tuple, response_handler = response
1974
2003
found_verb = True
1978
2007
if response_tuple[0] != 'ok':
1979
2008
raise errors.UnexpectedSmartServerResponse(response_tuple)
1980
2009
byte_stream = response_handler.read_streamed_body()
1981
src_format, stream = smart_repo._byte_stream_to_stream(byte_stream)
2010
src_format, stream = smart_repo._byte_stream_to_stream(byte_stream,
2011
self._record_counter)
1982
2012
if src_format.network_name() != repo._format.network_name():
1983
2013
raise AssertionError(
1984
2014
"Mismatched RemoteRepository and stream src %r, %r" % (
2122
2152
# Turn the response into a RemoteRepository object.
2123
2153
format = RemoteBranchFormat(network_name=response[1])
2124
2154
repo_format = response_tuple_to_repo_format(response[3:])
2125
if response[2] == '':
2126
repo_bzrdir = a_bzrdir
2155
repo_path = response[2]
2156
if repository is not None:
2157
remote_repo_url = urlutils.join(medium.base, repo_path)
2158
url_diff = urlutils.relative_url(repository.user_url,
2161
raise AssertionError(
2162
'repository.user_url %r does not match URL from server '
2163
'response (%r + %r)'
2164
% (repository.user_url, medium.base, repo_path))
2165
remote_repo = repository
2128
repo_bzrdir = RemoteBzrDir(
2129
a_bzrdir.root_transport.clone(response[2]), a_bzrdir._format,
2131
remote_repo = RemoteRepository(repo_bzrdir, repo_format)
2168
repo_bzrdir = a_bzrdir
2170
repo_bzrdir = RemoteBzrDir(
2171
a_bzrdir.root_transport.clone(repo_path), a_bzrdir._format,
2173
remote_repo = RemoteRepository(repo_bzrdir, repo_format)
2132
2174
remote_branch = RemoteBranch(a_bzrdir, remote_repo,
2133
2175
format=format, setup_stacking=False, name=name)
2134
2176
# XXX: We know this is a new branch, so it must have revno 0, revid
2364
2406
self._ensure_real()
2365
2407
return self._real_branch._get_tags_bytes()
2367
2410
def _get_tags_bytes(self):
2411
if self._tags_bytes is None:
2412
self._tags_bytes = self._get_tags_bytes_via_hpss()
2413
return self._tags_bytes
2415
def _get_tags_bytes_via_hpss(self):
2368
2416
medium = self._client._medium
2369
2417
if medium._is_remote_before((1, 13)):
2370
2418
return self._vfs_get_tags_bytes()
2418
2467
repo_token = self.repository.lock_write().repository_token
2419
2468
self.repository.unlock()
2420
2469
err_context = {'token': token}
2421
response = self._call(
2422
'Branch.lock_write', self._remote_path(), branch_token,
2423
repo_token or '', **err_context)
2471
response = self._call(
2472
'Branch.lock_write', self._remote_path(), branch_token,
2473
repo_token or '', **err_context)
2474
except errors.LockContention, e:
2475
# The LockContention from the server doesn't have any
2476
# information about the lock_url. We re-raise LockContention
2477
# with valid lock_url.
2478
raise errors.LockContention('(remote lock)',
2479
self.repository.base.split('.bzr/')[0])
2424
2480
if response[0] != 'ok':
2425
2481
raise errors.UnexpectedSmartServerResponse(response)
2426
2482
ok, branch_token, repo_token = response
2787
2843
medium = self._branch._client._medium
2788
2844
if medium._is_remote_before((1, 14)):
2789
2845
return self._vfs_set_option(value, name, section)
2846
if isinstance(value, dict):
2847
if medium._is_remote_before((2, 2)):
2848
return self._vfs_set_option(value, name, section)
2849
return self._set_config_option_dict(value, name, section)
2851
return self._set_config_option(value, name, section)
2853
def _set_config_option(self, value, name, section):
2791
2855
path = self._branch._remote_path()
2792
2856
response = self._branch._client.call('Branch.set_config_option',
2793
2857
path, self._branch._lock_token, self._branch._repo_lock_token,
2794
2858
value.encode('utf8'), name, section or '')
2795
2859
except errors.UnknownSmartMethod:
2860
medium = self._branch._client._medium
2796
2861
medium._remember_remote_is_before((1, 14))
2797
2862
return self._vfs_set_option(value, name, section)
2798
2863
if response != ():
2799
2864
raise errors.UnexpectedSmartServerResponse(response)
2866
def _serialize_option_dict(self, option_dict):
2868
for key, value in option_dict.items():
2869
if isinstance(key, unicode):
2870
key = key.encode('utf8')
2871
if isinstance(value, unicode):
2872
value = value.encode('utf8')
2873
utf8_dict[key] = value
2874
return bencode.bencode(utf8_dict)
2876
def _set_config_option_dict(self, value, name, section):
2878
path = self._branch._remote_path()
2879
serialised_dict = self._serialize_option_dict(value)
2880
response = self._branch._client.call(
2881
'Branch.set_config_option_dict',
2882
path, self._branch._lock_token, self._branch._repo_lock_token,
2883
serialised_dict, name, section or '')
2884
except errors.UnknownSmartMethod:
2885
medium = self._branch._client._medium
2886
medium._remember_remote_is_before((2, 2))
2887
return self._vfs_set_option(value, name, section)
2889
raise errors.UnexpectedSmartServerResponse(response)
2801
2891
def _real_object(self):
2802
2892
self._branch._ensure_real()
2803
2893
return self._branch._real_branch