/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
1
# Copyright (C) 2006, 2007 Canonical Ltd
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
2
#
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
1752.2.39 by Martin Pool
[broken] implement upgrade apis on remote bzrdirs
17
# TODO: At some point, handle upgrades by just passing the whole request
18
# across to run on the server.
19
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
20
from cStringIO import StringIO
2018.5.26 by Andrew Bennetts
Extract a simple SmartClient class from RemoteTransport, and a hack to avoid VFS operations when probing for a bzrdir over a smart transport.
21
from urlparse import urlparse
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
22
2018.5.25 by Andrew Bennetts
Make sure RemoteBzrDirFormat is always registered (John Arbash Meinel, Robert Collins, Andrew Bennetts).
23
from bzrlib import branch, errors, repository
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
24
from bzrlib.branch import BranchReferenceFormat
2018.5.25 by Andrew Bennetts
Make sure RemoteBzrDirFormat is always registered (John Arbash Meinel, Robert Collins, Andrew Bennetts).
25
from bzrlib.bzrdir import BzrDir, BzrDirFormat, RemoteBzrDirFormat
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
26
from bzrlib.revision import NULL_REVISION
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
27
from bzrlib.smart import client, vfs
2018.5.32 by Robert Collins
Unescape urls before handing over the wire to the smart server for the probe_transport method.
28
from bzrlib.urlutils import unescape
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
29
2018.5.25 by Andrew Bennetts
Make sure RemoteBzrDirFormat is always registered (John Arbash Meinel, Robert Collins, Andrew Bennetts).
30
# Note: RemoteBzrDirFormat is in bzrdir.py
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
31
32
class RemoteBzrDir(BzrDir):
33
    """Control directory on a remote server, accessed by HPSS."""
34
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
35
    def __init__(self, transport, _client=None):
36
        """Construct a RemoteBzrDir.
37
38
        :param _client: Private parameter for testing. Disables probing and the
39
            use of a real bzrdir.
40
        """
1752.2.39 by Martin Pool
[broken] implement upgrade apis on remote bzrdirs
41
        BzrDir.__init__(self, transport, RemoteBzrDirFormat())
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
42
        if _client is not None:
43
            self.client = _client
44
            return
45
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
46
        self.client = transport.get_smart_client()
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
47
        # this object holds a delegated bzrdir that uses file-level operations
48
        # to talk to the other side
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
49
        # XXX: We should go into find_format, but not allow it to find
50
        # RemoteBzrDirFormat and make sure it finds the real underlying format.
51
        
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
52
        # THIS IS A COMPLETE AND UTTER LIE.
53
        # XXX: XXX: XXX: must be removed before merging to mainline
54
        # SMART_SERVER_MERGE_BLOCKER
1752.2.72 by Andrew Bennetts
Make Remote* classes in remote.py more consistent and remove some dead code.
55
        default_format = BzrDirFormat.get_default_format()
56
        self._real_bzrdir = default_format.open(transport, _found=True)
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
57
        smartclient = client.SmartClient(self.client)
58
        path = self._path_for_remote_call(smartclient)
2018.5.26 by Andrew Bennetts
Extract a simple SmartClient class from RemoteTransport, and a hack to avoid VFS operations when probing for a bzrdir over a smart transport.
59
        #self._real_bzrdir._format.probe_transport(transport)
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
60
        response = smartclient.call('probe_dont_use', path)
2018.5.26 by Andrew Bennetts
Extract a simple SmartClient class from RemoteTransport, and a hack to avoid VFS operations when probing for a bzrdir over a smart transport.
61
        if response == ('no',):
62
            raise errors.NotBranchError(path=transport.base)
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
63
1752.2.39 by Martin Pool
[broken] implement upgrade apis on remote bzrdirs
64
    def create_repository(self, shared=False):
1752.2.72 by Andrew Bennetts
Make Remote* classes in remote.py more consistent and remove some dead code.
65
        return RemoteRepository(
66
            self, self._real_bzrdir.create_repository(shared=shared))
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
67
68
    def create_branch(self):
1752.2.72 by Andrew Bennetts
Make Remote* classes in remote.py more consistent and remove some dead code.
69
        real_branch = self._real_bzrdir.create_branch()
70
        real_repository = real_branch.repository
71
        remote_repository = RemoteRepository(self, real_repository)
72
        return RemoteBranch(self, remote_repository, real_branch)
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
73
74
    def create_workingtree(self, revision_id=None):
1752.2.72 by Andrew Bennetts
Make Remote* classes in remote.py more consistent and remove some dead code.
75
        real_workingtree = self._real_bzrdir.create_workingtree(revision_id=revision_id)
76
        return RemoteWorkingTree(self, real_workingtree)
1752.2.39 by Martin Pool
[broken] implement upgrade apis on remote bzrdirs
77
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
78
    def open_branch(self, _unsupported=False):
79
        assert _unsupported == False, 'unsupported flag support not implemented yet.'
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
80
        smartclient = client.SmartClient(self.client)
81
        path = self._path_for_remote_call(smartclient)
82
        response = smartclient.call('BzrDir.open_branch', path)
2018.5.52 by Wouter van Heyst
Provide more information when encountering unexpected responses from a smart
83
        assert response[0] == 'ok', 'unexpected response code %s' % (response,)
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
84
        if response[0] != 'ok':
85
            # this should probably be a regular translate no ?
86
            raise errors.NotBranchError(path=self.root_transport.base)
87
        if response[1] == '':
88
            # branch at this location.
89
            if vfs.vfs_enabled():
90
                # if the VFS is enabled, create a local object using the VFS.
91
                real_branch = self._real_bzrdir.open_branch(unsupported=_unsupported)
92
                # This branch accessed through the smart server, so wrap the
93
                # file-level objects.
94
                real_repository = real_branch.repository
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
95
                assert isinstance(real_repository.bzrdir, RemoteBzrDir)
96
                remote_repository = RemoteRepository(real_repository.bzrdir, real_repository)
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
97
                return RemoteBranch(self, remote_repository, real_branch)
98
            else:
99
                # otherwise just create a proxy for the branch.
100
                return RemoteBranch(self, self.find_repository())
101
        else:
102
            # a branch reference, use the existing BranchReference logic.
103
            format = BranchReferenceFormat()
104
            return format.open(self, _found=True, location=response[1])
105
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
106
    def open_repository(self):
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
107
        smartclient = client.SmartClient(self.client)
108
        path = self._path_for_remote_call(smartclient)
109
        response = smartclient.call('BzrDir.find_repository', path)
110
        assert response[0] in ('ok', 'norepository'), \
2018.5.52 by Wouter van Heyst
Provide more information when encountering unexpected responses from a smart
111
            'unexpected response code %s' % (response,)
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
112
        if response[0] == 'norepository':
113
            raise errors.NoRepositoryPresent(self)
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
114
        if response[1] == '':
115
            if vfs.vfs_enabled():
116
                return RemoteRepository(self, self._real_bzrdir.open_repository())
117
            else:
118
                return RemoteRepository(self)
119
        else:
120
            raise errors.NoRepositoryPresent(self)
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
121
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
122
    def open_workingtree(self):
1752.2.72 by Andrew Bennetts
Make Remote* classes in remote.py more consistent and remove some dead code.
123
        return RemoteWorkingTree(self, self._real_bzrdir.open_workingtree())
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
124
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
125
    def _path_for_remote_call(self, client):
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
126
        """Return the path to be used for this bzrdir in a remote call."""
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
127
        return client.remote_path_from_transport(self.root_transport)
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
128
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
129
    def get_branch_transport(self, branch_format):
130
        return self._real_bzrdir.get_branch_transport(branch_format)
131
1752.2.43 by Andrew Bennetts
Fix get_{branch,repository,workingtree}_transport.
132
    def get_repository_transport(self, repository_format):
133
        return self._real_bzrdir.get_repository_transport(repository_format)
134
135
    def get_workingtree_transport(self, workingtree_format):
136
        return self._real_bzrdir.get_workingtree_transport(workingtree_format)
137
1752.2.39 by Martin Pool
[broken] implement upgrade apis on remote bzrdirs
138
    def can_convert_format(self):
139
        """Upgrading of remote bzrdirs is not supported yet."""
140
        return False
141
142
    def needs_format_conversion(self, format=None):
143
        """Upgrading of remote bzrdirs is not supported yet."""
144
        return False
145
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
146
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
147
class RemoteRepositoryFormat(repository.RepositoryFormat):
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
148
    """Format for repositories accessed over rpc.
149
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
150
    Instances of this repository are represented by RemoteRepository
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
151
    instances.
152
    """
153
154
    _matchingbzrdir = RemoteBzrDirFormat
155
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
156
    def initialize(self, a_bzrdir, shared=False):
1752.2.72 by Andrew Bennetts
Make Remote* classes in remote.py more consistent and remove some dead code.
157
        assert isinstance(a_bzrdir, RemoteBzrDir)
158
        return a_bzrdir.create_repository(shared=shared)
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
159
    
160
    def open(self, a_bzrdir):
1752.2.72 by Andrew Bennetts
Make Remote* classes in remote.py more consistent and remove some dead code.
161
        assert isinstance(a_bzrdir, RemoteBzrDir)
162
        return a_bzrdir.open_repository()
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
163
164
    def get_format_description(self):
165
        return 'bzr remote repository'
166
167
    def __eq__(self, other):
1752.2.87 by Andrew Bennetts
Make tests pass.
168
        return self.__class__ == other.__class__
169
170
    rich_root_data = False
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
171
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
172
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
173
class RemoteRepository(object):
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
174
    """Repository accessed over rpc.
175
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
176
    For the moment everything is delegated to IO-like operations over
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
177
    the transport.
178
    """
179
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
180
    def __init__(self, remote_bzrdir, real_repository=None, _client=None):
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
181
        """Create a RemoteRepository instance.
182
        
183
        :param remote_bzrdir: The bzrdir hosting this repository.
184
        :param real_repository: If not None, a local implementation of the
185
            repository logic for the repository, usually accessing the data
186
            via the VFS.
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
187
        :param _client: Private testing parameter - override the smart client
188
            to be used by the repository.
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
189
        """
190
        if real_repository:
2018.5.36 by Andrew Bennetts
Fix typo, and clean up some ununsed import warnings from pyflakes at the same time.
191
            self._real_repository = real_repository
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
192
        self.bzrdir = remote_bzrdir
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
193
        if _client is None:
194
            self._client = client.SmartClient(self.bzrdir.client)
195
        else:
196
            self._client = _client
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
197
        self._format = RemoteRepositoryFormat()
198
2018.5.40 by Robert Collins
Implement a remote Repository.has_revision method.
199
    def has_revision(self, revision_id):
200
        """See Repository.has_revision()."""
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
201
        path = self.bzrdir._path_for_remote_call(self._client)
2018.5.40 by Robert Collins
Implement a remote Repository.has_revision method.
202
        response = self._client.call('Repository.has_revision', path, revision_id.encode('utf8'))
2018.5.52 by Wouter van Heyst
Provide more information when encountering unexpected responses from a smart
203
        assert response[0] in ('ok', 'no'), 'unexpected response code %s' % (response,)
2018.5.40 by Robert Collins
Implement a remote Repository.has_revision method.
204
        return response[0] == 'ok'
205
2018.5.62 by Robert Collins
Stub out RemoteRepository.gather_stats while its implemented in parallel.
206
    def gather_stats(self, revid, committers=None):
207
        """See Repository.gather_stats()."""
208
        # SMART_SERVER_MERGE_BLOCKER
209
        return self._real_repository.gather_stats(revid, committers)
210
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
211
    def get_physical_lock_status(self):
212
        """See Repository.get_physical_lock_status()."""
213
        return False
214
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
215
    def is_shared(self):
216
        """See Repository.is_shared()."""
217
        path = self.bzrdir._path_for_remote_call(self._client)
218
        response = self._client.call('Repository.is_shared', path)
219
        assert response[0] in ('yes', 'no'), 'unexpected response code %s' % (response,)
220
        return response[0] == 'yes'
221
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
222
    def lock_read(self):
223
        # wrong eventually - want a local lock cache context
224
        return self._real_repository.lock_read()
225
226
    def lock_write(self):
227
        # definately wrong: want to check if there is a real repo
228
        # and not thunk through if not
229
        return self._real_repository.lock_write()
230
231
    def unlock(self):
232
        # should free cache context.
233
        return self._real_repository.unlock()
234
235
    def break_lock(self):
236
        # should hand off to the network - or better yet, we should not
237
        # allow stale network locks ?
238
        return self._real_repository.break_lock()
239
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
240
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
241
class RemoteBranchLockableFiles(object):
242
    """A 'LockableFiles' implementation that talks to a smart server.
243
    
244
    This is not a public interface class.
245
    """
246
247
    def __init__(self, bzrdir, _client):
248
        self.bzrdir = bzrdir
249
        self._client = _client
250
251
    def get(self, path):
252
        """'get' a remote path as per the LockableFiles interface.
253
254
        :param path: the file to 'get'. If this is 'branch.conf', we do not
255
             just retrieve a file, instead we ask the smart server to generate
256
             a configuration for us - which is retrieved as an INI file.
257
        """
258
        assert path == 'branch.conf'
259
        path = self.bzrdir._path_for_remote_call(self._client)
260
        response = self._client.call2('Branch.get_config_file', path)
261
        assert response[0][0] == 'ok', 'unexpected response code %s' % (response[0],)
262
        return StringIO(response[1].read_body_bytes())
263
264
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
265
class RemoteBranchFormat(branch.BranchFormat):
266
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
267
    def get_format_description(self):
268
        return 'Remote BZR Branch'
269
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
270
    def open(self, a_bzrdir):
1752.2.72 by Andrew Bennetts
Make Remote* classes in remote.py more consistent and remove some dead code.
271
        assert isinstance(a_bzrdir, RemoteBzrDir)
272
        return a_bzrdir.open_branch()
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
273
274
    def initialize(self, a_bzrdir):
275
        assert isinstance(a_bzrdir, RemoteBzrDir)
276
        return a_bzrdir.create_branch()
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
277
278
279
class RemoteBranch(branch.Branch):
280
    """Branch stored on a server accessed by HPSS RPC.
281
282
    At the moment most operations are mapped down to simple file operations.
283
    """
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
284
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
285
    def __init__(self, remote_bzrdir, remote_repository, real_branch=None,
286
        _client=None):
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
287
        """Create a RemoteBranch instance.
288
289
        :param real_branch: An optional local implementation of the branch
290
            format, usually accessing the data via the VFS.
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
291
        :param _client: Private parameter for testing.
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
292
        """
1752.2.64 by Andrew Bennetts
Improve how RemoteBzrDir.open_branch works to handle references and not double-open repositories.
293
        self.bzrdir = remote_bzrdir
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
294
        if _client is not None:
295
            self._client = _client
296
        else:
297
            self._client = client.SmartClient(self.bzrdir.client)
1752.2.64 by Andrew Bennetts
Improve how RemoteBzrDir.open_branch works to handle references and not double-open repositories.
298
        self.repository = remote_repository
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
299
        if real_branch is not None:
300
            self._real_branch = real_branch
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
301
        # Fill out expected attributes of branch for bzrlib api users.
1752.2.64 by Andrew Bennetts
Improve how RemoteBzrDir.open_branch works to handle references and not double-open repositories.
302
        self._format = RemoteBranchFormat()
2018.5.55 by Robert Collins
Give RemoteBranch a base url in line with the Branch protocol.
303
        self.base = self.bzrdir.root_transport.base
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
304
        self.control_files = RemoteBranchLockableFiles(self.bzrdir, self._client)
1752.2.64 by Andrew Bennetts
Improve how RemoteBzrDir.open_branch works to handle references and not double-open repositories.
305
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
306
    def get_physical_lock_status(self):
307
        """See Branch.get_physical_lock_status()."""
308
        # should be an API call to the server, as branches must be lockable.
309
        return self._real_branch.get_physical_lock_status()
310
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
311
    def lock_read(self):
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
312
        return self._real_branch.lock_read()
313
314
    def lock_write(self):
315
        return self._real_branch.lock_write()
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
316
317
    def unlock(self):
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
318
        return self._real_branch.unlock()
319
320
    def break_lock(self):
321
        return self._real_branch.break_lock()
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
322
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
323
    def last_revision_info(self):
324
        """See Branch.last_revision_info()."""
325
        path = self.bzrdir._path_for_remote_call(self._client)
326
        response = self._client.call('Branch.last_revision_info', path)
2018.5.52 by Wouter van Heyst
Provide more information when encountering unexpected responses from a smart
327
        assert response[0] == 'ok', 'unexpected response code %s' % (response,)
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
328
        revno = int(response[1])
329
        last_revision = response[2].decode('utf8')
330
        if last_revision == '':
331
            last_revision = NULL_REVISION
332
        return (revno, last_revision)
333
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
334
    def revision_history(self):
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
335
        """See Branch.revision_history()."""
336
        # XXX: TODO: this does not cache the revision history for the duration
337
        # of a lock, which is a bug - see the code for regular branches
338
        # for details.
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
339
        path = self.bzrdir._path_for_remote_call(self._client)
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
340
        response = self._client.call2('Branch.revision_history', path)
2018.5.52 by Wouter van Heyst
Provide more information when encountering unexpected responses from a smart
341
        assert response[0][0] == 'ok', 'unexpected response code %s' % (response[0],)
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
342
        result = response[1].read_body_bytes().decode('utf8').split('\x00')
343
        if result == ['']:
344
            return []
345
        return result
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
346
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
347
    def set_revision_history(self, rev_history):
348
        return self._real_branch.set_revision_history(rev_history)
349
350
    def get_parent(self):
351
        return self._real_branch.get_parent()
352
        
1752.2.63 by Andrew Bennetts
Delegate set_parent.
353
    def set_parent(self, url):
354
        return self._real_branch.set_parent(url)
355
        
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
356
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
357
class RemoteWorkingTree(object):
358
1752.2.72 by Andrew Bennetts
Make Remote* classes in remote.py more consistent and remove some dead code.
359
    def __init__(self, remote_bzrdir, real_workingtree):
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
360
        self.real_workingtree = real_workingtree
361
        self.bzrdir = remote_bzrdir
362
363
    def __getattr__(self, name):
364
        # XXX: temporary way to lazily delegate everything to the real
365
        # workingtree
366
        return getattr(self.real_workingtree, name)
367
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
368