45
44
from bzrlib.smart import client, vfs, repository as smart_repo
46
45
from bzrlib.revision import ensure_null, NULL_REVISION
47
46
from bzrlib.trace import mutter, note, warning
48
from bzrlib.util import bencode
51
49
class _RpcHelper(object):
670
673
self._ensure_real()
671
674
return self._real_repository.suspend_write_group()
673
def get_missing_parent_inventories(self):
675
return self._real_repository.get_missing_parent_inventories()
676
def get_missing_parent_inventories(self, check_for_missing_texts=True):
678
return self._real_repository.get_missing_parent_inventories(
679
check_for_missing_texts=check_for_missing_texts)
681
def _get_rev_id_for_revno_vfs(self, revno, known_pair):
683
return self._real_repository.get_rev_id_for_revno(
686
def get_rev_id_for_revno(self, revno, known_pair):
687
"""See Repository.get_rev_id_for_revno."""
688
path = self.bzrdir._path_for_remote_call(self._client)
690
if self._client._medium._is_remote_before((1, 17)):
691
return self._get_rev_id_for_revno_vfs(revno, known_pair)
692
response = self._call(
693
'Repository.get_rev_id_for_revno', path, revno, known_pair)
694
except errors.UnknownSmartMethod:
695
self._client._medium._remember_remote_is_before((1, 17))
696
return self._get_rev_id_for_revno_vfs(revno, known_pair)
697
if response[0] == 'ok':
698
return True, response[1]
699
elif response[0] == 'history-incomplete':
700
known_pair = response[1:3]
701
for fallback in self._fallback_repositories:
702
found, result = fallback.get_rev_id_for_revno(revno, known_pair)
707
# Not found in any fallbacks
708
return False, known_pair
710
raise errors.UnexpectedSmartServerResponse(response)
677
712
def _ensure_real(self):
678
713
"""Ensure that there is a _real_repository set.
688
723
invocation. If in doubt chat to the bzr network team.
690
725
if self._real_repository is None:
691
if 'hpss' in debug.debug_flags:
726
if 'hpssvfs' in debug.debug_flags:
693
728
warning('VFS Repository access triggered\n%s',
694
729
''.join(traceback.format_stack()))
860
895
self._unstacked_provider.enable_cache(cache_misses=True)
861
896
if self._real_repository is not None:
862
897
self._real_repository.lock_read()
898
for repo in self._fallback_repositories:
864
901
self._lock_count += 1
865
for repo in self._fallback_repositories:
868
903
def _remote_lock_write(self, token):
869
904
path = self.bzrdir._path_for_remote_call(self._client)
901
936
self._lock_count = 1
902
937
cache_misses = self._real_repository is None
903
938
self._unstacked_provider.enable_cache(cache_misses=cache_misses)
939
for repo in self._fallback_repositories:
940
# Writes don't affect fallback repos
904
942
elif self._lock_mode == 'r':
905
943
raise errors.ReadOnlyError(self)
907
945
self._lock_count += 1
908
for repo in self._fallback_repositories:
909
# Writes don't affect fallback repos
911
946
return self._lock_token or None
913
948
def leave_lock_in_place(self):
1084
1123
# We need to accumulate additional repositories here, to pass them in
1085
1124
# on various RPC's.
1126
if self.is_locked():
1127
# We will call fallback.unlock() when we transition to the unlocked
1128
# state, so always add a lock here. If a caller passes us a locked
1129
# repository, they are responsible for unlocking it later.
1130
repository.lock_read()
1087
1131
self._fallback_repositories.append(repository)
1088
1132
# If self._real_repository was parameterised already (e.g. because a
1089
1133
# _real_branch had its get_stacked_on_url method called), then the
1452
1496
return self._real_repository.inventories
1454
1498
@needs_write_lock
1499
def pack(self, hint=None):
1456
1500
"""Compress the data within the repository.
1458
1502
This is not currently implemented within the smart server.
1460
1504
self._ensure_real()
1461
return self._real_repository.pack()
1505
return self._real_repository.pack(hint=hint)
1464
1508
def revisions(self):
1566
1610
providers.insert(0, other)
1567
1611
providers.extend(r._make_parents_provider() for r in
1568
1612
self._fallback_repositories)
1569
return graph._StackedParentsProvider(providers)
1613
return graph.StackedParentsProvider(providers)
1571
1615
def _serialise_search_recipe(self, recipe):
1572
1616
"""Serialise a graph search recipe.
1885
1929
self._ensure_real()
1886
1930
return self._custom_format.supports_stacking()
1932
def supports_set_append_revisions_only(self):
1934
return self._custom_format.supports_set_append_revisions_only()
1889
1937
class RemoteBranch(branch.Branch, _RpcHelper):
1890
1938
"""Branch stored on a server accessed by HPSS RPC.
1909
1957
# We intentionally don't call the parent class's __init__, because it
1910
1958
# will try to assign to self.tags, which is a property in this subclass.
1911
1959
# And the parent's __init__ doesn't do much anyway.
1912
self._revision_id_to_revno_cache = None
1913
self._partial_revision_id_to_revno_cache = {}
1914
self._revision_history_cache = None
1915
self._last_revision_info_cache = None
1916
self._merge_sorted_revisions_cache = None
1917
1960
self.bzrdir = remote_bzrdir
1918
1961
if _client is not None:
1919
1962
self._client = _client
1971
2016
except (errors.NotStacked, errors.UnstackableBranchFormat,
1972
2017
errors.UnstackableRepositoryFormat), e:
1974
self._activate_fallback_location(fallback_url, None)
2019
self._is_stacked = True
2020
self._activate_fallback_location(fallback_url)
1976
2022
def _get_config(self):
1977
2023
return RemoteBranchConfig(self)
2078
2124
raise errors.UnexpectedSmartServerResponse(response)
2079
2125
return response[1]
2127
def set_stacked_on_url(self, url):
2128
branch.Branch.set_stacked_on_url(self, url)
2130
self._is_stacked = False
2132
self._is_stacked = True
2081
2134
def _vfs_get_tags_bytes(self):
2082
2135
self._ensure_real()
2083
2136
return self._real_branch._get_tags_bytes()
2210
2263
raise NotImplementedError(self.dont_leave_lock_in_place)
2211
2264
self._leave_lock = False
2266
def get_rev_id(self, revno, history=None):
2268
return _mod_revision.NULL_REVISION
2269
last_revision_info = self.last_revision_info()
2270
ok, result = self.repository.get_rev_id_for_revno(
2271
revno, last_revision_info)
2274
missing_parent = result[1]
2275
# Either the revision named by the server is missing, or its parent
2276
# is. Call get_parent_map to determine which, so that we report a
2278
parent_map = self.repository.get_parent_map([missing_parent])
2279
if missing_parent in parent_map:
2280
missing_parent = parent_map[missing_parent]
2281
raise errors.RevisionNotPresent(missing_parent, self.repository)
2213
2283
def _last_revision_info(self):
2214
2284
response = self._call('Branch.last_revision_info', self._remote_path())
2215
2285
if response[0] != 'ok':
2221
2291
def _gen_revision_history(self):
2222
2292
"""See Branch._gen_revision_history()."""
2293
if self._is_stacked:
2295
return self._real_branch._gen_revision_history()
2223
2296
response_tuple, response_handler = self._call_expecting_body(
2224
2297
'Branch.revision_history', self._remote_path())
2225
2298
if response_tuple[0] != 'ok':