~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/remote.py

  • Committer: John Arbash Meinel
  • Date: 2009-07-08 14:37:25 UTC
  • mfrom: (4516 +trunk)
  • mto: This revision was merged to the branch mainline in revision 4517.
  • Revision ID: john@arbash-meinel.com-20090708143725-sc9sjy3mz4cxwxzz
Merge bzr.dev 4516

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
import bz2
21
21
 
22
22
from bzrlib import (
 
23
    bencode,
23
24
    branch,
24
25
    bzrdir,
25
26
    config,
27
28
    errors,
28
29
    graph,
29
30
    lockdir,
30
 
    pack,
31
31
    repository,
32
32
    revision,
33
33
    revision as _mod_revision,
34
34
    symbol_versioning,
35
 
    urlutils,
36
35
)
37
36
from bzrlib.branch import BranchReferenceFormat
38
37
from bzrlib.bzrdir import BzrDir, RemoteBzrDirFormat
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
49
47
 
50
48
 
51
49
class _RpcHelper(object):
568
566
        return self._creating_repo._real_repository._format.network_name()
569
567
 
570
568
    @property
 
569
    def pack_compresses(self):
 
570
        self._ensure_real()
 
571
        return self._custom_format.pack_compresses
 
572
 
 
573
    @property
571
574
    def _serializer(self):
572
575
        self._ensure_real()
573
576
        return self._custom_format._serializer
670
673
        self._ensure_real()
671
674
        return self._real_repository.suspend_write_group()
672
675
 
673
 
    def get_missing_parent_inventories(self):
674
 
        self._ensure_real()
675
 
        return self._real_repository.get_missing_parent_inventories()
 
676
    def get_missing_parent_inventories(self, check_for_missing_texts=True):
 
677
        self._ensure_real()
 
678
        return self._real_repository.get_missing_parent_inventories(
 
679
            check_for_missing_texts=check_for_missing_texts)
 
680
 
 
681
    def _get_rev_id_for_revno_vfs(self, revno, known_pair):
 
682
        self._ensure_real()
 
683
        return self._real_repository.get_rev_id_for_revno(
 
684
            revno, known_pair)
 
685
 
 
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)
 
689
        try:
 
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)
 
703
                if found:
 
704
                    return True, result
 
705
                else:
 
706
                    known_pair = result
 
707
            # Not found in any fallbacks
 
708
            return False, known_pair
 
709
        else:
 
710
            raise errors.UnexpectedSmartServerResponse(response)
676
711
 
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.
689
724
        """
690
725
        if self._real_repository is None:
691
 
            if 'hpss' in debug.debug_flags:
 
726
            if 'hpssvfs' in debug.debug_flags:
692
727
                import traceback
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:
 
899
                repo.lock_read()
863
900
        else:
864
901
            self._lock_count += 1
865
 
        for repo in self._fallback_repositories:
866
 
            repo.lock_read()
867
902
 
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
 
941
                repo.lock_read()
904
942
        elif self._lock_mode == 'r':
905
943
            raise errors.ReadOnlyError(self)
906
944
        else:
907
945
            self._lock_count += 1
908
 
        for repo in self._fallback_repositories:
909
 
            # Writes don't affect fallback repos
910
 
            repo.lock_read()
911
946
        return self._lock_token or None
912
947
 
913
948
    def leave_lock_in_place(self):
1015
1050
                self._lock_token = None
1016
1051
                if not self._leave_lock:
1017
1052
                    self._unlock(old_token)
 
1053
        # Fallbacks are always 'lock_read()' so we don't pay attention to
 
1054
        # self._leave_lock
 
1055
        for repo in self._fallback_repositories:
 
1056
            repo.unlock()
1018
1057
 
1019
1058
    def break_lock(self):
1020
1059
        # should hand off to the network
1084
1123
        # We need to accumulate additional repositories here, to pass them in
1085
1124
        # on various RPC's.
1086
1125
        #
 
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
1453
1497
 
1454
1498
    @needs_write_lock
1455
 
    def pack(self):
 
1499
    def pack(self, hint=None):
1456
1500
        """Compress the data within the repository.
1457
1501
 
1458
1502
        This is not currently implemented within the smart server.
1459
1503
        """
1460
1504
        self._ensure_real()
1461
 
        return self._real_repository.pack()
 
1505
        return self._real_repository.pack(hint=hint)
1462
1506
 
1463
1507
    @property
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)
1570
1614
 
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()
1887
1931
 
 
1932
    def supports_set_append_revisions_only(self):
 
1933
        self._ensure_real()
 
1934
        return self._custom_format.supports_set_append_revisions_only()
 
1935
 
1888
1936
 
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
1933
1976
        else:
1934
1977
            self._real_branch = None
1935
1978
        # Fill out expected attributes of branch for bzrlib API users.
 
1979
        self._clear_cached_state()
1936
1980
        self.base = self.bzrdir.root_transport.base
1937
1981
        self._control_files = None
1938
1982
        self._lock_mode = None
1960
2004
        hooks = branch.Branch.hooks['open']
1961
2005
        for hook in hooks:
1962
2006
            hook(self)
 
2007
        self._is_stacked = False
1963
2008
        if setup_stacking:
1964
2009
            self._setup_stacking()
1965
2010
 
1971
2016
        except (errors.NotStacked, errors.UnstackableBranchFormat,
1972
2017
            errors.UnstackableRepositoryFormat), e:
1973
2018
            return
1974
 
        self._activate_fallback_location(fallback_url, None)
 
2019
        self._is_stacked = True
 
2020
        self._activate_fallback_location(fallback_url)
1975
2021
 
1976
2022
    def _get_config(self):
1977
2023
        return RemoteBranchConfig(self)
2078
2124
            raise errors.UnexpectedSmartServerResponse(response)
2079
2125
        return response[1]
2080
2126
 
 
2127
    def set_stacked_on_url(self, url):
 
2128
        branch.Branch.set_stacked_on_url(self, url)
 
2129
        if not url:
 
2130
            self._is_stacked = False
 
2131
        else:
 
2132
            self._is_stacked = True
 
2133
        
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
2212
2265
 
 
2266
    def get_rev_id(self, revno, history=None):
 
2267
        if revno == 0:
 
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)
 
2272
        if ok:
 
2273
            return result
 
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
 
2277
        # useful error.
 
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)
 
2282
 
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':
2220
2290
 
2221
2291
    def _gen_revision_history(self):
2222
2292
        """See Branch._gen_revision_history()."""
 
2293
        if self._is_stacked:
 
2294
            self._ensure_real()
 
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':