~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/remote.py

merge hpss

Show diffs side-by-side

added added

removed removed

Lines of Context:
20
20
from cStringIO import StringIO
21
21
from urlparse import urlparse
22
22
 
23
 
from bzrlib import branch, errors, repository
 
23
from bzrlib import branch, errors, lockdir, repository
24
24
from bzrlib.branch import BranchReferenceFormat
25
25
from bzrlib.bzrdir import BzrDir, BzrDirFormat, RemoteBzrDirFormat
26
26
from bzrlib.config import BranchConfig, TreeConfig
27
27
from bzrlib.decorators import needs_read_lock, needs_write_lock
28
28
from bzrlib.errors import NoSuchRevision
 
29
from bzrlib.lockable_files import LockableFiles
29
30
from bzrlib.revision import NULL_REVISION
30
31
from bzrlib.smart import client, vfs
31
32
from bzrlib.urlutils import unescape
85
86
        real_workingtree = self._real_bzrdir.create_workingtree(revision_id=revision_id)
86
87
        return RemoteWorkingTree(self, real_workingtree)
87
88
 
88
 
    def open_branch(self, _unsupported=False):
89
 
        assert _unsupported == False, 'unsupported flag support not implemented yet.'
 
89
    def find_branch_format(self):
 
90
        """Find the branch 'format' for this bzrdir.
 
91
 
 
92
        This might be a synthetic object for e.g. RemoteBranch and SVN.
 
93
        """
 
94
        b = self.open_branch()
 
95
        return b._format
 
96
 
 
97
    def get_branch_reference(self):
 
98
        """See BzrDir.get_branch_reference()."""
90
99
        path = self._path_for_remote_call(self._client)
91
100
        response = self._client.call('BzrDir.open_branch', path)
92
101
        if response[0] == 'ok':
93
102
            if response[1] == '':
94
103
                # branch at this location.
95
 
                return RemoteBranch(self, self.find_repository())
 
104
                return None
96
105
            else:
97
106
                # a branch reference, use the existing BranchReference logic.
98
 
                format = BranchReferenceFormat()
99
 
                return format.open(self, _found=True, location=response[1])
 
107
                return response[1]
100
108
        elif response == ('nobranch',):
101
109
            raise errors.NotBranchError(path=self.root_transport.base)
102
110
        else:
103
111
            assert False, 'unexpected response code %r' % (response,)
 
112
 
 
113
    def open_branch(self, _unsupported=False):
 
114
        assert _unsupported == False, 'unsupported flag support not implemented yet.'
 
115
        reference_url = self.get_branch_reference()
 
116
        if reference_url is None:
 
117
            # branch at this location.
 
118
            return RemoteBranch(self, self.find_repository())
 
119
        else:
 
120
            # a branch reference, use the existing BranchReference logic.
 
121
            format = BranchReferenceFormat()
 
122
            return format.open(self, _found=True, location=reference_url)
104
123
                
105
124
    def open_repository(self):
106
125
        path = self._path_for_remote_call(self._client)
119
138
            raise errors.NoRepositoryPresent(self)
120
139
 
121
140
    def open_workingtree(self):
122
 
        return RemoteWorkingTree(self, self._real_bzrdir.open_workingtree())
 
141
        raise errors.NotLocalUrl(self.root_transport)
123
142
 
124
143
    def _path_for_remote_call(self, client):
125
144
        """Return the path to be used for this bzrdir in a remote call."""
587
606
        return self._real_repository.has_signature_for_revision_id(revision_id)
588
607
 
589
608
 
590
 
class RemoteBranchLockableFiles(object):
 
609
class RemoteBranchLockableFiles(LockableFiles):
591
610
    """A 'LockableFiles' implementation that talks to a smart server.
592
611
    
593
612
    This is not a public interface class.
596
615
    def __init__(self, bzrdir, _client):
597
616
        self.bzrdir = bzrdir
598
617
        self._client = _client
 
618
        # XXX: This assumes that the branch control directory is .bzr/branch,
 
619
        # which isn't necessarily true.
 
620
        LockableFiles.__init__(
 
621
            self, bzrdir.root_transport.clone('.bzr/branch'),
 
622
            'lock', lockdir.LockDir)
599
623
 
600
624
    def get(self, path):
601
625
        """'get' a remote path as per the LockableFiles interface.
604
628
             just retrieve a file, instead we ask the smart server to generate
605
629
             a configuration for us - which is retrieved as an INI file.
606
630
        """
607
 
        assert path == 'branch.conf'
608
 
        path = self.bzrdir._path_for_remote_call(self._client)
609
 
        response = self._client.call2('Branch.get_config_file', path)
610
 
        assert response[0][0] == 'ok', \
611
 
            'unexpected response code %s' % (response[0],)
612
 
        return StringIO(response[1].read_body_bytes())
 
631
        if path == 'branch.conf':
 
632
            path = self.bzrdir._path_for_remote_call(self._client)
 
633
            response = self._client.call2('Branch.get_config_file', path)
 
634
            assert response[0][0] == 'ok', \
 
635
                'unexpected response code %s' % (response[0],)
 
636
            return StringIO(response[1].read_body_bytes())
 
637
        else:
 
638
            # VFS fallback.
 
639
            return LockableFiles.get(self, path)
613
640
 
614
641
 
615
642
class RemoteBranchFormat(branch.BranchFormat):
616
643
 
 
644
    def __eq__(self, other):
 
645
        return (isinstance(other, RemoteBranchFormat) and 
 
646
            self.__dict__ == other.__dict__)
 
647
 
617
648
    def get_format_description(self):
618
649
        return 'Remote BZR Branch'
619
650
 
918
949
            other, stop_revision=stop_revision)
919
950
 
920
951
 
921
 
class RemoteWorkingTree(object):
922
 
 
923
 
    def __init__(self, remote_bzrdir, real_workingtree):
924
 
        self.real_workingtree = real_workingtree
925
 
        self.bzrdir = remote_bzrdir
926
 
 
927
 
    def __getattr__(self, name):
928
 
        # XXX: temporary way to lazily delegate everything to the real
929
 
        # workingtree
930
 
        return getattr(self.real_workingtree, name)
931
 
 
932
 
 
933
952
class RemoteBranchConfig(BranchConfig):
934
953
 
935
954
    def username(self):