~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/remote.py

Merge from bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
42
42
    deprecated_method,
43
43
    zero_ninetyone,
44
44
    )
45
 
from bzrlib.revision import NULL_REVISION
 
45
from bzrlib.revision import ensure_null, NULL_REVISION
46
46
from bzrlib.trace import mutter, note, warning
47
47
 
48
48
# Note: RemoteBzrDirFormat is in bzrdir.py
62
62
        self._real_bzrdir = None
63
63
 
64
64
        if _client is None:
65
 
            self._shared_medium = transport.get_shared_medium()
66
 
            self._client = client._SmartClient(self._shared_medium)
 
65
            medium = transport.get_smart_medium()
 
66
            self._client = client._SmartClient(medium, transport.base)
67
67
        else:
68
68
            self._client = _client
69
 
            self._shared_medium = None
70
69
            return
71
70
 
72
71
        path = self._path_for_remote_call(self._client)
150
149
    def open_repository(self):
151
150
        path = self._path_for_remote_call(self._client)
152
151
        verb = 'BzrDir.find_repositoryV2'
153
 
        response = self._client.call(verb, path)
154
 
        if (response == ('error', "Generic bzr smart protocol error: "
155
 
                "bad request '%s'" % verb) or
156
 
              response == ('error', "Generic bzr smart protocol error: "
157
 
                "bad request u'%s'" % verb)):
 
152
        try:
 
153
            response = self._client.call(verb, path)
 
154
        except errors.UnknownSmartMethod:
158
155
            verb = 'BzrDir.find_repository'
159
156
            response = self._client.call(verb, path)
160
157
        assert response[0] in ('ok', 'norepository'), \
277
274
            self._real_repository = None
278
275
        self.bzrdir = remote_bzrdir
279
276
        if _client is None:
280
 
            self._client = client._SmartClient(self.bzrdir._shared_medium)
 
277
            self._client = remote_bzrdir._client
281
278
        else:
282
279
            self._client = _client
283
280
        self._format = format
361
358
        self._ensure_real()
362
359
        return self._real_repository._generate_text_key_index()
363
360
 
 
361
    @symbol_versioning.deprecated_method(symbol_versioning.one_four)
364
362
    def get_revision_graph(self, revision_id=None):
365
363
        """See Repository.get_revision_graph()."""
 
364
        return self._get_revision_graph(revision_id)
 
365
 
 
366
    def _get_revision_graph(self, revision_id):
 
367
        """Private method for using with old (< 1.2) servers to fallback."""
366
368
        if revision_id is None:
367
369
            revision_id = ''
368
370
        elif revision.is_null(revision_id):
630
632
        """
631
633
        import tempfile
632
634
        path = self.bzrdir._path_for_remote_call(self._client)
633
 
        response, protocol = self._client.call_expecting_body(
634
 
            'Repository.tarball', path, compression)
 
635
        try:
 
636
            response, protocol = self._client.call_expecting_body(
 
637
                'Repository.tarball', path, compression)
 
638
        except errors.UnknownSmartMethod:
 
639
            protocol.cancel_read_body()
 
640
            return None
635
641
        if response[0] == 'ok':
636
642
            # Extract the tarball and return it
637
643
            t = tempfile.NamedTemporaryFile()
639
645
            t.write(protocol.read_body_bytes())
640
646
            t.seek(0)
641
647
            return t
642
 
        if (response == ('error', "Generic bzr smart protocol error: "
643
 
                "bad request 'Repository.tarball'") or
644
 
              response == ('error', "Generic bzr smart protocol error: "
645
 
                "bad request u'Repository.tarball'")):
646
 
            protocol.cancel_read_body()
647
 
            return None
648
648
        raise errors.UnexpectedSmartServerResponse(response)
649
649
 
650
650
    def sprout(self, to_bzrdir, revision_id=None):
714
714
        return self._real_repository.clone(a_bzrdir, revision_id=revision_id)
715
715
 
716
716
    def make_working_trees(self):
717
 
        """RemoteRepositories never create working trees by default."""
718
 
        return False
 
717
        """See Repository.make_working_trees"""
 
718
        self._ensure_real()
 
719
        return self._real_repository.make_working_trees()
719
720
 
720
721
    def revision_ids_to_search_result(self, result_set):
721
722
        """Convert a set of revision ids to a graph SearchResult."""
811
812
                100.0 * len(self._requested_parents) / len(ancestry))
812
813
        return dict((k, ancestry[k]) for k in present_keys)
813
814
 
814
 
    def _response_is_unknown_method(self, response, verb):
815
 
        """Return True if response is an unknonwn method response to verb.
816
 
        
817
 
        :param response: The response from a smart client call_expecting_body
818
 
            call.
819
 
        :param verb: The verb used in that call.
820
 
        :return: True if an unknown method was encountered.
821
 
        """
822
 
        # This might live better on
823
 
        # bzrlib.smart.protocol.SmartClientRequestProtocolOne
824
 
        if (response[0] == ('error', "Generic bzr smart protocol error: "
825
 
                "bad request '%s'" % verb) or
826
 
              response[0] == ('error', "Generic bzr smart protocol error: "
827
 
                "bad request u'%s'" % verb)):
828
 
           response[1].cancel_read_body()
829
 
           return True
830
 
        return False
831
 
 
832
815
    def _get_parent_map(self, keys):
833
816
        """Helper for get_parent_map that performs the RPC."""
834
 
        medium = self._client.get_smart_medium()
 
817
        medium = self._client._medium
835
818
        if not medium._remote_is_at_least_1_2:
836
819
            # We already found out that the server can't understand
837
820
            # Repository.get_parent_map requests, so just fetch the whole
838
821
            # graph.
 
822
            # XXX: Note that this will issue a deprecation warning. This is ok
 
823
            # :- its because we're working with a deprecated server anyway, and
 
824
            # the user will almost certainly have seen a warning about the
 
825
            # server version already.
839
826
            return self.get_revision_graph()
840
827
 
841
828
        keys = set(keys)
875
862
            assert type(key) is str
876
863
        verb = 'Repository.get_parent_map'
877
864
        args = (path,) + tuple(keys)
878
 
        response = self._client.call_with_body_bytes_expecting_body(
879
 
            verb, args, self._serialise_search_recipe(recipe))
880
 
        if self._response_is_unknown_method(response, verb):
 
865
        try:
 
866
            response = self._client.call_with_body_bytes_expecting_body(
 
867
                verb, args, self._serialise_search_recipe(recipe))
 
868
        except errors.UnknownSmartMethod:
881
869
            # Server does not support this method, so get the whole graph.
882
870
            # Worse, we have to force a disconnection, because the server now
883
871
            # doesn't realise it has a body on the wire to consume, so the
889
877
            # To avoid having to disconnect repeatedly, we keep track of the
890
878
            # fact the server doesn't understand remote methods added in 1.2.
891
879
            medium._remote_is_at_least_1_2 = False
892
 
            return self.get_revision_graph()
893
 
        elif response[0][0] not in ['ok']:
894
 
            reponse[1].cancel_read_body()
 
880
            return self.get_revision_graph(None)
 
881
        if response[0][0] not in ['ok']:
 
882
            response[1].cancel_read_body()
895
883
            raise errors.UnexpectedSmartServerResponse(response[0])
896
884
        if response[0][0] == 'ok':
897
885
            coded = bz2.decompress(response[1].read_body_bytes())
1007
995
        return self._real_repository.pack()
1008
996
 
1009
997
    def set_make_working_trees(self, new_value):
1010
 
        raise NotImplementedError(self.set_make_working_trees)
 
998
        self._ensure_real()
 
999
        self._real_repository.set_make_working_trees(new_value)
1011
1000
 
1012
1001
    @needs_write_lock
1013
1002
    def sign_revision(self, revision_id, gpg_strategy):
1046
1035
        return self._real_repository.has_signature_for_revision_id(revision_id)
1047
1036
 
1048
1037
    def get_data_stream_for_search(self, search):
1049
 
        medium = self._client.get_smart_medium()
 
1038
        medium = self._client._medium
1050
1039
        if not medium._remote_is_at_least_1_2:
1051
1040
            self._ensure_real()
1052
1041
            return self._real_repository.get_data_stream_for_search(search)
1053
1042
        REQUEST_NAME = 'Repository.stream_revisions_chunked'
1054
1043
        path = self.bzrdir._path_for_remote_call(self._client)
1055
1044
        body = self._serialise_search_recipe(search.get_recipe())
1056
 
        response, protocol = self._client.call_with_body_bytes_expecting_body(
1057
 
            REQUEST_NAME, (path,), body)
1058
 
 
1059
 
        if self._response_is_unknown_method((response, protocol), REQUEST_NAME):
 
1045
        try:
 
1046
            result = self._client.call_with_body_bytes_expecting_body(
 
1047
                REQUEST_NAME, (path,), body)
 
1048
            response, protocol = result
 
1049
        except errors.UnknownSmartMethod:
1060
1050
            # Server does not support this method, so fall back to VFS.
1061
1051
            # Worse, we have to force a disconnection, because the server now
1062
1052
            # doesn't realise it has a body on the wire to consume, so the
1220
1210
        if _client is not None:
1221
1211
            self._client = _client
1222
1212
        else:
1223
 
            self._client = client._SmartClient(self.bzrdir._shared_medium)
 
1213
            self._client = remote_bzrdir._client
1224
1214
        self.repository = remote_repository
1225
1215
        if real_branch is not None:
1226
1216
            self._real_branch = real_branch
1240
1230
        self._control_files = None
1241
1231
        self._lock_mode = None
1242
1232
        self._lock_token = None
 
1233
        self._repo_lock_token = None
1243
1234
        self._lock_count = 0
1244
1235
        self._leave_lock = False
1245
1236
 
1500
1491
    def is_locked(self):
1501
1492
        return self._lock_count >= 1
1502
1493
 
 
1494
    @needs_write_lock
1503
1495
    def set_last_revision_info(self, revno, revision_id):
1504
 
        self._ensure_real()
1505
 
        self._clear_cached_state()
1506
 
        return self._real_branch.set_last_revision_info(revno, revision_id)
 
1496
        assert type(revno) is int
 
1497
        revision_id = ensure_null(revision_id)
 
1498
        path = self.bzrdir._path_for_remote_call(self._client)
 
1499
        try:
 
1500
            response = self._client.call('Branch.set_last_revision_info',
 
1501
                path, self._lock_token, self._repo_lock_token, str(revno), revision_id)
 
1502
        except errors.UnknownSmartMethod:
 
1503
            self._ensure_real()
 
1504
            self._clear_cached_state()
 
1505
            return self._real_branch.set_last_revision_info(revno, revision_id)
 
1506
        if response == ('ok',):
 
1507
            self._clear_cached_state()
 
1508
        elif response[0] == 'NoSuchRevision':
 
1509
            raise NoSuchRevision(self, response[1])
 
1510
        else:
 
1511
            raise errors.UnexpectedSmartServerResponse(response)
1507
1512
 
1508
1513
    def generate_revision_history(self, revision_id, last_rev=None,
1509
1514
                                  other_branch=None):