/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
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
21
2490.2.5 by Aaron Bentley
Use GraphWalker.unique_ancestor to determine merge base
22
from bzrlib import (
23
    branch,
24
    errors,
25
    lockdir,
26
    repository,
2948.3.1 by John Arbash Meinel
Fix bug #158333, make sure that Repository.fetch(self) is properly a no-op for all Repository implementations.
27
    revision,
2490.2.5 by Aaron Bentley
Use GraphWalker.unique_ancestor to determine merge base
28
)
2535.4.27 by Andrew Bennetts
Remove some unused imports.
29
from bzrlib.branch import BranchReferenceFormat
2018.5.174 by Andrew Bennetts
Various nits discovered by pyflakes.
30
from bzrlib.bzrdir import BzrDir, RemoteBzrDirFormat
2018.14.2 by Andrew Bennetts
All but one repository_implementation tests for RemoteRepository passing.
31
from bzrlib.config import BranchConfig, TreeConfig
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
32
from bzrlib.decorators import needs_read_lock, needs_write_lock
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
33
from bzrlib.errors import NoSuchRevision
2018.5.127 by Andrew Bennetts
Fix most of the lockable_files tests for RemoteBranchLockableFiles.
34
from bzrlib.lockable_files import LockableFiles
2535.4.20 by Andrew Bennetts
Remove unused import.
35
from bzrlib.pack import ContainerPushParser
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
36
from bzrlib.smart import client, vfs
2697.2.2 by Martin Pool
deprecate Branch.append_revision
37
from bzrlib.symbol_versioning import (
38
    deprecated_method,
39
    zero_ninetyone,
40
    )
3172.3.1 by Robert Collins
Repository has a new method ``has_revisions`` which signals the presence
41
from bzrlib.revision import NULL_REVISION
2018.18.20 by Martin Pool
Route branch operations through remote copy_content_into
42
from bzrlib.trace import note
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
43
2018.5.25 by Andrew Bennetts
Make sure RemoteBzrDirFormat is always registered (John Arbash Meinel, Robert Collins, Andrew Bennetts).
44
# Note: RemoteBzrDirFormat is in bzrdir.py
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
45
46
class RemoteBzrDir(BzrDir):
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
47
    """Control directory on a remote server, accessed via bzr:// or similar."""
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
48
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
49
    def __init__(self, transport, _client=None):
50
        """Construct a RemoteBzrDir.
51
52
        :param _client: Private parameter for testing. Disables probing and the
53
            use of a real bzrdir.
54
        """
1752.2.39 by Martin Pool
[broken] implement upgrade apis on remote bzrdirs
55
        BzrDir.__init__(self, transport, RemoteBzrDirFormat())
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
56
        # this object holds a delegated bzrdir that uses file-level operations
57
        # to talk to the other side
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
58
        self._real_bzrdir = None
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
59
60
        if _client is None:
2485.8.54 by Vincent Ladeuil
Refactor medium uses by making a distinction betweem shared and real medium.
61
            self._shared_medium = transport.get_shared_medium()
62
            self._client = client._SmartClient(self._shared_medium)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
63
        else:
64
            self._client = _client
2485.8.54 by Vincent Ladeuil
Refactor medium uses by making a distinction betweem shared and real medium.
65
            self._shared_medium = None
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
66
            return
67
68
        path = self._path_for_remote_call(self._client)
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
69
        response = self._client.call('BzrDir.open', path)
70
        if response not in [('yes',), ('no',)]:
71
            raise errors.UnexpectedSmartServerResponse(response)
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.
72
        if response == ('no',):
73
            raise errors.NotBranchError(path=transport.base)
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
74
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
75
    def _ensure_real(self):
76
        """Ensure that there is a _real_bzrdir set.
77
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
78
        Used before calls to self._real_bzrdir.
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
79
        """
80
        if not self._real_bzrdir:
2018.5.169 by Andrew Bennetts
Add a _server_formats flag to BzrDir.open_from_transport and BzrDirFormat.find_format, make RemoteBranch.control_files into a property.
81
            self._real_bzrdir = BzrDir.open_from_transport(
82
                self.root_transport, _server_formats=False)
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
83
1752.2.39 by Martin Pool
[broken] implement upgrade apis on remote bzrdirs
84
    def create_repository(self, shared=False):
2018.5.162 by Andrew Bennetts
Add some missing _ensure_real calls, and a missing import.
85
        self._ensure_real()
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
86
        self._real_bzrdir.create_repository(shared=shared)
87
        return self.open_repository()
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
88
2796.2.19 by Aaron Bentley
Support reconfigure --lightweight-checkout
89
    def destroy_repository(self):
90
        """See BzrDir.destroy_repository"""
91
        self._ensure_real()
92
        self._real_bzrdir.destroy_repository()
93
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
94
    def create_branch(self):
2018.5.162 by Andrew Bennetts
Add some missing _ensure_real calls, and a missing import.
95
        self._ensure_real()
1752.2.72 by Andrew Bennetts
Make Remote* classes in remote.py more consistent and remove some dead code.
96
        real_branch = self._real_bzrdir.create_branch()
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
97
        return RemoteBranch(self, self.find_repository(), real_branch)
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
98
2796.2.6 by Aaron Bentley
Implement destroy_branch
99
    def destroy_branch(self):
2796.2.16 by Aaron Bentley
Documentation updates from review
100
        """See BzrDir.destroy_branch"""
2796.2.6 by Aaron Bentley
Implement destroy_branch
101
        self._ensure_real()
102
        self._real_bzrdir.destroy_branch()
103
2955.5.3 by Vincent Ladeuil
Fix second unwanted connection by providing the right branch to create_checkout.
104
    def create_workingtree(self, revision_id=None, from_branch=None):
2018.5.174 by Andrew Bennetts
Various nits discovered by pyflakes.
105
        raise errors.NotLocalUrl(self.transport.base)
1752.2.39 by Martin Pool
[broken] implement upgrade apis on remote bzrdirs
106
2018.5.124 by Robert Collins
Fix test_format_initialize_find_open by delegating Branch formt lookup to the BzrDir, where it should have stayed from the start.
107
    def find_branch_format(self):
108
        """Find the branch 'format' for this bzrdir.
109
110
        This might be a synthetic object for e.g. RemoteBranch and SVN.
111
        """
112
        b = self.open_branch()
113
        return b._format
114
2018.5.132 by Robert Collins
Make all BzrDir implementation tests pass on RemoteBzrDir - fix some things, and remove the incomplete_with_basis tests as cruft.
115
    def get_branch_reference(self):
116
        """See BzrDir.get_branch_reference()."""
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
117
        path = self._path_for_remote_call(self._client)
118
        response = self._client.call('BzrDir.open_branch', path)
119
        if response[0] == 'ok':
120
            if response[1] == '':
121
                # branch at this location.
2018.5.132 by Robert Collins
Make all BzrDir implementation tests pass on RemoteBzrDir - fix some things, and remove the incomplete_with_basis tests as cruft.
122
                return None
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
123
            else:
124
                # a branch reference, use the existing BranchReference logic.
2018.5.132 by Robert Collins
Make all BzrDir implementation tests pass on RemoteBzrDir - fix some things, and remove the incomplete_with_basis tests as cruft.
125
                return response[1]
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
126
        elif response == ('nobranch',):
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
127
            raise errors.NotBranchError(path=self.root_transport.base)
128
        else:
2555.1.1 by Martin Pool
Remove use of 'assert False' to raise an exception unconditionally
129
            raise errors.UnexpectedSmartServerResponse(response)
2018.5.132 by Robert Collins
Make all BzrDir implementation tests pass on RemoteBzrDir - fix some things, and remove the incomplete_with_basis tests as cruft.
130
131
    def open_branch(self, _unsupported=False):
132
        assert _unsupported == False, 'unsupported flag support not implemented yet.'
133
        reference_url = self.get_branch_reference()
134
        if reference_url is None:
135
            # branch at this location.
136
            return RemoteBranch(self, self.find_repository())
137
        else:
138
            # a branch reference, use the existing BranchReference logic.
139
            format = BranchReferenceFormat()
140
            return format.open(self, _found=True, location=reference_url)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
141
                
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
142
    def open_repository(self):
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
143
        path = self._path_for_remote_call(self._client)
144
        response = self._client.call('BzrDir.find_repository', path)
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
145
        assert response[0] in ('ok', 'norepository'), \
2018.5.52 by Wouter van Heyst
Provide more information when encountering unexpected responses from a smart
146
            'unexpected response code %s' % (response,)
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
147
        if response[0] == 'norepository':
148
            raise errors.NoRepositoryPresent(self)
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
149
        assert len(response) == 4, 'incorrect response length %s' % (response,)
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
150
        if response[1] == '':
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
151
            format = RemoteRepositoryFormat()
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
152
            format.rich_root_data = (response[2] == 'yes')
153
            format.supports_tree_reference = (response[3] == 'yes')
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
154
            return RemoteRepository(self, format)
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
155
        else:
156
            raise errors.NoRepositoryPresent(self)
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
157
2018.5.138 by Robert Collins
Merge bzr.dev.
158
    def open_workingtree(self, recommend_upgrade=True):
2445.1.1 by Andrew Bennetts
Make RemoteBzrDir.open_workingtree raise NoWorkingTree rather than NotLocalUrl
159
        self._ensure_real()
160
        if self._real_bzrdir.has_workingtree():
161
            raise errors.NotLocalUrl(self.root_transport)
162
        else:
163
            raise errors.NoWorkingTree(self.root_transport.base)
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
164
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
165
    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.
166
        """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 :).
167
        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.
168
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
169
    def get_branch_transport(self, branch_format):
2018.5.162 by Andrew Bennetts
Add some missing _ensure_real calls, and a missing import.
170
        self._ensure_real()
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
171
        return self._real_bzrdir.get_branch_transport(branch_format)
172
1752.2.43 by Andrew Bennetts
Fix get_{branch,repository,workingtree}_transport.
173
    def get_repository_transport(self, repository_format):
2018.5.162 by Andrew Bennetts
Add some missing _ensure_real calls, and a missing import.
174
        self._ensure_real()
1752.2.43 by Andrew Bennetts
Fix get_{branch,repository,workingtree}_transport.
175
        return self._real_bzrdir.get_repository_transport(repository_format)
176
177
    def get_workingtree_transport(self, workingtree_format):
2018.5.162 by Andrew Bennetts
Add some missing _ensure_real calls, and a missing import.
178
        self._ensure_real()
1752.2.43 by Andrew Bennetts
Fix get_{branch,repository,workingtree}_transport.
179
        return self._real_bzrdir.get_workingtree_transport(workingtree_format)
180
1752.2.39 by Martin Pool
[broken] implement upgrade apis on remote bzrdirs
181
    def can_convert_format(self):
182
        """Upgrading of remote bzrdirs is not supported yet."""
183
        return False
184
185
    def needs_format_conversion(self, format=None):
186
        """Upgrading of remote bzrdirs is not supported yet."""
187
        return False
188
2018.5.138 by Robert Collins
Merge bzr.dev.
189
    def clone(self, url, revision_id=None, force_new_repo=False):
2018.5.94 by Andrew Bennetts
Various small changes in aid of making tests pass (including deleting one invalid test).
190
        self._ensure_real()
191
        return self._real_bzrdir.clone(url, revision_id=revision_id,
2018.5.138 by Robert Collins
Merge bzr.dev.
192
            force_new_repo=force_new_repo)
2018.5.94 by Andrew Bennetts
Various small changes in aid of making tests pass (including deleting one invalid test).
193
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
194
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
195
class RemoteRepositoryFormat(repository.RepositoryFormat):
2018.5.159 by Andrew Bennetts
Rename SmartClient to _SmartClient.
196
    """Format for repositories accessed over a _SmartClient.
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
197
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
198
    Instances of this repository are represented by RemoteRepository
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
199
    instances.
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
200
3128.1.3 by Vincent Ladeuil
Since we are there s/parameteris.*/parameteriz&/.
201
    The RemoteRepositoryFormat is parameterized during construction
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
202
    to reflect the capabilities of the real, remote format. Specifically
2018.5.138 by Robert Collins
Merge bzr.dev.
203
    the attributes rich_root_data and supports_tree_reference are set
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
204
    on a per instance basis, and are not set (and should not be) at
205
    the class level.
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
206
    """
207
208
    _matchingbzrdir = RemoteBzrDirFormat
209
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
210
    def initialize(self, a_bzrdir, shared=False):
2018.5.138 by Robert Collins
Merge bzr.dev.
211
        assert isinstance(a_bzrdir, RemoteBzrDir), \
212
            '%r is not a RemoteBzrDir' % (a_bzrdir,)
1752.2.72 by Andrew Bennetts
Make Remote* classes in remote.py more consistent and remove some dead code.
213
        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.
214
    
215
    def open(self, a_bzrdir):
1752.2.72 by Andrew Bennetts
Make Remote* classes in remote.py more consistent and remove some dead code.
216
        assert isinstance(a_bzrdir, RemoteBzrDir)
217
        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.
218
219
    def get_format_description(self):
220
        return 'bzr remote repository'
221
222
    def __eq__(self, other):
1752.2.87 by Andrew Bennetts
Make tests pass.
223
        return self.__class__ == other.__class__
224
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
225
    def check_conversion_target(self, target_format):
226
        if self.rich_root_data and not target_format.rich_root_data:
227
            raise errors.BadConversionTarget(
228
                'Does not support rich root data.', target_format)
2018.5.138 by Robert Collins
Merge bzr.dev.
229
        if (self.supports_tree_reference and
230
            not getattr(target_format, 'supports_tree_reference', False)):
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
231
            raise errors.BadConversionTarget(
232
                'Does not support nested trees', target_format)
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
233
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
234
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
235
class RemoteRepository(object):
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
236
    """Repository accessed over rpc.
237
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
238
    For the moment most operations are performed using local transport-backed
239
    Repository objects.
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
240
    """
241
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
242
    def __init__(self, remote_bzrdir, format, 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.
243
        """Create a RemoteRepository instance.
244
        
245
        :param remote_bzrdir: The bzrdir hosting this repository.
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
246
        :param format: The RemoteFormat object to use.
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
247
        :param real_repository: If not None, a local implementation of the
248
            repository logic for the repository, usually accessing the data
249
            via the VFS.
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
250
        :param _client: Private testing parameter - override the smart client
251
            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.
252
        """
253
        if real_repository:
2018.5.36 by Andrew Bennetts
Fix typo, and clean up some ununsed import warnings from pyflakes at the same time.
254
            self._real_repository = real_repository
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
255
        else:
256
            self._real_repository = None
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
257
        self.bzrdir = remote_bzrdir
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
258
        if _client is None:
2485.8.54 by Vincent Ladeuil
Refactor medium uses by making a distinction betweem shared and real medium.
259
            self._client = client._SmartClient(self.bzrdir._shared_medium)
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
260
        else:
261
            self._client = _client
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
262
        self._format = format
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
263
        self._lock_mode = None
264
        self._lock_token = None
265
        self._lock_count = 0
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
266
        self._leave_lock = False
2951.1.10 by Robert Collins
Peer review feedback with Ian.
267
        # For tests:
268
        # These depend on the actual remote format, so force them off for
269
        # maximum compatibility. XXX: In future these should depend on the
270
        # remote repository instance, but this is irrelevant until we perform
271
        # reconcile via an RPC call.
2951.1.5 by Robert Collins
Some work towards including the correct changes for TREE_ROOT in check parameterised tests.
272
        self._reconcile_does_inventory_gc = False
273
        self._reconcile_fixes_text_parents = False
2951.1.3 by Robert Collins
Partial support for native reconcile with packs.
274
        self._reconcile_backsup_inventory = False
2592.4.5 by Martin Pool
Add Repository.base on all repositories.
275
        self.base = self.bzrdir.transport.base
276
277
    def __str__(self):
278
        return "%s(%s)" % (self.__class__.__name__, self.base)
279
280
    __repr__ = __str__
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
281
2617.6.2 by Robert Collins
Add abort_write_group and wire write_groups into fetch and commit.
282
    def abort_write_group(self):
2617.6.7 by Robert Collins
More review feedback.
283
        """Complete a write group on the decorated repository.
2617.6.2 by Robert Collins
Add abort_write_group and wire write_groups into fetch and commit.
284
        
285
        Smart methods peform operations in a single step so this api
2617.6.6 by Robert Collins
Some review feedback.
286
        is not really applicable except as a compatibility thunk
2617.6.2 by Robert Collins
Add abort_write_group and wire write_groups into fetch and commit.
287
        for older plugins that don't use e.g. the CommitBuilder
288
        facility.
289
        """
290
        self._ensure_real()
291
        return self._real_repository.abort_write_group()
292
293
    def commit_write_group(self):
2617.6.7 by Robert Collins
More review feedback.
294
        """Complete a write group on the decorated repository.
2617.6.2 by Robert Collins
Add abort_write_group and wire write_groups into fetch and commit.
295
        
296
        Smart methods peform operations in a single step so this api
2617.6.6 by Robert Collins
Some review feedback.
297
        is not really applicable except as a compatibility thunk
2617.6.2 by Robert Collins
Add abort_write_group and wire write_groups into fetch and commit.
298
        for older plugins that don't use e.g. the CommitBuilder
299
        facility.
300
        """
301
        self._ensure_real()
302
        return self._real_repository.commit_write_group()
2617.6.1 by Robert Collins
* New method on Repository - ``start_write_group``, ``end_write_group``
303
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
304
    def _ensure_real(self):
305
        """Ensure that there is a _real_repository set.
306
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
307
        Used before calls to self._real_repository.
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
308
        """
309
        if not self._real_repository:
310
            self.bzrdir._ensure_real()
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
311
            #self._real_repository = self.bzrdir._real_bzrdir.open_repository()
312
            self._set_real_repository(self.bzrdir._real_bzrdir.open_repository())
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
313
2988.1.2 by Robert Collins
New Repository API find_text_key_references for use by reconcile and check.
314
    def find_text_key_references(self):
315
        """Find the text key references within the repository.
316
317
        :return: a dictionary mapping (file_id, revision_id) tuples to altered file-ids to an iterable of
318
        revision_ids. Each altered file-ids has the exact revision_ids that
319
        altered it listed explicitly.
320
        :return: A dictionary mapping text keys ((fileid, revision_id) tuples)
321
            to whether they were referred to by the inventory of the
322
            revision_id that they contain. The inventory texts from all present
323
            revision ids are assessed to generate this report.
324
        """
325
        self._ensure_real()
326
        return self._real_repository.find_text_key_references()
327
2988.1.3 by Robert Collins
Add a new repositoy method _generate_text_key_index for use by reconcile/check.
328
    def _generate_text_key_index(self):
329
        """Generate a new text key index for the repository.
330
331
        This is an expensive function that will take considerable time to run.
332
333
        :return: A dict mapping (file_id, revision_id) tuples to a list of
334
            parents, also (file_id, revision_id) tuples.
335
        """
336
        self._ensure_real()
337
        return self._real_repository._generate_text_key_index()
338
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
339
    def get_revision_graph(self, revision_id=None):
340
        """See Repository.get_revision_graph()."""
341
        if revision_id is None:
342
            revision_id = ''
2948.3.1 by John Arbash Meinel
Fix bug #158333, make sure that Repository.fetch(self) is properly a no-op for all Repository implementations.
343
        elif revision.is_null(revision_id):
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
344
            return {}
345
346
        path = self.bzrdir._path_for_remote_call(self._client)
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
347
        assert type(revision_id) is str
2018.5.153 by Andrew Bennetts
Rename call2 to call_expecting_body, and other small changes prompted by review.
348
        response = self._client.call_expecting_body(
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
349
            'Repository.get_revision_graph', path, revision_id)
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
350
        if response[0][0] not in ['ok', 'nosuchrevision']:
351
            raise errors.UnexpectedSmartServerResponse(response[0])
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
352
        if response[0][0] == 'ok':
353
            coded = response[1].read_body_bytes()
2018.5.105 by Andrew Bennetts
Implement revision_history caching for RemoteBranch.
354
            if coded == '':
355
                # no revisions in this repository!
356
                return {}
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
357
            lines = coded.split('\n')
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
358
            revision_graph = {}
359
            for line in lines:
2625.8.1 by Robert Collins
LIBRARY API BREAKS:
360
                d = tuple(line.split())
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
361
                revision_graph[d[0]] = d[1:]
362
                
363
            return revision_graph
364
        else:
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
365
            response_body = response[1].read_body_bytes()
366
            assert response_body == ''
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
367
            raise NoSuchRevision(self, revision_id)
368
2018.5.40 by Robert Collins
Implement a remote Repository.has_revision method.
369
    def has_revision(self, revision_id):
370
        """See Repository.has_revision()."""
3172.3.1 by Robert Collins
Repository has a new method ``has_revisions`` which signals the presence
371
        if revision_id == NULL_REVISION:
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
372
            # The null revision is always present.
373
            return True
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
374
        path = self.bzrdir._path_for_remote_call(self._client)
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
375
        response = self._client.call('Repository.has_revision', path, revision_id)
2018.5.158 by Andrew Bennetts
Return 'yes'/'no' rather than 'ok'/'no' from the Repository.has_revision smart command.
376
        assert response[0] in ('yes', 'no'), 'unexpected response code %s' % (response,)
377
        return response[0] == 'yes'
2018.5.40 by Robert Collins
Implement a remote Repository.has_revision method.
378
3172.3.1 by Robert Collins
Repository has a new method ``has_revisions`` which signals the presence
379
    def has_revisions(self, revision_ids):
380
        """See Repository.has_revisions()."""
381
        result = set()
382
        for revision_id in revision_ids:
383
            if self.has_revision(revision_id):
384
                result.add(revision_id)
385
        return result
386
2617.6.9 by Robert Collins
Merge bzr.dev.
387
    def has_same_location(self, other):
2592.3.162 by Robert Collins
Remove some arbitrary differences from bzr.dev.
388
        return (self.__class__ == other.__class__ and
389
                self.bzrdir.transport.base == other.bzrdir.transport.base)
2617.6.9 by Robert Collins
Merge bzr.dev.
390
        
2490.2.21 by Aaron Bentley
Rename graph to deprecated_graph
391
    def get_graph(self, other_repository=None):
392
        """Return the graph for this repository format"""
2850.4.1 by Andrew Bennetts
Add smoketest for repo.get_graph, and fix bug in RemoteRepository.get_graph that it reveals.
393
        self._ensure_real()
2490.2.21 by Aaron Bentley
Rename graph to deprecated_graph
394
        return self._real_repository.get_graph(other_repository)
2490.2.5 by Aaron Bentley
Use GraphWalker.unique_ancestor to determine merge base
395
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
396
    def gather_stats(self, revid=None, committers=None):
2018.5.62 by Robert Collins
Stub out RemoteRepository.gather_stats while its implemented in parallel.
397
        """See Repository.gather_stats()."""
2018.10.3 by v.ladeuil+lp at free
more tests for gather_stats
398
        path = self.bzrdir._path_for_remote_call(self._client)
2948.3.4 by John Arbash Meinel
Repository.gather_stats() validly can get None for the revid.
399
        # revid can be None to indicate no revisions, not just NULL_REVISION
400
        if revid is None or revision.is_null(revid):
2018.10.3 by v.ladeuil+lp at free
more tests for gather_stats
401
            fmt_revid = ''
402
        else:
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
403
            fmt_revid = revid
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
404
        if committers is None or not committers:
2018.10.3 by v.ladeuil+lp at free
more tests for gather_stats
405
            fmt_committers = 'no'
406
        else:
407
            fmt_committers = 'yes'
2018.5.153 by Andrew Bennetts
Rename call2 to call_expecting_body, and other small changes prompted by review.
408
        response = self._client.call_expecting_body(
409
            'Repository.gather_stats', path, fmt_revid, fmt_committers)
2018.10.3 by v.ladeuil+lp at free
more tests for gather_stats
410
        assert response[0][0] == 'ok', \
411
            'unexpected response code %s' % (response[0],)
412
413
        body = response[1].read_body_bytes()
414
        result = {}
415
        for line in body.split('\n'):
416
            if not line:
417
                continue
418
            key, val_text = line.split(':')
419
            if key in ('revisions', 'size', 'committers'):
420
                result[key] = int(val_text)
421
            elif key in ('firstrev', 'latestrev'):
422
                values = val_text.split(' ')[1:]
423
                result[key] = (float(values[0]), long(values[1]))
424
425
        return result
2018.5.62 by Robert Collins
Stub out RemoteRepository.gather_stats while its implemented in parallel.
426
3140.1.2 by Aaron Bentley
Add ability to find branches inside repositories
427
    def find_branches(self, using=False):
428
        """See Repository.find_branches()."""
429
        # should be an API call to the server.
430
        self._ensure_real()
431
        return self._real_repository.find_branches(using=using)
432
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
433
    def get_physical_lock_status(self):
434
        """See Repository.get_physical_lock_status()."""
3015.2.10 by Robert Collins
Fix regression due to other pack related fixes in tests with packs not-default.
435
        # should be an API call to the server.
436
        self._ensure_real()
437
        return self._real_repository.get_physical_lock_status()
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
438
2617.6.1 by Robert Collins
* New method on Repository - ``start_write_group``, ``end_write_group``
439
    def is_in_write_group(self):
440
        """Return True if there is an open write group.
441
442
        write groups are only applicable locally for the smart server..
443
        """
444
        if self._real_repository:
445
            return self._real_repository.is_in_write_group()
446
447
    def is_locked(self):
448
        return self._lock_count >= 1
449
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
450
    def is_shared(self):
451
        """See Repository.is_shared()."""
452
        path = self.bzrdir._path_for_remote_call(self._client)
453
        response = self._client.call('Repository.is_shared', path)
454
        assert response[0] in ('yes', 'no'), 'unexpected response code %s' % (response,)
455
        return response[0] == 'yes'
456
2904.1.1 by Robert Collins
* New method ``bzrlib.repository.Repository.is_write_locked`` useful for
457
    def is_write_locked(self):
458
        return self._lock_mode == 'w'
459
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
460
    def lock_read(self):
461
        # wrong eventually - want a local lock cache context
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
462
        if not self._lock_mode:
463
            self._lock_mode = 'r'
464
            self._lock_count = 1
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
465
            if self._real_repository is not None:
466
                self._real_repository.lock_read()
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
467
        else:
468
            self._lock_count += 1
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
469
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
470
    def _remote_lock_write(self, token):
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
471
        path = self.bzrdir._path_for_remote_call(self._client)
472
        if token is None:
473
            token = ''
474
        response = self._client.call('Repository.lock_write', path, token)
475
        if response[0] == 'ok':
476
            ok, token = response
477
            return token
478
        elif response[0] == 'LockContention':
479
            raise errors.LockContention('(remote lock)')
2018.5.95 by Andrew Bennetts
Add a Transport.is_readonly remote call, let {Branch,Repository}.lock_write remote call return UnlockableTransport, and miscellaneous test fixes.
480
        elif response[0] == 'UnlockableTransport':
481
            raise errors.UnlockableTransport(self.bzrdir.root_transport)
2872.5.3 by Martin Pool
Pass back LockFailed from smart server lock methods
482
        elif response[0] == 'LockFailed':
483
            raise errors.LockFailed(response[1], response[2])
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
484
        else:
2555.1.1 by Martin Pool
Remove use of 'assert False' to raise an exception unconditionally
485
            raise errors.UnexpectedSmartServerResponse(response)
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
486
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
487
    def lock_write(self, token=None):
488
        if not self._lock_mode:
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
489
            self._lock_token = self._remote_lock_write(token)
3015.2.9 by Robert Collins
Handle repositories that do not allow remote locking, like pack repositories, in the client side remote server proxy objects.
490
            # if self._lock_token is None, then this is something like packs or
491
            # svn where we don't get to lock the repo, or a weave style repository
492
            # where we cannot lock it over the wire and attempts to do so will
493
            # fail.
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
494
            if self._real_repository is not None:
495
                self._real_repository.lock_write(token=self._lock_token)
496
            if token is not None:
497
                self._leave_lock = True
498
            else:
499
                self._leave_lock = False
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
500
            self._lock_mode = 'w'
501
            self._lock_count = 1
502
        elif self._lock_mode == 'r':
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
503
            raise errors.ReadOnlyError(self)
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
504
        else:
505
            self._lock_count += 1
3015.2.9 by Robert Collins
Handle repositories that do not allow remote locking, like pack repositories, in the client side remote server proxy objects.
506
        return self._lock_token or None
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
507
508
    def leave_lock_in_place(self):
3015.2.9 by Robert Collins
Handle repositories that do not allow remote locking, like pack repositories, in the client side remote server proxy objects.
509
        if not self._lock_token:
510
            raise NotImplementedError(self.leave_lock_in_place)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
511
        self._leave_lock = True
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
512
513
    def dont_leave_lock_in_place(self):
3015.2.9 by Robert Collins
Handle repositories that do not allow remote locking, like pack repositories, in the client side remote server proxy objects.
514
        if not self._lock_token:
3015.2.15 by Robert Collins
Review feedback.
515
            raise NotImplementedError(self.dont_leave_lock_in_place)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
516
        self._leave_lock = False
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
517
518
    def _set_real_repository(self, repository):
519
        """Set the _real_repository for this repository.
520
521
        :param repository: The repository to fallback to for non-hpss
522
            implemented operations.
523
        """
2018.5.97 by Andrew Bennetts
Fix more tests.
524
        assert not isinstance(repository, RemoteRepository)
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
525
        self._real_repository = repository
526
        if self._lock_mode == 'w':
527
            # if we are already locked, the real repository must be able to
528
            # acquire the lock with our token.
529
            self._real_repository.lock_write(self._lock_token)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
530
        elif self._lock_mode == 'r':
531
            self._real_repository.lock_read()
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
532
2617.6.1 by Robert Collins
* New method on Repository - ``start_write_group``, ``end_write_group``
533
    def start_write_group(self):
534
        """Start a write group on the decorated repository.
535
        
536
        Smart methods peform operations in a single step so this api
2617.6.6 by Robert Collins
Some review feedback.
537
        is not really applicable except as a compatibility thunk
2617.6.1 by Robert Collins
* New method on Repository - ``start_write_group``, ``end_write_group``
538
        for older plugins that don't use e.g. the CommitBuilder
539
        facility.
540
        """
541
        self._ensure_real()
542
        return self._real_repository.start_write_group()
543
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
544
    def _unlock(self, token):
545
        path = self.bzrdir._path_for_remote_call(self._client)
3015.2.9 by Robert Collins
Handle repositories that do not allow remote locking, like pack repositories, in the client side remote server proxy objects.
546
        if not token:
547
            # with no token the remote repository is not persistently locked.
548
            return
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
549
        response = self._client.call('Repository.unlock', path, token)
550
        if response == ('ok',):
551
            return
552
        elif response[0] == 'TokenMismatch':
553
            raise errors.TokenMismatch(token, '(remote token)')
554
        else:
2555.1.1 by Martin Pool
Remove use of 'assert False' to raise an exception unconditionally
555
            raise errors.UnexpectedSmartServerResponse(response)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
556
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
557
    def unlock(self):
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
558
        self._lock_count -= 1
2592.3.244 by Martin Pool
unlock while in a write group now aborts the write group, unlocks, and errors.
559
        if self._lock_count > 0:
560
            return
561
        old_mode = self._lock_mode
562
        self._lock_mode = None
563
        try:
564
            # The real repository is responsible at present for raising an
565
            # exception if it's in an unfinished write group.  However, it
566
            # normally will *not* actually remove the lock from disk - that's
567
            # done by the server on receiving the Repository.unlock call.
568
            # This is just to let the _real_repository stay up to date.
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
569
            if self._real_repository is not None:
570
                self._real_repository.unlock()
2592.3.244 by Martin Pool
unlock while in a write group now aborts the write group, unlocks, and errors.
571
        finally:
572
            # The rpc-level lock should be released even if there was a
573
            # problem releasing the vfs-based lock.
574
            if old_mode == 'w':
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
575
                # Only write-locked repositories need to make a remote method
576
                # call to perfom the unlock.
2592.3.244 by Martin Pool
unlock while in a write group now aborts the write group, unlocks, and errors.
577
                old_token = self._lock_token
578
                self._lock_token = None
579
                if not self._leave_lock:
580
                    self._unlock(old_token)
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
581
582
    def break_lock(self):
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
583
        # should hand off to the network
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
584
        self._ensure_real()
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
585
        return self._real_repository.break_lock()
586
2018.18.8 by Ian Clatworthy
Tarball proxy code & tests
587
    def _get_tarball(self, compression):
2814.10.2 by Andrew Bennetts
Make the fallback a little tidier.
588
        """Return a TemporaryFile containing a repository tarball.
589
        
590
        Returns None if the server does not support sending tarballs.
591
        """
2018.18.25 by Martin Pool
Repository.tarball fixes for python2.4
592
        import tempfile
2018.18.8 by Ian Clatworthy
Tarball proxy code & tests
593
        path = self.bzrdir._path_for_remote_call(self._client)
2018.18.14 by Martin Pool
merge hpss again; restore incorrectly removed RemoteRepository.break_lock
594
        response, protocol = self._client.call_expecting_body(
595
            'Repository.tarball', path, compression)
2018.18.8 by Ian Clatworthy
Tarball proxy code & tests
596
        if response[0] == 'ok':
597
            # Extract the tarball and return it
2018.18.25 by Martin Pool
Repository.tarball fixes for python2.4
598
            t = tempfile.NamedTemporaryFile()
599
            # TODO: rpc layer should read directly into it...
600
            t.write(protocol.read_body_bytes())
601
            t.seek(0)
602
            return t
2814.10.1 by Andrew Bennetts
Cope gracefully if the server doesn't support the Repository.tarball smart request.
603
        if (response == ('error', "Generic bzr smart protocol error: "
604
                "bad request 'Repository.tarball'") or
605
              response == ('error', "Generic bzr smart protocol error: "
606
                "bad request u'Repository.tarball'")):
607
            protocol.cancel_read_body()
2814.10.2 by Andrew Bennetts
Make the fallback a little tidier.
608
            return None
2814.10.1 by Andrew Bennetts
Cope gracefully if the server doesn't support the Repository.tarball smart request.
609
        raise errors.UnexpectedSmartServerResponse(response)
2018.18.8 by Ian Clatworthy
Tarball proxy code & tests
610
2440.1.1 by Martin Pool
Add new Repository.sprout,
611
    def sprout(self, to_bzrdir, revision_id=None):
612
        # TODO: Option to control what format is created?
3047.1.1 by Andrew Bennetts
Fix for bug 164626, add test that Repository.sprout preserves format.
613
        self._ensure_real()
3047.1.4 by Andrew Bennetts
Simplify RemoteRepository.sprout thanks to review comments.
614
        dest_repo = self._real_repository._format.initialize(to_bzrdir,
615
                                                             shared=False)
2535.3.17 by Andrew Bennetts
[broken] Closer to a working Repository.fetch_revisions smart request.
616
        dest_repo.fetch(self, revision_id=revision_id)
617
        return dest_repo
2440.1.1 by Martin Pool
Add new Repository.sprout,
618
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
619
    ### These methods are just thin shims to the VFS object for now.
620
621
    def revision_tree(self, revision_id):
622
        self._ensure_real()
623
        return self._real_repository.revision_tree(revision_id)
624
2520.4.113 by Aaron Bentley
Avoid peeking at Repository._serializer
625
    def get_serializer_format(self):
626
        self._ensure_real()
627
        return self._real_repository.get_serializer_format()
628
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
629
    def get_commit_builder(self, branch, parents, config, timestamp=None,
630
                           timezone=None, committer=None, revprops=None,
631
                           revision_id=None):
632
        # FIXME: It ought to be possible to call this without immediately
633
        # triggering _ensure_real.  For now it's the easiest thing to do.
634
        self._ensure_real()
635
        builder = self._real_repository.get_commit_builder(branch, parents,
636
                config, timestamp=timestamp, timezone=timezone,
637
                committer=committer, revprops=revprops, revision_id=revision_id)
638
        return builder
639
640
    @needs_write_lock
641
    def add_inventory(self, revid, inv, parents):
642
        self._ensure_real()
643
        return self._real_repository.add_inventory(revid, inv, parents)
644
645
    @needs_write_lock
646
    def add_revision(self, rev_id, rev, inv=None, config=None):
647
        self._ensure_real()
648
        return self._real_repository.add_revision(
649
            rev_id, rev, inv=inv, config=config)
650
651
    @needs_read_lock
652
    def get_inventory(self, revision_id):
653
        self._ensure_real()
654
        return self._real_repository.get_inventory(revision_id)
655
3169.2.1 by Robert Collins
New method ``iter_inventories`` on Repository for access to many
656
    def iter_inventories(self, revision_ids):
657
        self._ensure_real()
658
        return self._real_repository.iter_inventories(revision_ids)
659
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
660
    @needs_read_lock
661
    def get_revision(self, revision_id):
662
        self._ensure_real()
663
        return self._real_repository.get_revision(revision_id)
664
665
    @property
666
    def weave_store(self):
667
        self._ensure_real()
668
        return self._real_repository.weave_store
669
670
    def get_transaction(self):
671
        self._ensure_real()
672
        return self._real_repository.get_transaction()
673
674
    @needs_read_lock
2018.5.138 by Robert Collins
Merge bzr.dev.
675
    def clone(self, a_bzrdir, revision_id=None):
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
676
        self._ensure_real()
2018.5.138 by Robert Collins
Merge bzr.dev.
677
        return self._real_repository.clone(a_bzrdir, revision_id=revision_id)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
678
679
    def make_working_trees(self):
2018.5.120 by Robert Collins
The Repository API ``make_working_trees`` is now permitted to return
680
        """RemoteRepositories never create working trees by default."""
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
681
        return False
682
683
    def fetch(self, source, revision_id=None, pb=None):
2881.4.1 by Robert Collins
Move responsibility for detecting same-repo fetching from the
684
        if self.has_same_location(source):
685
            # check that last_revision is in 'from' and then return a
686
            # no-operation.
687
            if (revision_id is not None and
2948.3.1 by John Arbash Meinel
Fix bug #158333, make sure that Repository.fetch(self) is properly a no-op for all Repository implementations.
688
                not revision.is_null(revision_id)):
2881.4.1 by Robert Collins
Move responsibility for detecting same-repo fetching from the
689
                self.get_revision(revision_id)
2592.4.5 by Martin Pool
Add Repository.base on all repositories.
690
            return 0, []
2592.3.119 by Robert Collins
Merge some test fixes from Martin.
691
        self._ensure_real()
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
692
        return self._real_repository.fetch(
693
            source, revision_id=revision_id, pb=pb)
694
2520.4.54 by Aaron Bentley
Hang a create_bundle method off repository
695
    def create_bundle(self, target, base, fileobj, format=None):
696
        self._ensure_real()
697
        self._real_repository.create_bundle(target, base, fileobj, format)
698
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
699
    @property
700
    def control_weaves(self):
701
        self._ensure_real()
702
        return self._real_repository.control_weaves
703
704
    @needs_read_lock
2530.1.1 by Aaron Bentley
Make topological sorting optional for get_ancestry
705
    def get_ancestry(self, revision_id, topo_sorted=True):
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
706
        self._ensure_real()
2530.1.1 by Aaron Bentley
Make topological sorting optional for get_ancestry
707
        return self._real_repository.get_ancestry(revision_id, topo_sorted)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
708
709
    @needs_read_lock
710
    def get_inventory_weave(self):
711
        self._ensure_real()
712
        return self._real_repository.get_inventory_weave()
713
714
    def fileids_altered_by_revision_ids(self, revision_ids):
715
        self._ensure_real()
716
        return self._real_repository.fileids_altered_by_revision_ids(revision_ids)
717
3036.1.3 by Robert Collins
Privatise VersionedFileChecker.
718
    def _get_versioned_file_checker(self, revisions, revision_versions_cache):
2745.6.1 by Aaron Bentley
Initial checking of knit graphs
719
        self._ensure_real()
3036.1.3 by Robert Collins
Privatise VersionedFileChecker.
720
        return self._real_repository._get_versioned_file_checker(
2745.6.50 by Andrew Bennetts
Remove find_bad_ancestors; it's not needed anymore.
721
            revisions, revision_versions_cache)
722
        
2708.1.7 by Aaron Bentley
Rename extract_files_bytes to iter_files_bytes
723
    def iter_files_bytes(self, desired_files):
2708.1.9 by Aaron Bentley
Clean-up docs and imports
724
        """See Repository.iter_file_bytes.
2708.1.3 by Aaron Bentley
Implement extract_files_bytes on Repository
725
        """
726
        self._ensure_real()
2708.1.7 by Aaron Bentley
Rename extract_files_bytes to iter_files_bytes
727
        return self._real_repository.iter_files_bytes(desired_files)
2708.1.3 by Aaron Bentley
Implement extract_files_bytes on Repository
728
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
729
    @needs_read_lock
730
    def get_signature_text(self, revision_id):
731
        self._ensure_real()
732
        return self._real_repository.get_signature_text(revision_id)
733
734
    @needs_read_lock
735
    def get_revision_graph_with_ghosts(self, revision_ids=None):
736
        self._ensure_real()
737
        return self._real_repository.get_revision_graph_with_ghosts(
738
            revision_ids=revision_ids)
739
740
    @needs_read_lock
741
    def get_inventory_xml(self, revision_id):
742
        self._ensure_real()
743
        return self._real_repository.get_inventory_xml(revision_id)
744
745
    def deserialise_inventory(self, revision_id, xml):
746
        self._ensure_real()
747
        return self._real_repository.deserialise_inventory(revision_id, xml)
748
749
    def reconcile(self, other=None, thorough=False):
750
        self._ensure_real()
751
        return self._real_repository.reconcile(other=other, thorough=thorough)
752
        
753
    def all_revision_ids(self):
754
        self._ensure_real()
755
        return self._real_repository.all_revision_ids()
756
    
757
    @needs_read_lock
758
    def get_deltas_for_revisions(self, revisions):
759
        self._ensure_real()
760
        return self._real_repository.get_deltas_for_revisions(revisions)
761
762
    @needs_read_lock
763
    def get_revision_delta(self, revision_id):
764
        self._ensure_real()
765
        return self._real_repository.get_revision_delta(revision_id)
766
767
    @needs_read_lock
768
    def revision_trees(self, revision_ids):
769
        self._ensure_real()
770
        return self._real_repository.revision_trees(revision_ids)
771
772
    @needs_read_lock
773
    def get_revision_reconcile(self, revision_id):
774
        self._ensure_real()
775
        return self._real_repository.get_revision_reconcile(revision_id)
776
777
    @needs_read_lock
2745.6.36 by Andrew Bennetts
Deprecate revision_ids arg to Repository.check and other tweaks.
778
    def check(self, revision_ids=None):
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
779
        self._ensure_real()
2745.6.36 by Andrew Bennetts
Deprecate revision_ids arg to Repository.check and other tweaks.
780
        return self._real_repository.check(revision_ids=revision_ids)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
781
2018.5.138 by Robert Collins
Merge bzr.dev.
782
    def copy_content_into(self, destination, revision_id=None):
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
783
        self._ensure_real()
784
        return self._real_repository.copy_content_into(
2018.5.138 by Robert Collins
Merge bzr.dev.
785
            destination, revision_id=revision_id)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
786
2814.10.2 by Andrew Bennetts
Make the fallback a little tidier.
787
    def _copy_repository_tarball(self, to_bzrdir, revision_id=None):
2018.18.10 by Martin Pool
copy_content_into from Remote repositories by using temporary directories on both ends.
788
        # get a tarball of the remote repository, and copy from that into the
789
        # destination
790
        from bzrlib import osutils
2018.18.9 by Martin Pool
remote Repository.tarball builds a temporary directory and tars that
791
        import tarfile
2018.18.10 by Martin Pool
copy_content_into from Remote repositories by using temporary directories on both ends.
792
        import tempfile
2018.18.20 by Martin Pool
Route branch operations through remote copy_content_into
793
        # TODO: Maybe a progress bar while streaming the tarball?
794
        note("Copying repository content as tarball...")
2018.18.25 by Martin Pool
Repository.tarball fixes for python2.4
795
        tar_file = self._get_tarball('bz2')
2814.10.2 by Andrew Bennetts
Make the fallback a little tidier.
796
        if tar_file is None:
797
            return None
798
        destination = to_bzrdir.create_repository()
2018.18.10 by Martin Pool
copy_content_into from Remote repositories by using temporary directories on both ends.
799
        try:
2018.18.25 by Martin Pool
Repository.tarball fixes for python2.4
800
            tar = tarfile.open('repository', fileobj=tar_file,
801
                mode='r|bz2')
802
            tmpdir = tempfile.mkdtemp()
803
            try:
804
                _extract_tar(tar, tmpdir)
805
                tmp_bzrdir = BzrDir.open(tmpdir)
806
                tmp_repo = tmp_bzrdir.open_repository()
807
                tmp_repo.copy_content_into(destination, revision_id)
808
            finally:
809
                osutils.rmtree(tmpdir)
2018.18.10 by Martin Pool
copy_content_into from Remote repositories by using temporary directories on both ends.
810
        finally:
2018.18.25 by Martin Pool
Repository.tarball fixes for python2.4
811
            tar_file.close()
2814.10.2 by Andrew Bennetts
Make the fallback a little tidier.
812
        return destination
2018.18.23 by Martin Pool
review cleanups
813
        # TODO: Suggestion from john: using external tar is much faster than
814
        # python's tarfile library, but it may not work on windows.
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
815
2604.2.1 by Robert Collins
(robertc) Introduce a pack command.
816
    @needs_write_lock
817
    def pack(self):
818
        """Compress the data within the repository.
819
820
        This is not currently implemented within the smart server.
821
        """
822
        self._ensure_real()
823
        return self._real_repository.pack()
824
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
825
    def set_make_working_trees(self, new_value):
826
        raise NotImplementedError(self.set_make_working_trees)
827
828
    @needs_write_lock
829
    def sign_revision(self, revision_id, gpg_strategy):
830
        self._ensure_real()
831
        return self._real_repository.sign_revision(revision_id, gpg_strategy)
832
833
    @needs_read_lock
834
    def get_revisions(self, revision_ids):
835
        self._ensure_real()
836
        return self._real_repository.get_revisions(revision_ids)
837
838
    def supports_rich_root(self):
2018.5.84 by Andrew Bennetts
Merge in supports-rich-root, another test passing.
839
        self._ensure_real()
840
        return self._real_repository.supports_rich_root()
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
841
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
842
    def iter_reverse_revision_history(self, revision_id):
843
        self._ensure_real()
844
        return self._real_repository.iter_reverse_revision_history(revision_id)
845
2018.5.96 by Andrew Bennetts
Merge from bzr.dev, resolving the worst of the semantic conflicts, but there's
846
    @property
847
    def _serializer(self):
848
        self._ensure_real()
849
        return self._real_repository._serializer
850
2018.5.97 by Andrew Bennetts
Fix more tests.
851
    def store_revision_signature(self, gpg_strategy, plaintext, revision_id):
852
        self._ensure_real()
853
        return self._real_repository.store_revision_signature(
854
            gpg_strategy, plaintext, revision_id)
855
2996.2.8 by Aaron Bentley
Fix add_signature discrepancies
856
    def add_signature_text(self, revision_id, signature):
2996.2.3 by Aaron Bentley
Add tests for install_revisions and add_signature
857
        self._ensure_real()
2996.2.8 by Aaron Bentley
Fix add_signature discrepancies
858
        return self._real_repository.add_signature_text(revision_id, signature)
2996.2.3 by Aaron Bentley
Add tests for install_revisions and add_signature
859
2018.5.97 by Andrew Bennetts
Fix more tests.
860
    def has_signature_for_revision_id(self, revision_id):
861
        self._ensure_real()
862
        return self._real_repository.has_signature_for_revision_id(revision_id)
863
2535.3.12 by Andrew Bennetts
Add a first cut of a get_data_stream method to Repository.
864
    def get_data_stream(self, revision_ids):
2535.4.29 by Andrew Bennetts
Add a new smart method, Repository.stream_revisions_chunked, rather than changing the behaviour of an existing method.
865
        REQUEST_NAME = 'Repository.stream_revisions_chunked'
2535.3.15 by Andrew Bennetts
Add KnitVersionedFile.get_stream_as_bytes, start smart implementation of RemoteRepository.get_data_stream.
866
        path = self.bzrdir._path_for_remote_call(self._client)
867
        response, protocol = self._client.call_expecting_body(
2535.4.21 by Andrew Bennetts
Rename smart request, to avoid confusion with non-chunked version merged into bzr.dev.
868
            REQUEST_NAME, path, *revision_ids)
2535.4.2 by Andrew Bennetts
Nasty hackery to make stream_knit_data_for_revisions response use streaming.
869
2535.3.39 by Andrew Bennetts
Tidy some XXXs.
870
        if response == ('ok',):
2535.3.68 by Andrew Bennetts
Backwards compatibility for new smart method.
871
            return self._deserialise_stream(protocol)
872
        elif (response == ('error', "Generic bzr smart protocol error: "
2535.4.21 by Andrew Bennetts
Rename smart request, to avoid confusion with non-chunked version merged into bzr.dev.
873
                "bad request '%s'" % REQUEST_NAME) or
2535.3.68 by Andrew Bennetts
Backwards compatibility for new smart method.
874
              response == ('error', "Generic bzr smart protocol error: "
2535.4.21 by Andrew Bennetts
Rename smart request, to avoid confusion with non-chunked version merged into bzr.dev.
875
                "bad request u'%s'" % REQUEST_NAME)):
2535.3.68 by Andrew Bennetts
Backwards compatibility for new smart method.
876
            protocol.cancel_read_body()
877
            self._ensure_real()
878
            return self._real_repository.get_data_stream(revision_ids)
2535.3.15 by Andrew Bennetts
Add KnitVersionedFile.get_stream_as_bytes, start smart implementation of RemoteRepository.get_data_stream.
879
        else:
2535.3.17 by Andrew Bennetts
[broken] Closer to a working Repository.fetch_revisions smart request.
880
            raise errors.UnexpectedSmartServerResponse(response)
2535.3.15 by Andrew Bennetts
Add KnitVersionedFile.get_stream_as_bytes, start smart implementation of RemoteRepository.get_data_stream.
881
2535.3.68 by Andrew Bennetts
Backwards compatibility for new smart method.
882
    def _deserialise_stream(self, protocol):
2535.4.11 by Andrew Bennetts
Merge from repo-refactor.
883
        stream = protocol.read_streamed_body()
2535.4.15 by Andrew Bennetts
Remove 'PackSource' hack by using the ContainerPushParser.
884
        container_parser = ContainerPushParser()
885
        for bytes in stream:
886
            container_parser.accept_bytes(bytes)
887
            records = container_parser.read_pending_records()
888
            for record_names, record_bytes in records:
2535.4.31 by Andrew Bennetts
Tweak in response to review comments.
889
                if len(record_names) != 1:
2535.4.15 by Andrew Bennetts
Remove 'PackSource' hack by using the ContainerPushParser.
890
                    # These records should have only one name, and that name
891
                    # should be a one-element tuple.
892
                    raise errors.SmartProtocolError(
893
                        'Repository data stream had invalid record name %r'
894
                        % (record_names,))
2535.4.31 by Andrew Bennetts
Tweak in response to review comments.
895
                name_tuple = record_names[0]
2535.4.15 by Andrew Bennetts
Remove 'PackSource' hack by using the ContainerPushParser.
896
                yield name_tuple, record_bytes
2535.3.68 by Andrew Bennetts
Backwards compatibility for new smart method.
897
2535.3.17 by Andrew Bennetts
[broken] Closer to a working Repository.fetch_revisions smart request.
898
    def insert_data_stream(self, stream):
899
        self._ensure_real()
900
        self._real_repository.insert_data_stream(stream)
2535.3.12 by Andrew Bennetts
Add a first cut of a get_data_stream method to Repository.
901
2535.3.45 by Andrew Bennetts
Add item_keys_introduced_by to RemoteRepository.
902
    def item_keys_introduced_by(self, revision_ids, _files_pb=None):
903
        self._ensure_real()
904
        return self._real_repository.item_keys_introduced_by(revision_ids,
905
            _files_pb=_files_pb)
906
2819.2.4 by Andrew Bennetts
Add a 'revision_graph_can_have_wrong_parents' method to repository.
907
    def revision_graph_can_have_wrong_parents(self):
908
        # The answer depends on the remote repo format.
909
        self._ensure_real()
910
        return self._real_repository.revision_graph_can_have_wrong_parents()
911
2819.2.5 by Andrew Bennetts
Make reconcile abort gracefully if the revision index has bad parents.
912
    def _find_inconsistent_revision_parents(self):
913
        self._ensure_real()
914
        return self._real_repository._find_inconsistent_revision_parents()
915
916
    def _check_for_inconsistent_revision_parents(self):
917
        self._ensure_real()
918
        return self._real_repository._check_for_inconsistent_revision_parents()
919
3089.2.1 by Andrew Bennetts
Implement RemoteRepository._make_parents_provider.
920
    def _make_parents_provider(self):
921
        self._ensure_real()
922
        return self._real_repository._make_parents_provider()
923
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
924
2018.5.127 by Andrew Bennetts
Fix most of the lockable_files tests for RemoteBranchLockableFiles.
925
class RemoteBranchLockableFiles(LockableFiles):
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
926
    """A 'LockableFiles' implementation that talks to a smart server.
927
    
928
    This is not a public interface class.
929
    """
930
931
    def __init__(self, bzrdir, _client):
932
        self.bzrdir = bzrdir
933
        self._client = _client
2018.5.135 by Andrew Bennetts
Prevent remote branch clients from determining the 'right' mode for control files, because we don't want clients setting the mode anyway.
934
        self._need_find_modes = True
2018.5.133 by Andrew Bennetts
All TestLockableFiles_RemoteLockDir tests passing.
935
        LockableFiles.__init__(
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
936
            self, bzrdir.get_branch_transport(None),
2018.5.133 by Andrew Bennetts
All TestLockableFiles_RemoteLockDir tests passing.
937
            'lock', lockdir.LockDir)
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
938
2018.5.135 by Andrew Bennetts
Prevent remote branch clients from determining the 'right' mode for control files, because we don't want clients setting the mode anyway.
939
    def _find_modes(self):
940
        # RemoteBranches don't let the client set the mode of control files.
941
        self._dir_mode = None
942
        self._file_mode = None
943
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
944
    def get(self, path):
945
        """'get' a remote path as per the LockableFiles interface.
946
947
        :param path: the file to 'get'. If this is 'branch.conf', we do not
948
             just retrieve a file, instead we ask the smart server to generate
949
             a configuration for us - which is retrieved as an INI file.
950
        """
2018.5.133 by Andrew Bennetts
All TestLockableFiles_RemoteLockDir tests passing.
951
        if path == 'branch.conf':
952
            path = self.bzrdir._path_for_remote_call(self._client)
2018.5.153 by Andrew Bennetts
Rename call2 to call_expecting_body, and other small changes prompted by review.
953
            response = self._client.call_expecting_body(
954
                'Branch.get_config_file', path)
2018.5.133 by Andrew Bennetts
All TestLockableFiles_RemoteLockDir tests passing.
955
            assert response[0][0] == 'ok', \
956
                'unexpected response code %s' % (response[0],)
957
            return StringIO(response[1].read_body_bytes())
958
        else:
959
            # VFS fallback.
960
            return LockableFiles.get(self, path)
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
961
962
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
963
class RemoteBranchFormat(branch.BranchFormat):
964
2018.5.124 by Robert Collins
Fix test_format_initialize_find_open by delegating Branch formt lookup to the BzrDir, where it should have stayed from the start.
965
    def __eq__(self, other):
966
        return (isinstance(other, RemoteBranchFormat) and 
967
            self.__dict__ == other.__dict__)
968
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
969
    def get_format_description(self):
970
        return 'Remote BZR Branch'
971
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
972
    def get_format_string(self):
973
        return 'Remote BZR Branch'
974
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
975
    def open(self, a_bzrdir):
1752.2.72 by Andrew Bennetts
Make Remote* classes in remote.py more consistent and remove some dead code.
976
        assert isinstance(a_bzrdir, RemoteBzrDir)
977
        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.
978
979
    def initialize(self, a_bzrdir):
980
        assert isinstance(a_bzrdir, RemoteBzrDir)
981
        return a_bzrdir.create_branch()
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
982
2696.3.6 by Martin Pool
Mark RemoteBranch as (possibly) supporting tags
983
    def supports_tags(self):
984
        # Remote branches might support tags, but we won't know until we
985
        # access the real remote branch.
986
        return True
987
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
988
989
class RemoteBranch(branch.Branch):
990
    """Branch stored on a server accessed by HPSS RPC.
991
992
    At the moment most operations are mapped down to simple file operations.
993
    """
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
994
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
995
    def __init__(self, remote_bzrdir, remote_repository, real_branch=None,
996
        _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.
997
        """Create a RemoteBranch instance.
998
999
        :param real_branch: An optional local implementation of the branch
1000
            format, usually accessing the data via the VFS.
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
1001
        :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.
1002
        """
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
1003
        # We intentionally don't call the parent class's __init__, because it
1004
        # will try to assign to self.tags, which is a property in this subclass.
1005
        # And the parent's __init__ doesn't do much anyway.
2978.7.1 by John Arbash Meinel
Fix bug #162486, by having RemoteBranch properly initialize self._revision_id_to_revno_map.
1006
        self._revision_id_to_revno_cache = None
2018.5.105 by Andrew Bennetts
Implement revision_history caching for RemoteBranch.
1007
        self._revision_history_cache = None
1752.2.64 by Andrew Bennetts
Improve how RemoteBzrDir.open_branch works to handle references and not double-open repositories.
1008
        self.bzrdir = remote_bzrdir
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
1009
        if _client is not None:
1010
            self._client = _client
1011
        else:
2485.8.54 by Vincent Ladeuil
Refactor medium uses by making a distinction betweem shared and real medium.
1012
            self._client = client._SmartClient(self.bzrdir._shared_medium)
1752.2.64 by Andrew Bennetts
Improve how RemoteBzrDir.open_branch works to handle references and not double-open repositories.
1013
        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.
1014
        if real_branch is not None:
1015
            self._real_branch = real_branch
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1016
            # Give the remote repository the matching real repo.
2018.5.97 by Andrew Bennetts
Fix more tests.
1017
            real_repo = self._real_branch.repository
1018
            if isinstance(real_repo, RemoteRepository):
1019
                real_repo._ensure_real()
1020
                real_repo = real_repo._real_repository
1021
            self.repository._set_real_repository(real_repo)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1022
            # Give the branch the remote repository to let fast-pathing happen.
1023
            self._real_branch.repository = self.repository
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
1024
        else:
1025
            self._real_branch = None
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
1026
        # 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.
1027
        self._format = RemoteBranchFormat()
2018.5.55 by Robert Collins
Give RemoteBranch a base url in line with the Branch protocol.
1028
        self.base = self.bzrdir.root_transport.base
2018.5.169 by Andrew Bennetts
Add a _server_formats flag to BzrDir.open_from_transport and BzrDirFormat.find_format, make RemoteBranch.control_files into a property.
1029
        self._control_files = None
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1030
        self._lock_mode = None
1031
        self._lock_token = None
1032
        self._lock_count = 0
1033
        self._leave_lock = False
1752.2.64 by Andrew Bennetts
Improve how RemoteBzrDir.open_branch works to handle references and not double-open repositories.
1034
2477.1.1 by Martin Pool
Add RemoteBranch repr
1035
    def __str__(self):
1036
        return "%s(%s)" % (self.__class__.__name__, self.base)
1037
1038
    __repr__ = __str__
1039
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
1040
    def _ensure_real(self):
1041
        """Ensure that there is a _real_branch set.
1042
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
1043
        Used before calls to self._real_branch.
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
1044
        """
1045
        if not self._real_branch:
1046
            assert vfs.vfs_enabled()
1047
            self.bzrdir._ensure_real()
1048
            self._real_branch = self.bzrdir._real_bzrdir.open_branch()
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
1049
            # Give the remote repository the matching real repo.
2018.5.97 by Andrew Bennetts
Fix more tests.
1050
            real_repo = self._real_branch.repository
1051
            if isinstance(real_repo, RemoteRepository):
1052
                real_repo._ensure_real()
1053
                real_repo = real_repo._real_repository
1054
            self.repository._set_real_repository(real_repo)
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
1055
            # Give the branch the remote repository to let fast-pathing happen.
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
1056
            self._real_branch.repository = self.repository
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1057
            # XXX: deal with _lock_mode == 'w'
1058
            if self._lock_mode == 'r':
1059
                self._real_branch.lock_read()
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
1060
2018.5.169 by Andrew Bennetts
Add a _server_formats flag to BzrDir.open_from_transport and BzrDirFormat.find_format, make RemoteBranch.control_files into a property.
1061
    @property
1062
    def control_files(self):
1063
        # Defer actually creating RemoteBranchLockableFiles until its needed,
1064
        # because it triggers an _ensure_real that we otherwise might not need.
1065
        if self._control_files is None:
1066
            self._control_files = RemoteBranchLockableFiles(
1067
                self.bzrdir, self._client)
1068
        return self._control_files
1069
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
1070
    def _get_checkout_format(self):
1071
        self._ensure_real()
1072
        return self._real_branch._get_checkout_format()
1073
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
1074
    def get_physical_lock_status(self):
1075
        """See Branch.get_physical_lock_status()."""
1076
        # should be an API call to the server, as branches must be lockable.
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
1077
        self._ensure_real()
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
1078
        return self._real_branch.get_physical_lock_status()
1079
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
1080
    def lock_read(self):
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1081
        if not self._lock_mode:
1082
            self._lock_mode = 'r'
1083
            self._lock_count = 1
1084
            if self._real_branch is not None:
1085
                self._real_branch.lock_read()
1086
        else:
1087
            self._lock_count += 1
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
1088
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
1089
    def _remote_lock_write(self, token):
1090
        if token is None:
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1091
            branch_token = repo_token = ''
1092
        else:
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
1093
            branch_token = token
1094
            repo_token = self.repository.lock_write()
1095
            self.repository.unlock()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1096
        path = self.bzrdir._path_for_remote_call(self._client)
1097
        response = self._client.call('Branch.lock_write', path, branch_token,
3015.2.9 by Robert Collins
Handle repositories that do not allow remote locking, like pack repositories, in the client side remote server proxy objects.
1098
                                     repo_token or '')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1099
        if response[0] == 'ok':
1100
            ok, branch_token, repo_token = response
1101
            return branch_token, repo_token
1102
        elif response[0] == 'LockContention':
1103
            raise errors.LockContention('(remote lock)')
1104
        elif response[0] == 'TokenMismatch':
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
1105
            raise errors.TokenMismatch(token, '(remote token)')
2018.5.95 by Andrew Bennetts
Add a Transport.is_readonly remote call, let {Branch,Repository}.lock_write remote call return UnlockableTransport, and miscellaneous test fixes.
1106
        elif response[0] == 'UnlockableTransport':
1107
            raise errors.UnlockableTransport(self.bzrdir.root_transport)
2018.5.123 by Robert Collins
Translate ReadOnlyError in RemoteBranch._remote_lock_write.
1108
        elif response[0] == 'ReadOnlyError':
1109
            raise errors.ReadOnlyError(self)
2872.5.3 by Martin Pool
Pass back LockFailed from smart server lock methods
1110
        elif response[0] == 'LockFailed':
1111
            raise errors.LockFailed(response[1], response[2])
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1112
        else:
2555.1.1 by Martin Pool
Remove use of 'assert False' to raise an exception unconditionally
1113
            raise errors.UnexpectedSmartServerResponse(response)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1114
            
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
1115
    def lock_write(self, token=None):
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1116
        if not self._lock_mode:
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
1117
            remote_tokens = self._remote_lock_write(token)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1118
            self._lock_token, self._repo_lock_token = remote_tokens
1119
            assert self._lock_token, 'Remote server did not return a token!'
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1120
            # TODO: We really, really, really don't want to call _ensure_real
1121
            # here, but it's the easiest way to ensure coherency between the
1122
            # state of the RemoteBranch and RemoteRepository objects and the
1123
            # physical locks.  If we don't materialise the real objects here,
1124
            # then getting everything in the right state later is complex, so
1125
            # for now we just do it the lazy way.
1126
            #   -- Andrew Bennetts, 2007-02-22.
1127
            self._ensure_real()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1128
            if self._real_branch is not None:
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
1129
                self._real_branch.repository.lock_write(
1130
                    token=self._repo_lock_token)
1131
                try:
1132
                    self._real_branch.lock_write(token=self._lock_token)
1133
                finally:
1134
                    self._real_branch.repository.unlock()
1135
            if token is not None:
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1136
                self._leave_lock = True
1137
            else:
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
1138
                # XXX: this case seems to be unreachable; token cannot be None.
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1139
                self._leave_lock = False
1140
            self._lock_mode = 'w'
1141
            self._lock_count = 1
1142
        elif self._lock_mode == 'r':
1143
            raise errors.ReadOnlyTransaction
1144
        else:
2018.5.142 by Andrew Bennetts
Change Branch.lock_token to only accept and receive the branch lock token (rather than the branch and repo lock tokens).
1145
            if token is not None:
1146
                # A token was given to lock_write, and we're relocking, so check
1147
                # that the given token actually matches the one we already have.
1148
                if token != self._lock_token:
1149
                    raise errors.TokenMismatch(token, self._lock_token)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1150
            self._lock_count += 1
3015.2.9 by Robert Collins
Handle repositories that do not allow remote locking, like pack repositories, in the client side remote server proxy objects.
1151
        return self._lock_token or None
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1152
1153
    def _unlock(self, branch_token, repo_token):
1154
        path = self.bzrdir._path_for_remote_call(self._client)
1155
        response = self._client.call('Branch.unlock', path, branch_token,
3015.2.9 by Robert Collins
Handle repositories that do not allow remote locking, like pack repositories, in the client side remote server proxy objects.
1156
                                     repo_token or '')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1157
        if response == ('ok',):
1158
            return
1159
        elif response[0] == 'TokenMismatch':
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1160
            raise errors.TokenMismatch(
1161
                str((branch_token, repo_token)), '(remote tokens)')
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1162
        else:
2555.1.1 by Martin Pool
Remove use of 'assert False' to raise an exception unconditionally
1163
            raise errors.UnexpectedSmartServerResponse(response)
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
1164
1165
    def unlock(self):
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1166
        self._lock_count -= 1
1167
        if not self._lock_count:
2018.5.105 by Andrew Bennetts
Implement revision_history caching for RemoteBranch.
1168
            self._clear_cached_state()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1169
            mode = self._lock_mode
1170
            self._lock_mode = None
1171
            if self._real_branch is not None:
3015.2.9 by Robert Collins
Handle repositories that do not allow remote locking, like pack repositories, in the client side remote server proxy objects.
1172
                if (not self._leave_lock and mode == 'w' and
1173
                    self._repo_lock_token):
2018.15.1 by Andrew Bennetts
All branch_implementations/test_locking tests passing.
1174
                    # If this RemoteBranch will remove the physical lock for the
1175
                    # repository, make sure the _real_branch doesn't do it
1176
                    # first.  (Because the _real_branch's repository is set to
1177
                    # be the RemoteRepository.)
1178
                    self._real_branch.repository.leave_lock_in_place()
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1179
                self._real_branch.unlock()
1180
            if mode != 'w':
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
1181
                # Only write-locked branched need to make a remote method call
1182
                # to perfom the unlock.
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1183
                return
1184
            assert self._lock_token, 'Locked, but no token!'
1185
            branch_token = self._lock_token
1186
            repo_token = self._repo_lock_token
1187
            self._lock_token = None
1188
            self._repo_lock_token = None
1189
            if not self._leave_lock:
1190
                self._unlock(branch_token, repo_token)
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
1191
1192
    def break_lock(self):
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
1193
        self._ensure_real()
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
1194
        return self._real_branch.break_lock()
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
1195
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1196
    def leave_lock_in_place(self):
3015.2.9 by Robert Collins
Handle repositories that do not allow remote locking, like pack repositories, in the client side remote server proxy objects.
1197
        if not self._lock_token:
1198
            raise NotImplementedError(self.leave_lock_in_place)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1199
        self._leave_lock = True
1200
1201
    def dont_leave_lock_in_place(self):
3015.2.9 by Robert Collins
Handle repositories that do not allow remote locking, like pack repositories, in the client side remote server proxy objects.
1202
        if not self._lock_token:
3015.2.15 by Robert Collins
Review feedback.
1203
            raise NotImplementedError(self.dont_leave_lock_in_place)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
1204
        self._leave_lock = False
1205
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
1206
    def last_revision_info(self):
1207
        """See Branch.last_revision_info()."""
1208
        path = self.bzrdir._path_for_remote_call(self._client)
1209
        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
1210
        assert response[0] == 'ok', 'unexpected response code %s' % (response,)
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
1211
        revno = int(response[1])
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
1212
        last_revision = response[2]
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
1213
        return (revno, last_revision)
1214
2018.5.105 by Andrew Bennetts
Implement revision_history caching for RemoteBranch.
1215
    def _gen_revision_history(self):
1216
        """See Branch._gen_revision_history()."""
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
1217
        path = self.bzrdir._path_for_remote_call(self._client)
2018.5.153 by Andrew Bennetts
Rename call2 to call_expecting_body, and other small changes prompted by review.
1218
        response = self._client.call_expecting_body(
1219
            'Branch.revision_history', path)
1220
        assert response[0][0] == 'ok', ('unexpected response code %s'
1221
                                        % (response[0],))
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
1222
        result = response[1].read_body_bytes().split('\x00')
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
1223
        if result == ['']:
1224
            return []
1225
        return result
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
1226
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1227
    @needs_write_lock
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
1228
    def set_revision_history(self, rev_history):
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
1229
        # Send just the tip revision of the history; the server will generate
1230
        # the full history from that.  If the revision doesn't exist in this
1231
        # branch, NoSuchRevision will be raised.
1232
        path = self.bzrdir._path_for_remote_call(self._client)
1233
        if rev_history == []:
2018.5.170 by Andrew Bennetts
Use 'null:' instead of '' to mean NULL_REVISION on the wire.
1234
            rev_id = 'null:'
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
1235
        else:
1236
            rev_id = rev_history[-1]
2418.5.12 by John Arbash Meinel
Move functions from BzrBranch to base Branch object.
1237
        self._clear_cached_state()
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1238
        response = self._client.call('Branch.set_last_revision',
1239
            path, self._lock_token, self._repo_lock_token, rev_id)
2018.12.3 by Andrew Bennetts
Add a Branch.set_last_revision smart method, and make RemoteBranch.set_revision_history use it.
1240
        if response[0] == 'NoSuchRevision':
1241
            raise NoSuchRevision(self, rev_id)
1242
        else:
1243
            assert response == ('ok',), (
1244
                'unexpected response code %r' % (response,))
2018.5.105 by Andrew Bennetts
Implement revision_history caching for RemoteBranch.
1245
        self._cache_revision_history(rev_history)
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
1246
1247
    def get_parent(self):
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
1248
        self._ensure_real()
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
1249
        return self._real_branch.get_parent()
1250
        
1752.2.63 by Andrew Bennetts
Delegate set_parent.
1251
    def set_parent(self, url):
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
1252
        self._ensure_real()
1752.2.63 by Andrew Bennetts
Delegate set_parent.
1253
        return self._real_branch.set_parent(url)
1254
        
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1255
    def get_config(self):
1256
        return RemoteBranchConfig(self)
1257
2018.5.94 by Andrew Bennetts
Various small changes in aid of making tests pass (including deleting one invalid test).
1258
    def sprout(self, to_bzrdir, revision_id=None):
1259
        # Like Branch.sprout, except that it sprouts a branch in the default
1260
        # format, because RemoteBranches can't be created at arbitrary URLs.
1261
        # XXX: if to_bzrdir is a RemoteBranch, this should perhaps do
1262
        # to_bzrdir.create_branch...
3047.1.1 by Andrew Bennetts
Fix for bug 164626, add test that Repository.sprout preserves format.
1263
        self._ensure_real()
1264
        result = self._real_branch._format.initialize(to_bzrdir)
2018.18.20 by Martin Pool
Route branch operations through remote copy_content_into
1265
        self.copy_content_into(result, revision_id=revision_id)
2018.5.94 by Andrew Bennetts
Various small changes in aid of making tests pass (including deleting one invalid test).
1266
        result.set_parent(self.bzrdir.root_transport.base)
1267
        return result
1268
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1269
    @needs_write_lock
2477.1.2 by Martin Pool
Rename push/pull back to 'run_hooks' (jameinel)
1270
    def pull(self, source, overwrite=False, stop_revision=None,
2477.1.9 by Martin Pool
Review cleanups from John, mostly docs
1271
             **kwargs):
1272
        # FIXME: This asks the real branch to run the hooks, which means
1273
        # they're called with the wrong target branch parameter. 
1274
        # The test suite specifically allows this at present but it should be
1275
        # fixed.  It should get a _override_hook_target branch,
1276
        # as push does.  -- mbp 20070405
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1277
        self._ensure_real()
1278
        self._real_branch.pull(
2477.1.2 by Martin Pool
Rename push/pull back to 'run_hooks' (jameinel)
1279
            source, overwrite=overwrite, stop_revision=stop_revision,
1280
            **kwargs)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1281
2018.14.3 by Andrew Bennetts
Make a couple more branch_implementations tests pass.
1282
    @needs_read_lock
1283
    def push(self, target, overwrite=False, stop_revision=None):
1284
        self._ensure_real()
2018.5.97 by Andrew Bennetts
Fix more tests.
1285
        return self._real_branch.push(
2477.1.5 by Martin Pool
More cleanups of Branch.push to get the right behaviour with RemoteBranches
1286
            target, overwrite=overwrite, stop_revision=stop_revision,
1287
            _override_hook_source_branch=self)
2018.14.3 by Andrew Bennetts
Make a couple more branch_implementations tests pass.
1288
1289
    def is_locked(self):
1290
        return self._lock_count >= 1
1291
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
1292
    def set_last_revision_info(self, revno, revision_id):
1293
        self._ensure_real()
2018.5.105 by Andrew Bennetts
Implement revision_history caching for RemoteBranch.
1294
        self._clear_cached_state()
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
1295
        return self._real_branch.set_last_revision_info(revno, revision_id)
1296
2018.5.95 by Andrew Bennetts
Add a Transport.is_readonly remote call, let {Branch,Repository}.lock_write remote call return UnlockableTransport, and miscellaneous test fixes.
1297
    def generate_revision_history(self, revision_id, last_rev=None,
1298
                                  other_branch=None):
1299
        self._ensure_real()
1300
        return self._real_branch.generate_revision_history(
1301
            revision_id, last_rev=last_rev, other_branch=other_branch)
1302
2018.5.96 by Andrew Bennetts
Merge from bzr.dev, resolving the worst of the semantic conflicts, but there's
1303
    @property
1304
    def tags(self):
1305
        self._ensure_real()
1306
        return self._real_branch.tags
1307
2018.5.97 by Andrew Bennetts
Fix more tests.
1308
    def set_push_location(self, location):
1309
        self._ensure_real()
1310
        return self._real_branch.set_push_location(location)
1311
3052.5.4 by John Arbash Meinel
If we are going to overwrite the target, we don't have to do
1312
    def update_revisions(self, other, stop_revision=None, overwrite=False):
2018.5.97 by Andrew Bennetts
Fix more tests.
1313
        self._ensure_real()
1314
        return self._real_branch.update_revisions(
3052.5.4 by John Arbash Meinel
If we are going to overwrite the target, we don't have to do
1315
            other, stop_revision=stop_revision, overwrite=overwrite)
2018.5.97 by Andrew Bennetts
Fix more tests.
1316
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
1317
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1318
class RemoteBranchConfig(BranchConfig):
1319
1320
    def username(self):
1321
        self.branch._ensure_real()
1322
        return self.branch._real_branch.get_config().username()
1323
2018.14.2 by Andrew Bennetts
All but one repository_implementation tests for RemoteRepository passing.
1324
    def _get_branch_data_config(self):
1325
        self.branch._ensure_real()
1326
        if self._branch_data_config is None:
1327
            self._branch_data_config = TreeConfig(self.branch._real_branch)
1328
        return self._branch_data_config
1329
2018.18.25 by Martin Pool
Repository.tarball fixes for python2.4
1330
1331
def _extract_tar(tar, to_dir):
1332
    """Extract all the contents of a tarfile object.
1333
1334
    A replacement for extractall, which is not present in python2.4
1335
    """
1336
    for tarinfo in tar:
1337
        tar.extract(tarinfo, to_dir)