/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
5557.1.7 by John Arbash Meinel
Merge in the bzr.dev 5582
1
# Copyright (C) 2006-2011 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
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
16
3211.5.2 by Robert Collins
Change RemoteRepository.get_parent_map to use bz2 not gzip for compression.
17
import bz2
6280.9.4 by Jelmer Vernooij
use zlib instead.
18
import zlib
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
19
2490.2.5 by Aaron Bentley
Use GraphWalker.unique_ancestor to determine merge base
20
from bzrlib import (
2694.5.4 by Jelmer Vernooij
Move bzrlib.util.bencode to bzrlib._bencode_py.
21
    bencode,
2490.2.5 by Aaron Bentley
Use GraphWalker.unique_ancestor to determine merge base
22
    branch,
5712.3.13 by Jelmer Vernooij
Add Prober.known_formats().
23
    bzrdir as _mod_bzrdir,
4226.1.5 by Robert Collins
Reinstate the use of the Branch.get_config_file verb.
24
    config,
5363.2.10 by Jelmer Vernooij
base ControlDir on ControlComponent.
25
    controldir,
3192.1.1 by Andrew Bennetts
Add some -Dhpss debugging to get_parent_map.
26
    debug,
2490.2.5 by Aaron Bentley
Use GraphWalker.unique_ancestor to determine merge base
27
    errors,
6280.8.1 by Jelmer Vernooij
Avoid _ensure_real in RemoteRepository.verify_revision_signature and RemoteRepository.sign_revision.
28
    gpg,
3172.5.1 by Robert Collins
Create a RemoteRepository get_graph implementation and delegate get_parents_map to the real repository.
29
    graph,
4509.3.28 by Martin Pool
Add missing import
30
    lock,
2490.2.5 by Aaron Bentley
Use GraphWalker.unique_ancestor to determine merge base
31
    lockdir,
6280.10.18 by Jelmer Vernooij
Ensure file ids are always utf8.
32
    osutils,
6284.1.1 by Jelmer Vernooij
Allow registering custom error handlers in the HPSS client.
33
    registry,
5158.4.1 by Andrew Bennetts
Don't allow RemoteRepository to stack on incompatible formats.
34
    repository as _mod_repository,
4307.2.3 by Robert Collins
Change RemoteRepository.has_revision to use get_parent_map to leverage the caching.
35
    revision as _mod_revision,
4913.4.2 by Jelmer Vernooij
Add Repository.get_known_graph_ancestry.
36
    static_tuple,
3228.4.11 by John Arbash Meinel
Deprecations abound.
37
    symbol_versioning,
6280.8.1 by Jelmer Vernooij
Avoid _ensure_real in RemoteRepository.verify_revision_signature and RemoteRepository.sign_revision.
38
    testament as _mod_testament,
5535.3.7 by Andrew Bennetts
Allow for trailing-slash differences between local url path vs. remote url path for remote branch's repository.
39
    urlutils,
5815.4.1 by Jelmer Vernooij
Split versionedfile-specific stuff out into VersionedFileRepository.
40
    vf_repository,
41
    )
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
42
from bzrlib.branch import BranchReferenceFormat, BranchWriteLockResult
4634.85.9 by Andrew Bennetts
Add some experimental decorators: @only_raises(..) and @cleanup_method.
43
from bzrlib.decorators import needs_read_lock, needs_write_lock, only_raises
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
44
from bzrlib.errors import (
45
    NoSuchRevision,
46
    SmartProtocolError,
47
    )
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
48
from bzrlib.i18n import gettext
6267.1.3 by Jelmer Vernooij
Fix tests.
49
from bzrlib.inventory import Inventory
2018.5.127 by Andrew Bennetts
Fix most of the lockable_files tests for RemoteBranchLockableFiles.
50
from bzrlib.lockable_files import LockableFiles
4060.1.4 by Robert Collins
Streaming fetch from remote servers.
51
from bzrlib.smart import client, vfs, repository as smart_repo
5712.3.15 by Jelmer Vernooij
Remove unused register format functions.
52
from bzrlib.smart.client import _SmartClient
5712.3.13 by Jelmer Vernooij
Add Prober.known_formats().
53
from bzrlib.revision import NULL_REVISION
6267.1.3 by Jelmer Vernooij
Fix tests.
54
from bzrlib.revisiontree import InventoryRevisionTree
5816.8.3 by Andrew Bennetts
Add test for calling add_fallback_repository after _make_parents_provider, and make it work.
55
from bzrlib.repository import RepositoryWriteLockResult, _LazyListJoin
6280.9.1 by Jelmer Vernooij
Add remote side of Repository.iter_revisions.
56
from bzrlib.serializer import format_registry as serializer_format_registry
6280.7.5 by Jelmer Vernooij
Bunch of test fixes.
57
from bzrlib.trace import mutter, note, warning, log_exception_quietly
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
58
3445.1.5 by John Arbash Meinel
allow passing a 'graph' object into Branch.update_revisions.
59
6015.23.12 by John Arbash Meinel
Going with 100 to be friendlier to bandwith/latency constrained environs.
60
_DEFAULT_SEARCH_DEPTH = 100
6015.23.11 by John Arbash Meinel
allow a bit more flexibilty in how we walk the searches.
61
62
3786.2.3 by Andrew Bennetts
Remove duplicated 'call & translate errors' code in bzrlib.remote.
63
class _RpcHelper(object):
64
    """Mixin class that helps with issuing RPCs."""
65
66
    def _call(self, method, *args, **err_context):
67
        try:
68
            return self._client.call(method, *args)
69
        except errors.ErrorFromSmartServer, err:
70
            self._translate_error(err, **err_context)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
71
3786.2.3 by Andrew Bennetts
Remove duplicated 'call & translate errors' code in bzrlib.remote.
72
    def _call_expecting_body(self, method, *args, **err_context):
73
        try:
74
            return self._client.call_expecting_body(method, *args)
75
        except errors.ErrorFromSmartServer, err:
76
            self._translate_error(err, **err_context)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
77
4556.2.1 by Andrew Bennetts
Add Branch.set_tags_bytes RPC, with HPSS call count acceptance test. Also fixes serialisation of LockDir, and uses external_url() in LockDir's repr and contention message.
78
    def _call_with_body_bytes(self, method, args, body_bytes, **err_context):
79
        try:
80
            return self._client.call_with_body_bytes(method, args, body_bytes)
81
        except errors.ErrorFromSmartServer, err:
82
            self._translate_error(err, **err_context)
83
3786.2.3 by Andrew Bennetts
Remove duplicated 'call & translate errors' code in bzrlib.remote.
84
    def _call_with_body_bytes_expecting_body(self, method, args, body_bytes,
85
                                             **err_context):
86
        try:
87
            return self._client.call_with_body_bytes_expecting_body(
88
                method, args, body_bytes)
89
        except errors.ErrorFromSmartServer, err:
90
            self._translate_error(err, **err_context)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
91
4032.3.2 by Robert Collins
Create and use a RPC call to create branches on bzr servers rather than using VFS calls.
92
93
def response_tuple_to_repo_format(response):
94
    """Convert a response tuple describing a repository format to a format."""
95
    format = RemoteRepositoryFormat()
4118.1.1 by Andrew Bennetts
Fix performance regression (many small round-trips) when pushing to a remote pack, and tidy the tests.
96
    format._rich_root_data = (response[0] == 'yes')
97
    format._supports_tree_reference = (response[1] == 'yes')
98
    format._supports_external_lookups = (response[2] == 'yes')
4032.3.2 by Robert Collins
Create and use a RPC call to create branches on bzr servers rather than using VFS calls.
99
    format._network_name = response[3]
100
    return format
101
102
5712.3.13 by Jelmer Vernooij
Add Prober.known_formats().
103
# Note that RemoteBzrDirProber lives in bzrlib.bzrdir so bzrlib.remote
104
# does not have to be imported unless a remote format is involved.
105
106
class RemoteBzrDirFormat(_mod_bzrdir.BzrDirMetaFormat1):
107
    """Format representing bzrdirs accessed via a smart server"""
108
109
    supports_workingtrees = False
110
111
    def __init__(self):
5712.3.17 by Jelmer Vernooij
more fixes.
112
        _mod_bzrdir.BzrDirMetaFormat1.__init__(self)
5712.3.13 by Jelmer Vernooij
Add Prober.known_formats().
113
        # XXX: It's a bit ugly that the network name is here, because we'd
114
        # like to believe that format objects are stateless or at least
115
        # immutable,  However, we do at least avoid mutating the name after
116
        # it's returned.  See <https://bugs.launchpad.net/bzr/+bug/504102>
117
        self._network_name = None
118
119
    def __repr__(self):
120
        return "%s(_network_name=%r)" % (self.__class__.__name__,
121
            self._network_name)
122
123
    def get_format_description(self):
124
        if self._network_name:
6305.4.1 by Jelmer Vernooij
Print sensible error message when remote format is unknown.
125
            try:
126
                real_format = controldir.network_format_registry.get(
127
                        self._network_name)
128
            except KeyError:
129
                pass
130
            else:
131
                return 'Remote: ' + real_format.get_format_description()
5712.3.13 by Jelmer Vernooij
Add Prober.known_formats().
132
        return 'bzr remote bzrdir'
133
134
    def get_format_string(self):
135
        raise NotImplementedError(self.get_format_string)
136
137
    def network_name(self):
138
        if self._network_name:
139
            return self._network_name
140
        else:
141
            raise AssertionError("No network name set.")
142
143
    def initialize_on_transport(self, transport):
144
        try:
145
            # hand off the request to the smart server
146
            client_medium = transport.get_smart_medium()
147
        except errors.NoSmartMedium:
148
            # TODO: lookup the local format from a server hint.
149
            local_dir_format = _mod_bzrdir.BzrDirMetaFormat1()
150
            return local_dir_format.initialize_on_transport(transport)
151
        client = _SmartClient(client_medium)
152
        path = client.remote_path_from_transport(transport)
153
        try:
154
            response = client.call('BzrDirFormat.initialize', path)
155
        except errors.ErrorFromSmartServer, err:
156
            _translate_error(err, path=path)
157
        if response[0] != 'ok':
158
            raise errors.SmartProtocolError('unexpected response code %s' % (response,))
159
        format = RemoteBzrDirFormat()
160
        self._supply_sub_formats_to(format)
161
        return RemoteBzrDir(transport, format)
162
163
    def parse_NoneTrueFalse(self, arg):
164
        if not arg:
165
            return None
166
        if arg == 'False':
167
            return False
168
        if arg == 'True':
169
            return True
170
        raise AssertionError("invalid arg %r" % arg)
171
172
    def _serialize_NoneTrueFalse(self, arg):
173
        if arg is False:
174
            return 'False'
175
        if arg:
176
            return 'True'
177
        return ''
178
179
    def _serialize_NoneString(self, arg):
180
        return arg or ''
181
182
    def initialize_on_transport_ex(self, transport, use_existing_dir=False,
183
        create_prefix=False, force_new_repo=False, stacked_on=None,
184
        stack_on_pwd=None, repo_format_name=None, make_working_trees=None,
185
        shared_repo=False):
186
        try:
187
            # hand off the request to the smart server
188
            client_medium = transport.get_smart_medium()
189
        except errors.NoSmartMedium:
190
            do_vfs = True
191
        else:
192
            # Decline to open it if the server doesn't support our required
193
            # version (3) so that the VFS-based transport will do it.
194
            if client_medium.should_probe():
195
                try:
196
                    server_version = client_medium.protocol_version()
197
                    if server_version != '2':
198
                        do_vfs = True
199
                    else:
200
                        do_vfs = False
201
                except errors.SmartProtocolError:
202
                    # Apparently there's no usable smart server there, even though
203
                    # the medium supports the smart protocol.
204
                    do_vfs = True
205
            else:
206
                do_vfs = False
207
        if not do_vfs:
208
            client = _SmartClient(client_medium)
209
            path = client.remote_path_from_transport(transport)
210
            if client_medium._is_remote_before((1, 16)):
211
                do_vfs = True
212
        if do_vfs:
213
            # TODO: lookup the local format from a server hint.
214
            local_dir_format = _mod_bzrdir.BzrDirMetaFormat1()
215
            self._supply_sub_formats_to(local_dir_format)
216
            return local_dir_format.initialize_on_transport_ex(transport,
217
                use_existing_dir=use_existing_dir, create_prefix=create_prefix,
218
                force_new_repo=force_new_repo, stacked_on=stacked_on,
219
                stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
220
                make_working_trees=make_working_trees, shared_repo=shared_repo,
221
                vfs_only=True)
222
        return self._initialize_on_transport_ex_rpc(client, path, transport,
223
            use_existing_dir, create_prefix, force_new_repo, stacked_on,
224
            stack_on_pwd, repo_format_name, make_working_trees, shared_repo)
225
226
    def _initialize_on_transport_ex_rpc(self, client, path, transport,
227
        use_existing_dir, create_prefix, force_new_repo, stacked_on,
228
        stack_on_pwd, repo_format_name, make_working_trees, shared_repo):
229
        args = []
230
        args.append(self._serialize_NoneTrueFalse(use_existing_dir))
231
        args.append(self._serialize_NoneTrueFalse(create_prefix))
232
        args.append(self._serialize_NoneTrueFalse(force_new_repo))
233
        args.append(self._serialize_NoneString(stacked_on))
234
        # stack_on_pwd is often/usually our transport
235
        if stack_on_pwd:
236
            try:
237
                stack_on_pwd = transport.relpath(stack_on_pwd)
238
                if not stack_on_pwd:
239
                    stack_on_pwd = '.'
240
            except errors.PathNotChild:
241
                pass
242
        args.append(self._serialize_NoneString(stack_on_pwd))
243
        args.append(self._serialize_NoneString(repo_format_name))
244
        args.append(self._serialize_NoneTrueFalse(make_working_trees))
245
        args.append(self._serialize_NoneTrueFalse(shared_repo))
246
        request_network_name = self._network_name or \
247
            _mod_bzrdir.BzrDirFormat.get_default_format().network_name()
248
        try:
249
            response = client.call('BzrDirFormat.initialize_ex_1.16',
250
                request_network_name, path, *args)
251
        except errors.UnknownSmartMethod:
252
            client._medium._remember_remote_is_before((1,16))
253
            local_dir_format = _mod_bzrdir.BzrDirMetaFormat1()
254
            self._supply_sub_formats_to(local_dir_format)
255
            return local_dir_format.initialize_on_transport_ex(transport,
256
                use_existing_dir=use_existing_dir, create_prefix=create_prefix,
257
                force_new_repo=force_new_repo, stacked_on=stacked_on,
258
                stack_on_pwd=stack_on_pwd, repo_format_name=repo_format_name,
259
                make_working_trees=make_working_trees, shared_repo=shared_repo,
260
                vfs_only=True)
261
        except errors.ErrorFromSmartServer, err:
262
            _translate_error(err, path=path)
263
        repo_path = response[0]
264
        bzrdir_name = response[6]
265
        require_stacking = response[7]
266
        require_stacking = self.parse_NoneTrueFalse(require_stacking)
267
        format = RemoteBzrDirFormat()
268
        format._network_name = bzrdir_name
269
        self._supply_sub_formats_to(format)
270
        bzrdir = RemoteBzrDir(transport, format, _client=client)
271
        if repo_path:
272
            repo_format = response_tuple_to_repo_format(response[1:])
273
            if repo_path == '.':
274
                repo_path = ''
275
            if repo_path:
276
                repo_bzrdir_format = RemoteBzrDirFormat()
277
                repo_bzrdir_format._network_name = response[5]
278
                repo_bzr = RemoteBzrDir(transport.clone(repo_path),
279
                    repo_bzrdir_format)
280
            else:
281
                repo_bzr = bzrdir
282
            final_stack = response[8] or None
283
            final_stack_pwd = response[9] or None
284
            if final_stack_pwd:
285
                final_stack_pwd = urlutils.join(
286
                    transport.base, final_stack_pwd)
287
            remote_repo = RemoteRepository(repo_bzr, repo_format)
288
            if len(response) > 10:
289
                # Updated server verb that locks remotely.
290
                repo_lock_token = response[10] or None
291
                remote_repo.lock_write(repo_lock_token, _skip_rpc=True)
292
                if repo_lock_token:
293
                    remote_repo.dont_leave_lock_in_place()
294
            else:
295
                remote_repo.lock_write()
5712.3.17 by Jelmer Vernooij
more fixes.
296
            policy = _mod_bzrdir.UseExistingRepository(remote_repo, final_stack,
5712.3.13 by Jelmer Vernooij
Add Prober.known_formats().
297
                final_stack_pwd, require_stacking)
298
            policy.acquire_repository()
299
        else:
300
            remote_repo = None
301
            policy = None
302
        bzrdir._format.set_branch_format(self.get_branch_format())
303
        if require_stacking:
304
            # The repo has already been created, but we need to make sure that
305
            # we'll make a stackable branch.
306
            bzrdir._format.require_stacking(_skip_repo=True)
307
        return remote_repo, bzrdir, require_stacking, policy
308
309
    def _open(self, transport):
310
        return RemoteBzrDir(transport, self)
311
312
    def __eq__(self, other):
313
        if not isinstance(other, RemoteBzrDirFormat):
314
            return False
315
        return self.get_format_description() == other.get_format_description()
316
317
    def __return_repository_format(self):
318
        # Always return a RemoteRepositoryFormat object, but if a specific bzr
319
        # repository format has been asked for, tell the RemoteRepositoryFormat
320
        # that it should use that for init() etc.
321
        result = RemoteRepositoryFormat()
322
        custom_format = getattr(self, '_repository_format', None)
323
        if custom_format:
324
            if isinstance(custom_format, RemoteRepositoryFormat):
325
                return custom_format
326
            else:
327
                # We will use the custom format to create repositories over the
328
                # wire; expose its details like rich_root_data for code to
329
                # query
330
                result._custom_format = custom_format
331
        return result
332
333
    def get_branch_format(self):
334
        result = _mod_bzrdir.BzrDirMetaFormat1.get_branch_format(self)
335
        if not isinstance(result, RemoteBranchFormat):
336
            new_result = RemoteBranchFormat()
337
            new_result._custom_format = result
338
            # cache the result
339
            self.set_branch_format(new_result)
340
            result = new_result
341
        return result
342
343
    repository_format = property(__return_repository_format,
344
        _mod_bzrdir.BzrDirMetaFormat1._set_repository_format) #.im_func)
345
346
6270.1.6 by Jelmer Vernooij
Provide RemoteControlStore and RemoteBranchStore.
347
class RemoteControlStore(config.IniFileStore):
348
    """Control store which attempts to use HPSS calls to retrieve control store.
349
350
    Note that this is specific to bzr-based formats.
351
    """
352
353
    def __init__(self, bzrdir):
354
        super(RemoteControlStore, self).__init__()
355
        self.bzrdir = bzrdir
6270.1.7 by Jelmer Vernooij
Use _ensure_real.
356
        self._real_store = None
6270.1.6 by Jelmer Vernooij
Provide RemoteControlStore and RemoteBranchStore.
357
6270.1.8 by Jelmer Vernooij
Fix RemoteControlStore.
358
    def lock_write(self, token=None):
359
        self._ensure_real()
360
        return self._real_store.lock_write(token)
361
362
    def unlock(self):
363
        self._ensure_real()
364
        return self._real_store.unlock()
365
366
    @needs_write_lock
367
    def save(self):
368
        # We need to be able to override the undecorated implementation
369
        self.save_without_locking()
370
371
    def save_without_locking(self):
372
        super(RemoteControlStore, self).save()
373
6270.1.7 by Jelmer Vernooij
Use _ensure_real.
374
    def _ensure_real(self):
375
        self.bzrdir._ensure_real()
6270.1.8 by Jelmer Vernooij
Fix RemoteControlStore.
376
        if self._real_store is None:
377
            self._real_store = config.ControlStore(self.bzrdir)
6270.1.6 by Jelmer Vernooij
Provide RemoteControlStore and RemoteBranchStore.
378
379
    def external_url(self):
6270.1.15 by Jelmer Vernooij
Implement sensible .external_url().
380
        return self.bzrdir.user_url
6270.1.6 by Jelmer Vernooij
Provide RemoteControlStore and RemoteBranchStore.
381
382
    def _load_content(self):
383
        medium = self.bzrdir._client._medium
384
        path = self.bzrdir._path_for_remote_call(self.bzrdir._client)
385
        try:
386
            response, handler = self.bzrdir._call_expecting_body(
387
                'BzrDir.get_config_file', path)
388
        except errors.UnknownSmartMethod:
6270.1.7 by Jelmer Vernooij
Use _ensure_real.
389
            self._ensure_real()
390
            return self._real_store._load_content()
6270.1.6 by Jelmer Vernooij
Provide RemoteControlStore and RemoteBranchStore.
391
        if len(response) and response[0] != 'ok':
392
            raise errors.UnexpectedSmartServerResponse(response)
393
        return handler.read_body_bytes()
394
395
    def _save_content(self, content):
6270.1.12 by Jelmer Vernooij
Note HPSS usage.
396
        # FIXME JRV 2011-11-22: Ideally this should use a
397
        # HPSS call too, but at the moment it is not possible
398
        # to write lock control directories.
399
        self._ensure_real()
400
        return self._real_store._save_content(content)
6270.1.6 by Jelmer Vernooij
Provide RemoteControlStore and RemoteBranchStore.
401
402
5712.3.13 by Jelmer Vernooij
Add Prober.known_formats().
403
class RemoteBzrDir(_mod_bzrdir.BzrDir, _RpcHelper):
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
404
    """Control directory on a remote server, accessed via bzr:// or similar."""
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
405
4634.47.5 by Andrew Bennetts
Add tests, and fix BzrDirMeta1.has_workingtree which was failing if the local transport is decorated with a ChrootTransport or similar.
406
    def __init__(self, transport, format, _client=None, _force_probe=False):
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
407
        """Construct a RemoteBzrDir.
408
409
        :param _client: Private parameter for testing. Disables probing and the
410
            use of a real bzrdir.
411
        """
5712.3.13 by Jelmer Vernooij
Add Prober.known_formats().
412
        _mod_bzrdir.BzrDir.__init__(self, transport, format)
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
413
        # this object holds a delegated bzrdir that uses file-level operations
414
        # to talk to the other side
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
415
        self._real_bzrdir = None
4634.47.3 by Andrew Bennetts
Add a BzrDir.open_2.1 verb that indicates if there is a workingtree present. Removes the last 2 VFS calls from incremental pushes.
416
        self._has_working_tree = None
4044.1.3 by Robert Collins
Create a one-shot cache of the result of RemoteBzrDir.create_branch, eliminating 3 round trips for nonstacked branches and 5 for stacked.
417
        # 1-shot cache for the call pattern 'create_branch; open_branch' - see
418
        # create_branch for details.
419
        self._next_open_branch_result = None
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
420
421
        if _client is None:
3313.2.3 by Andrew Bennetts
Deprecate Transport.get_shared_medium.
422
            medium = transport.get_smart_medium()
3431.3.2 by Andrew Bennetts
Remove 'base' from _SmartClient entirely, now that the medium has it.
423
            self._client = client._SmartClient(medium)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
424
        else:
425
            self._client = _client
4634.47.5 by Andrew Bennetts
Add tests, and fix BzrDirMeta1.has_workingtree which was failing if the local transport is decorated with a ChrootTransport or similar.
426
            if not _force_probe:
427
                return
428
429
        self._probe_bzrdir()
430
4964.2.1 by Martin Pool
Add RemoteBzrDir repr
431
    def __repr__(self):
432
        return '%s(%r)' % (self.__class__.__name__, self._client)
433
4634.47.5 by Andrew Bennetts
Add tests, and fix BzrDirMeta1.has_workingtree which was failing if the local transport is decorated with a ChrootTransport or similar.
434
    def _probe_bzrdir(self):
435
        medium = self._client._medium
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
436
        path = self._path_for_remote_call(self._client)
4634.47.3 by Andrew Bennetts
Add a BzrDir.open_2.1 verb that indicates if there is a workingtree present. Removes the last 2 VFS calls from incremental pushes.
437
        if medium._is_remote_before((2, 1)):
438
            self._rpc_open(path)
439
            return
440
        try:
441
            self._rpc_open_2_1(path)
442
            return
443
        except errors.UnknownSmartMethod:
444
            medium._remember_remote_is_before((2, 1))
445
            self._rpc_open(path)
446
447
    def _rpc_open_2_1(self, path):
448
        response = self._call('BzrDir.open_2.1', path)
449
        if response == ('no',):
450
            raise errors.NotBranchError(path=self.root_transport.base)
451
        elif response[0] == 'yes':
452
            if response[1] == 'yes':
453
                self._has_working_tree = True
454
            elif response[1] == 'no':
455
                self._has_working_tree = False
456
            else:
457
                raise errors.UnexpectedSmartServerResponse(response)
458
        else:
459
            raise errors.UnexpectedSmartServerResponse(response)
460
461
    def _rpc_open(self, path):
3786.2.3 by Andrew Bennetts
Remove duplicated 'call & translate errors' code in bzrlib.remote.
462
        response = self._call('BzrDir.open', path)
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
463
        if response not in [('yes',), ('no',)]:
464
            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.
465
        if response == ('no',):
4634.47.3 by Andrew Bennetts
Add a BzrDir.open_2.1 verb that indicates if there is a workingtree present. Removes the last 2 VFS calls from incremental pushes.
466
            raise errors.NotBranchError(path=self.root_transport.base)
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
467
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
468
    def _ensure_real(self):
469
        """Ensure that there is a _real_bzrdir set.
470
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
471
        Used before calls to self._real_bzrdir.
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
472
        """
473
        if not self._real_bzrdir:
4789.2.1 by Robert Collins
Trigger hpssvfs backtrace dumps with RemoteBzrDir._ensure_real.
474
            if 'hpssvfs' in debug.debug_flags:
475
                import traceback
476
                warning('VFS BzrDir access triggered\n%s',
477
                    ''.join(traceback.format_stack()))
5712.3.13 by Jelmer Vernooij
Add Prober.known_formats().
478
            self._real_bzrdir = _mod_bzrdir.BzrDir.open_from_transport(
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.
479
                self.root_transport, _server_formats=False)
4070.2.1 by Robert Collins
Add a BzrDirFormat.network_name.
480
            self._format._network_name = \
481
                self._real_bzrdir._format.network_name()
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
482
3786.2.3 by Andrew Bennetts
Remove duplicated 'call & translate errors' code in bzrlib.remote.
483
    def _translate_error(self, err, **context):
484
        _translate_error(err, bzrdir=self, **context)
485
4044.1.3 by Robert Collins
Create a one-shot cache of the result of RemoteBzrDir.create_branch, eliminating 3 round trips for nonstacked branches and 5 for stacked.
486
    def break_lock(self):
487
        # Prevent aliasing problems in the next_open_branch_result cache.
488
        # See create_branch for rationale.
489
        self._next_open_branch_result = None
5712.3.13 by Jelmer Vernooij
Add Prober.known_formats().
490
        return _mod_bzrdir.BzrDir.break_lock(self)
4044.1.3 by Robert Collins
Create a one-shot cache of the result of RemoteBzrDir.create_branch, eliminating 3 round trips for nonstacked branches and 5 for stacked.
491
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
492
    def _vfs_cloning_metadir(self, require_stacking=False):
3242.3.28 by Aaron Bentley
Use repository acquisition policy for sprouting
493
        self._ensure_real()
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
494
        return self._real_bzrdir.cloning_metadir(
495
            require_stacking=require_stacking)
496
497
    def cloning_metadir(self, require_stacking=False):
498
        medium = self._client._medium
499
        if medium._is_remote_before((1, 13)):
500
            return self._vfs_cloning_metadir(require_stacking=require_stacking)
501
        verb = 'BzrDir.cloning_metadir'
502
        if require_stacking:
503
            stacking = 'True'
504
        else:
505
            stacking = 'False'
506
        path = self._path_for_remote_call(self._client)
507
        try:
508
            response = self._call(verb, path, stacking)
509
        except errors.UnknownSmartMethod:
4094.1.1 by Andrew Bennetts
Add some medium._remember_is_before((1, 13)) calls.
510
            medium._remember_remote_is_before((1, 13))
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
511
            return self._vfs_cloning_metadir(require_stacking=require_stacking)
4160.2.9 by Andrew Bennetts
Fix BzrDir.cloning_metadir RPC to fail on branch references, and make
512
        except errors.UnknownErrorFromSmartServer, err:
513
            if err.error_tuple != ('BranchReference',):
514
                raise
515
            # We need to resolve the branch reference to determine the
516
            # cloning_metadir.  This causes unnecessary RPCs to open the
517
            # referenced branch (and bzrdir, etc) but only when the caller
518
            # didn't already resolve the branch reference.
519
            referenced_branch = self.open_branch()
520
            return referenced_branch.bzrdir.cloning_metadir()
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
521
        if len(response) != 3:
522
            raise errors.UnexpectedSmartServerResponse(response)
4070.7.4 by Andrew Bennetts
Deal with branch references better in BzrDir.cloning_metadir RPC (changes protocol).
523
        control_name, repo_name, branch_info = response
524
        if len(branch_info) != 2:
525
            raise errors.UnexpectedSmartServerResponse(response)
526
        branch_ref, branch_name = branch_info
6305.4.1 by Jelmer Vernooij
Print sensible error message when remote format is unknown.
527
        try:
528
            format = controldir.network_format_registry.get(control_name)
529
        except KeyError:
530
            raise errors.UnknownFormatError(kind='control', format=control_name)
531
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
532
        if repo_name:
6305.4.1 by Jelmer Vernooij
Print sensible error message when remote format is unknown.
533
            try:
534
                format.repository_format = _mod_repository.network_format_registry.get(
535
                    repo_name)
536
            except KeyError:
537
                raise errors.UnknownFormatError(kind='repository',
538
                    format=repo_name)
4084.2.2 by Robert Collins
Review feedback.
539
        if branch_ref == 'ref':
4070.7.4 by Andrew Bennetts
Deal with branch references better in BzrDir.cloning_metadir RPC (changes protocol).
540
            # XXX: we need possible_transports here to avoid reopening the
4070.7.5 by Andrew Bennetts
Tweak comment.
541
            # connection to the referenced location
5712.3.13 by Jelmer Vernooij
Add Prober.known_formats().
542
            ref_bzrdir = _mod_bzrdir.BzrDir.open(branch_name)
4070.7.4 by Andrew Bennetts
Deal with branch references better in BzrDir.cloning_metadir RPC (changes protocol).
543
            branch_format = ref_bzrdir.cloning_metadir().get_branch_format()
544
            format.set_branch_format(branch_format)
4084.2.2 by Robert Collins
Review feedback.
545
        elif branch_ref == 'branch':
4070.7.4 by Andrew Bennetts
Deal with branch references better in BzrDir.cloning_metadir RPC (changes protocol).
546
            if branch_name:
6305.4.1 by Jelmer Vernooij
Print sensible error message when remote format is unknown.
547
                try:
548
                    branch_format = branch.network_format_registry.get(
549
                        branch_name)
550
                except KeyError:
551
                    raise errors.UnknownFormatError(kind='branch',
552
                        format=branch_name)
553
                format.set_branch_format(branch_format)
4070.7.4 by Andrew Bennetts
Deal with branch references better in BzrDir.cloning_metadir RPC (changes protocol).
554
        else:
555
            raise errors.UnexpectedSmartServerResponse(response)
4070.2.3 by Robert Collins
Get BzrDir.cloning_metadir working.
556
        return format
3242.3.28 by Aaron Bentley
Use repository acquisition policy for sprouting
557
1752.2.39 by Martin Pool
[broken] implement upgrade apis on remote bzrdirs
558
    def create_repository(self, shared=False):
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
559
        # as per meta1 formats - just delegate to the format object which may
560
        # be parameterised.
561
        result = self._format.repository_format.initialize(self, shared)
562
        if not isinstance(result, RemoteRepository):
563
            return self.open_repository()
564
        else:
565
            return result
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
566
2796.2.19 by Aaron Bentley
Support reconfigure --lightweight-checkout
567
    def destroy_repository(self):
568
        """See BzrDir.destroy_repository"""
6266.2.1 by Jelmer Vernooij
New HPSS call BzrDir.destroy_repository.
569
        path = self._path_for_remote_call(self._client)
570
        try:
571
            response = self._call('BzrDir.destroy_repository', path)
572
        except errors.UnknownSmartMethod:
573
            self._ensure_real()
574
            self._real_bzrdir.destroy_repository()
575
            return
576
        if response[0] != 'ok':
577
            raise SmartProtocolError('unexpected response code %s' % (response,))
2796.2.19 by Aaron Bentley
Support reconfigure --lightweight-checkout
578
6123.9.12 by Jelmer Vernooij
Add append_revisions_only argument to BranchFormat.initialize.
579
    def create_branch(self, name=None, repository=None,
580
                      append_revisions_only=None):
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
581
        # as per meta1 formats - just delegate to the format object which may
582
        # be parameterised.
5051.3.10 by Jelmer Vernooij
Pass colocated branch name around in more places.
583
        real_branch = self._format.get_branch_format().initialize(self,
6123.9.12 by Jelmer Vernooij
Add append_revisions_only argument to BranchFormat.initialize.
584
            name=name, repository=repository,
585
            append_revisions_only=append_revisions_only)
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
586
        if not isinstance(real_branch, RemoteBranch):
5536.1.1 by Andrew Bennetts
Avoid reopening (and relocking) the same branches/repositories in ControlDir.sprout. Still a few rough edges, but the tests I've run are passing.
587
            if not isinstance(repository, RemoteRepository):
5536.1.10 by Andrew Bennetts
Give more helpful message in AssertionErrors, just in case.
588
                raise AssertionError(
589
                    'need a RemoteRepository to use with RemoteBranch, got %r'
590
                    % (repository,))
5536.1.1 by Andrew Bennetts
Avoid reopening (and relocking) the same branches/repositories in ControlDir.sprout. Still a few rough edges, but the tests I've run are passing.
591
            result = RemoteBranch(self, repository, real_branch, name=name)
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
592
        else:
4044.1.3 by Robert Collins
Create a one-shot cache of the result of RemoteBzrDir.create_branch, eliminating 3 round trips for nonstacked branches and 5 for stacked.
593
            result = real_branch
594
        # BzrDir.clone_on_transport() uses the result of create_branch but does
595
        # not return it to its callers; we save approximately 8% of our round
596
        # trips by handing the branch we created back to the first caller to
597
        # open_branch rather than probing anew. Long term we need a API in
598
        # bzrdir that doesn't discard result objects (like result_branch).
599
        # RBC 20090225
600
        self._next_open_branch_result = result
601
        return result
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
602
5051.3.3 by Jelmer Vernooij
Add tests for colo branches.
603
    def destroy_branch(self, name=None):
2796.2.16 by Aaron Bentley
Documentation updates from review
604
        """See BzrDir.destroy_branch"""
6266.4.1 by Jelmer Vernooij
HPSS call 'BzrDir.destroy_branch'.
605
        path = self._path_for_remote_call(self._client)
606
        try:
6266.4.3 by Jelmer Vernooij
fix tests.
607
            if name is not None:
608
                args = (name, )
609
            else:
610
                args = ()
611
            response = self._call('BzrDir.destroy_branch', path, *args)
6266.4.1 by Jelmer Vernooij
HPSS call 'BzrDir.destroy_branch'.
612
        except errors.UnknownSmartMethod:
613
            self._ensure_real()
614
            self._real_bzrdir.destroy_branch(name=name)
615
            self._next_open_branch_result = None
616
            return
6266.4.3 by Jelmer Vernooij
fix tests.
617
        self._next_open_branch_result = None
6266.4.1 by Jelmer Vernooij
HPSS call 'BzrDir.destroy_branch'.
618
        if response[0] != 'ok':
619
            raise SmartProtocolError('unexpected response code %s' % (response,))
2796.2.6 by Aaron Bentley
Implement destroy_branch
620
5042.1.1 by Neil Martinsen-Burrell
Fix signature of RemoteBzrDir.create_workingtree
621
    def create_workingtree(self, revision_id=None, from_branch=None,
622
        accelerator_tree=None, hardlink=False):
2018.5.174 by Andrew Bennetts
Various nits discovered by pyflakes.
623
        raise errors.NotLocalUrl(self.transport.base)
1752.2.39 by Martin Pool
[broken] implement upgrade apis on remote bzrdirs
624
5147.4.1 by Jelmer Vernooij
Pass branch names in more places.
625
    def find_branch_format(self, name=None):
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.
626
        """Find the branch 'format' for this bzrdir.
627
628
        This might be a synthetic object for e.g. RemoteBranch and SVN.
629
        """
5147.4.3 by Jelmer Vernooij
Support branch name argument to BzrDir.get_branch_reference.
630
        b = self.open_branch(name=name)
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.
631
        return b._format
632
5147.4.3 by Jelmer Vernooij
Support branch name argument to BzrDir.get_branch_reference.
633
    def get_branch_reference(self, name=None):
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.
634
        """See BzrDir.get_branch_reference()."""
5147.4.3 by Jelmer Vernooij
Support branch name argument to BzrDir.get_branch_reference.
635
        if name is not None:
636
            # XXX JRV20100304: Support opening colocated branches
637
            raise errors.NoColocatedBranchSupport(self)
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
638
        response = self._get_branch_reference()
639
        if response[0] == 'ref':
640
            return response[1]
641
        else:
642
            return None
643
644
    def _get_branch_reference(self):
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
645
        path = self._path_for_remote_call(self._client)
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
646
        medium = self._client._medium
4734.4.8 by Andrew Bennetts
Fix HPSS tests; pass 'location is a repository' message via smart server when possible (adds BzrDir.open_branchV3 verb).
647
        candidate_calls = [
648
            ('BzrDir.open_branchV3', (2, 1)),
649
            ('BzrDir.open_branchV2', (1, 13)),
650
            ('BzrDir.open_branch', None),
651
            ]
652
        for verb, required_version in candidate_calls:
653
            if required_version and medium._is_remote_before(required_version):
654
                continue
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
655
            try:
4734.4.8 by Andrew Bennetts
Fix HPSS tests; pass 'location is a repository' message via smart server when possible (adds BzrDir.open_branchV3 verb).
656
                response = self._call(verb, path)
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
657
            except errors.UnknownSmartMethod:
4734.4.8 by Andrew Bennetts
Fix HPSS tests; pass 'location is a repository' message via smart server when possible (adds BzrDir.open_branchV3 verb).
658
                if required_version is None:
659
                    raise
660
                medium._remember_remote_is_before(required_version)
661
            else:
662
                break
663
        if verb == 'BzrDir.open_branch':
664
            if response[0] != 'ok':
665
                raise errors.UnexpectedSmartServerResponse(response)
666
            if response[1] != '':
667
                return ('ref', response[1])
668
            else:
669
                return ('branch', '')
670
        if response[0] not in ('ref', 'branch'):
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
671
            raise errors.UnexpectedSmartServerResponse(response)
4734.4.8 by Andrew Bennetts
Fix HPSS tests; pass 'location is a repository' message via smart server when possible (adds BzrDir.open_branchV3 verb).
672
        return 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.
673
5147.4.1 by Jelmer Vernooij
Pass branch names in more places.
674
    def _get_tree_branch(self, name=None):
3211.4.1 by Robert Collins
* ``RemoteBzrDir._get_tree_branch`` no longer triggers ``_ensure_real``,
675
        """See BzrDir._get_tree_branch()."""
5147.4.1 by Jelmer Vernooij
Pass branch names in more places.
676
        return None, self.open_branch(name=name)
3211.4.1 by Robert Collins
* ``RemoteBzrDir._get_tree_branch`` no longer triggers ``_ensure_real``,
677
5051.3.4 by Jelmer Vernooij
Support name to BzrDir.open_branch.
678
    def open_branch(self, name=None, unsupported=False,
6305.3.2 by Jelmer Vernooij
Only make a single connection.
679
                    ignore_fallbacks=False, possible_transports=None):
5051.3.4 by Jelmer Vernooij
Support name to BzrDir.open_branch.
680
        if unsupported:
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
681
            raise NotImplementedError('unsupported flag support not implemented yet.')
4044.1.3 by Robert Collins
Create a one-shot cache of the result of RemoteBzrDir.create_branch, eliminating 3 round trips for nonstacked branches and 5 for stacked.
682
        if self._next_open_branch_result is not None:
683
            # See create_branch for details.
684
            result = self._next_open_branch_result
685
            self._next_open_branch_result = None
686
            return result
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
687
        response = self._get_branch_reference()
688
        if response[0] == 'ref':
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.
689
            # a branch reference, use the existing BranchReference logic.
690
            format = BranchReferenceFormat()
5051.3.10 by Jelmer Vernooij
Pass colocated branch name around in more places.
691
            return format.open(self, name=name, _found=True,
6305.3.2 by Jelmer Vernooij
Only make a single connection.
692
                location=response[1], ignore_fallbacks=ignore_fallbacks,
693
                possible_transports=possible_transports)
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
694
        branch_format_name = response[1]
695
        if not branch_format_name:
696
            branch_format_name = None
697
        format = RemoteBranchFormat(network_name=branch_format_name)
4160.2.6 by Andrew Bennetts
Add ignore_fallbacks flag.
698
        return RemoteBranch(self, self.find_repository(), format=format,
6305.3.6 by Jelmer Vernooij
Pass possible_transports along for remote branches.
699
            setup_stacking=not ignore_fallbacks, name=name,
700
            possible_transports=possible_transports)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
701
4053.1.1 by Robert Collins
New version of the BzrDir.find_repository verb supporting _network_name to support removing more _ensure_real calls.
702
    def _open_repo_v1(self, path):
703
        verb = 'BzrDir.find_repository'
704
        response = self._call(verb, path)
705
        if response[0] != 'ok':
706
            raise errors.UnexpectedSmartServerResponse(response)
707
        # servers that only support the v1 method don't support external
708
        # references either.
709
        self._ensure_real()
710
        repo = self._real_bzrdir.open_repository()
711
        response = response + ('no', repo._format.network_name())
712
        return response, repo
713
714
    def _open_repo_v2(self, path):
715
        verb = 'BzrDir.find_repositoryV2'
716
        response = self._call(verb, path)
717
        if response[0] != 'ok':
718
            raise errors.UnexpectedSmartServerResponse(response)
719
        self._ensure_real()
720
        repo = self._real_bzrdir.open_repository()
721
        response = response + (repo._format.network_name(),)
722
        return response, repo
723
724
    def _open_repo_v3(self, path):
725
        verb = 'BzrDir.find_repositoryV3'
4053.1.2 by Robert Collins
Actually make this branch work.
726
        medium = self._client._medium
727
        if medium._is_remote_before((1, 13)):
728
            raise errors.UnknownSmartMethod(verb)
4094.1.1 by Andrew Bennetts
Add some medium._remember_is_before((1, 13)) calls.
729
        try:
730
            response = self._call(verb, path)
731
        except errors.UnknownSmartMethod:
732
            medium._remember_remote_is_before((1, 13))
733
            raise
4053.1.1 by Robert Collins
New version of the BzrDir.find_repository verb supporting _network_name to support removing more _ensure_real calls.
734
        if response[0] != 'ok':
735
            raise errors.UnexpectedSmartServerResponse(response)
736
        return response, None
737
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
738
    def open_repository(self):
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
739
        path = self._path_for_remote_call(self._client)
4053.1.1 by Robert Collins
New version of the BzrDir.find_repository verb supporting _network_name to support removing more _ensure_real calls.
740
        response = None
741
        for probe in [self._open_repo_v3, self._open_repo_v2,
742
            self._open_repo_v1]:
743
            try:
744
                response, real_repo = probe(path)
745
                break
746
            except errors.UnknownSmartMethod:
747
                pass
748
        if response is None:
749
            raise errors.UnknownSmartMethod('BzrDir.find_repository{3,2,}')
3245.4.24 by Andrew Bennetts
Consistently raise errors from the server as ErrorFromSmartServer exceptions.
750
        if response[0] != 'ok':
751
            raise errors.UnexpectedSmartServerResponse(response)
4053.1.1 by Robert Collins
New version of the BzrDir.find_repository verb supporting _network_name to support removing more _ensure_real calls.
752
        if len(response) != 6:
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
753
            raise SmartProtocolError('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.
754
        if response[1] == '':
4053.1.1 by Robert Collins
New version of the BzrDir.find_repository verb supporting _network_name to support removing more _ensure_real calls.
755
            # repo is at this dir.
756
            format = response_tuple_to_repo_format(response[2:])
3221.15.10 by Robert Collins
Add test that we can stack on a smart server from Jonathan Lange.
757
            # Used to support creating a real format instance when needed.
758
            format._creating_bzrdir = self
3990.5.1 by Andrew Bennetts
Add network_name() to RepositoryFormat.
759
            remote_repo = RemoteRepository(self, format)
760
            format._creating_repo = remote_repo
4053.1.1 by Robert Collins
New version of the BzrDir.find_repository verb supporting _network_name to support removing more _ensure_real calls.
761
            if real_repo is not None:
762
                remote_repo._set_real_repository(real_repo)
3990.5.1 by Andrew Bennetts
Add network_name() to RepositoryFormat.
763
            return remote_repo
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
764
        else:
765
            raise errors.NoRepositoryPresent(self)
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
766
4634.47.5 by Andrew Bennetts
Add tests, and fix BzrDirMeta1.has_workingtree which was failing if the local transport is decorated with a ChrootTransport or similar.
767
    def has_workingtree(self):
4634.47.3 by Andrew Bennetts
Add a BzrDir.open_2.1 verb that indicates if there is a workingtree present. Removes the last 2 VFS calls from incremental pushes.
768
        if self._has_working_tree is None:
6266.3.1 by Jelmer Vernooij
Add HPSS call for BzrDir.has_workingtree.
769
            path = self._path_for_remote_call(self._client)
770
            try:
771
                response = self._call('BzrDir.has_workingtree', path)
772
            except errors.UnknownSmartMethod:
773
                self._ensure_real()
774
                self._has_working_tree = self._real_bzrdir.has_workingtree()
775
            else:
776
                if response[0] not in ('yes', 'no'):
777
                    raise SmartProtocolError('unexpected response code %s' % (response,))
778
                self._has_working_tree = (response[0] == 'yes')
4634.47.5 by Andrew Bennetts
Add tests, and fix BzrDirMeta1.has_workingtree which was failing if the local transport is decorated with a ChrootTransport or similar.
779
        return self._has_working_tree
780
781
    def open_workingtree(self, recommend_upgrade=True):
782
        if self.has_workingtree():
2445.1.1 by Andrew Bennetts
Make RemoteBzrDir.open_workingtree raise NoWorkingTree rather than NotLocalUrl
783
            raise errors.NotLocalUrl(self.root_transport)
784
        else:
785
            raise errors.NoWorkingTree(self.root_transport.base)
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
786
2018.5.42 by Robert Collins
Various hopefully improvements, but wsgi is broken, handing over to spiv :).
787
    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.
788
        """Return the path to be used for this bzrdir in a remote call."""
5268.7.29 by Jelmer Vernooij
Fix remote tests.
789
        return urlutils.split_segment_parameters_raw(
790
            client.remote_path_from_transport(self.root_transport))[0]
2018.6.1 by Robert Collins
Implement a BzrDir.open_branch smart server method for opening a branch without VFS.
791
5051.3.10 by Jelmer Vernooij
Pass colocated branch name around in more places.
792
    def get_branch_transport(self, branch_format, name=None):
2018.5.162 by Andrew Bennetts
Add some missing _ensure_real calls, and a missing import.
793
        self._ensure_real()
5051.3.10 by Jelmer Vernooij
Pass colocated branch name around in more places.
794
        return self._real_bzrdir.get_branch_transport(branch_format, name=name)
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
795
1752.2.43 by Andrew Bennetts
Fix get_{branch,repository,workingtree}_transport.
796
    def get_repository_transport(self, repository_format):
2018.5.162 by Andrew Bennetts
Add some missing _ensure_real calls, and a missing import.
797
        self._ensure_real()
1752.2.43 by Andrew Bennetts
Fix get_{branch,repository,workingtree}_transport.
798
        return self._real_bzrdir.get_repository_transport(repository_format)
799
800
    def get_workingtree_transport(self, workingtree_format):
2018.5.162 by Andrew Bennetts
Add some missing _ensure_real calls, and a missing import.
801
        self._ensure_real()
1752.2.43 by Andrew Bennetts
Fix get_{branch,repository,workingtree}_transport.
802
        return self._real_bzrdir.get_workingtree_transport(workingtree_format)
803
1752.2.39 by Martin Pool
[broken] implement upgrade apis on remote bzrdirs
804
    def can_convert_format(self):
805
        """Upgrading of remote bzrdirs is not supported yet."""
806
        return False
807
5670.1.1 by Jelmer Vernooij
Remove all methods and arguments that were deprecated before bzr 2.0.0.
808
    def needs_format_conversion(self, format):
1752.2.39 by Martin Pool
[broken] implement upgrade apis on remote bzrdirs
809
        """Upgrading of remote bzrdirs is not supported yet."""
810
        return False
811
4288.1.1 by Robert Collins
Add support for a RemoteBzrDirConfig to support optimising push operations which need to look for default stacking locations.
812
    def _get_config(self):
813
        return RemoteBzrDirConfig(self)
3567.1.3 by Michael Hudson
fix problem
814
6270.1.19 by Jelmer Vernooij
Some changes discussed with vila on IRC.
815
    def _get_config_store(self):
816
        return RemoteControlStore(self)
6270.1.4 by Jelmer Vernooij
Add Branch.get_config_stack / BzrDir.get_config_stack.
817
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
818
5815.4.5 by Jelmer Vernooij
Use MetaDirVersionedFileRepositoryFormat (a Soyuz worthy name).
819
class RemoteRepositoryFormat(vf_repository.VersionedFileRepositoryFormat):
2018.5.159 by Andrew Bennetts
Rename SmartClient to _SmartClient.
820
    """Format for repositories accessed over a _SmartClient.
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
821
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
822
    Instances of this repository are represented by RemoteRepository
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
823
    instances.
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
824
3128.1.3 by Vincent Ladeuil
Since we are there s/parameteris.*/parameteriz&/.
825
    The RemoteRepositoryFormat is parameterized during construction
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
826
    to reflect the capabilities of the real, remote format. Specifically
2018.5.138 by Robert Collins
Merge bzr.dev.
827
    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.
828
    on a per instance basis, and are not set (and should not be) at
829
    the class level.
3990.5.3 by Robert Collins
Docs and polish on RepositoryFormat.network_name.
830
4032.1.1 by John Arbash Meinel
Merge the removal of all trailing whitespace, and resolve conflicts.
831
    :ivar _custom_format: If set, a specific concrete repository format that
3990.5.3 by Robert Collins
Docs and polish on RepositoryFormat.network_name.
832
        will be used when initializing a repository with this
833
        RemoteRepositoryFormat.
834
    :ivar _creating_repo: If set, the repository object that this
835
        RemoteRepositoryFormat was created for: it can be called into
3990.5.4 by Robert Collins
Review feedback.
836
        to obtain data like the network name.
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
837
    """
838
3543.1.2 by Michael Hudson
the two character fix
839
    _matchingbzrdir = RemoteBzrDirFormat()
5684.2.1 by Jelmer Vernooij
Add bzrlib.tests.per_repository_vf.
840
    supports_full_versioned_files = True
5684.2.6 by Jelmer Vernooij
Implement .supports_funky_characters and .supports_leaving_lock.
841
    supports_leaving_lock = True
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
842
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
843
    def __init__(self):
5712.3.17 by Jelmer Vernooij
more fixes.
844
        _mod_repository.RepositoryFormat.__init__(self)
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
845
        self._custom_format = None
4017.3.2 by Robert Collins
Reduce the number of round trips required to create a repository over the network.
846
        self._network_name = None
4017.3.3 by Robert Collins
Review feedback - make RemoteRepository.initialize use helpers, and version-lock the new method to not attempt the method on older servers.
847
        self._creating_bzrdir = None
5766.1.1 by Jelmer Vernooij
Make revision-graph-can-have-wrong-parents a repository format attribute rather than a repository method.
848
        self._revision_graph_can_have_wrong_parents = None
4476.3.15 by Andrew Bennetts
Partially working fallback for pre-1.17 servers.
849
        self._supports_chks = None
4118.1.1 by Andrew Bennetts
Fix performance regression (many small round-trips) when pushing to a remote pack, and tidy the tests.
850
        self._supports_external_lookups = None
851
        self._supports_tree_reference = None
5684.2.6 by Jelmer Vernooij
Implement .supports_funky_characters and .supports_leaving_lock.
852
        self._supports_funky_characters = None
6145.2.2 by Jelmer Vernooij
Set supports_nesting_repositories.
853
        self._supports_nesting_repositories = None
4118.1.1 by Andrew Bennetts
Fix performance regression (many small round-trips) when pushing to a remote pack, and tidy the tests.
854
        self._rich_root_data = None
855
4608.1.2 by Martin Pool
Add RemoteRepositoryFormat repr
856
    def __repr__(self):
857
        return "%s(_network_name=%r)" % (self.__class__.__name__,
858
            self._network_name)
859
4118.1.1 by Andrew Bennetts
Fix performance regression (many small round-trips) when pushing to a remote pack, and tidy the tests.
860
    @property
4183.5.1 by Robert Collins
Add RepositoryFormat.fast_deltas to signal fast delta creation.
861
    def fast_deltas(self):
862
        self._ensure_real()
863
        return self._custom_format.fast_deltas
864
865
    @property
4118.1.1 by Andrew Bennetts
Fix performance regression (many small round-trips) when pushing to a remote pack, and tidy the tests.
866
    def rich_root_data(self):
867
        if self._rich_root_data is None:
868
            self._ensure_real()
869
            self._rich_root_data = self._custom_format.rich_root_data
870
        return self._rich_root_data
871
872
    @property
4476.3.15 by Andrew Bennetts
Partially working fallback for pre-1.17 servers.
873
    def supports_chks(self):
874
        if self._supports_chks is None:
875
            self._ensure_real()
876
            self._supports_chks = self._custom_format.supports_chks
877
        return self._supports_chks
878
879
    @property
4118.1.1 by Andrew Bennetts
Fix performance regression (many small round-trips) when pushing to a remote pack, and tidy the tests.
880
    def supports_external_lookups(self):
881
        if self._supports_external_lookups is None:
882
            self._ensure_real()
883
            self._supports_external_lookups = \
4104.4.2 by Robert Collins
Fix test_source for 1.13 landing.
884
                self._custom_format.supports_external_lookups
4118.1.1 by Andrew Bennetts
Fix performance regression (many small round-trips) when pushing to a remote pack, and tidy the tests.
885
        return self._supports_external_lookups
886
887
    @property
5684.2.6 by Jelmer Vernooij
Implement .supports_funky_characters and .supports_leaving_lock.
888
    def supports_funky_characters(self):
889
        if self._supports_funky_characters is None:
890
            self._ensure_real()
891
            self._supports_funky_characters = \
892
                self._custom_format.supports_funky_characters
893
        return self._supports_funky_characters
894
895
    @property
6145.2.2 by Jelmer Vernooij
Set supports_nesting_repositories.
896
    def supports_nesting_repositories(self):
897
        if self._supports_nesting_repositories is None:
898
            self._ensure_real()
899
            self._supports_nesting_repositories = \
900
                self._custom_format.supports_nesting_repositories
901
        return self._supports_nesting_repositories
902
903
    @property
4118.1.1 by Andrew Bennetts
Fix performance regression (many small round-trips) when pushing to a remote pack, and tidy the tests.
904
    def supports_tree_reference(self):
905
        if self._supports_tree_reference is None:
906
            self._ensure_real()
907
            self._supports_tree_reference = \
908
                self._custom_format.supports_tree_reference
909
        return self._supports_tree_reference
4017.3.3 by Robert Collins
Review feedback - make RemoteRepository.initialize use helpers, and version-lock the new method to not attempt the method on older servers.
910
5766.1.1 by Jelmer Vernooij
Make revision-graph-can-have-wrong-parents a repository format attribute rather than a repository method.
911
    @property
912
    def revision_graph_can_have_wrong_parents(self):
913
        if self._revision_graph_can_have_wrong_parents is None:
914
            self._ensure_real()
915
            self._revision_graph_can_have_wrong_parents = \
916
                self._custom_format.revision_graph_can_have_wrong_parents
917
        return self._revision_graph_can_have_wrong_parents
918
4017.3.3 by Robert Collins
Review feedback - make RemoteRepository.initialize use helpers, and version-lock the new method to not attempt the method on older servers.
919
    def _vfs_initialize(self, a_bzrdir, shared):
920
        """Helper for common code in initialize."""
921
        if self._custom_format:
922
            # Custom format requested
923
            result = self._custom_format.initialize(a_bzrdir, shared=shared)
924
        elif self._creating_bzrdir is not None:
925
            # Use the format that the repository we were created to back
926
            # has.
927
            prior_repo = self._creating_bzrdir.open_repository()
928
            prior_repo._ensure_real()
929
            result = prior_repo._real_repository._format.initialize(
930
                a_bzrdir, shared=shared)
931
        else:
932
            # assume that a_bzr is a RemoteBzrDir but the smart server didn't
933
            # support remote initialization.
934
            # We delegate to a real object at this point (as RemoteBzrDir
935
            # delegate to the repository format which would lead to infinite
936
            # recursion if we just called a_bzrdir.create_repository.
937
            a_bzrdir._ensure_real()
938
            result = a_bzrdir._real_bzrdir.create_repository(shared=shared)
939
        if not isinstance(result, RemoteRepository):
940
            return self.open(a_bzrdir)
941
        else:
942
            return result
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
943
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
944
    def initialize(self, a_bzrdir, shared=False):
4017.3.2 by Robert Collins
Reduce the number of round trips required to create a repository over the network.
945
        # Being asked to create on a non RemoteBzrDir:
946
        if not isinstance(a_bzrdir, RemoteBzrDir):
4017.3.3 by Robert Collins
Review feedback - make RemoteRepository.initialize use helpers, and version-lock the new method to not attempt the method on older servers.
947
            return self._vfs_initialize(a_bzrdir, shared)
948
        medium = a_bzrdir._client._medium
949
        if medium._is_remote_before((1, 13)):
950
            return self._vfs_initialize(a_bzrdir, shared)
4017.3.2 by Robert Collins
Reduce the number of round trips required to create a repository over the network.
951
        # Creating on a remote bzr dir.
952
        # 1) get the network name to use.
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
953
        if self._custom_format:
4017.3.2 by Robert Collins
Reduce the number of round trips required to create a repository over the network.
954
            network_name = self._custom_format.network_name()
4294.2.5 by Robert Collins
Reasonable unit test coverage for initialize_on_transport_ex.
955
        elif self._network_name:
956
            network_name = self._network_name
4017.3.2 by Robert Collins
Reduce the number of round trips required to create a repository over the network.
957
        else:
958
            # Select the current bzrlib default and ask for that.
5712.3.13 by Jelmer Vernooij
Add Prober.known_formats().
959
            reference_bzrdir_format = _mod_bzrdir.format_registry.get('default')()
4017.3.2 by Robert Collins
Reduce the number of round trips required to create a repository over the network.
960
            reference_format = reference_bzrdir_format.repository_format
961
            network_name = reference_format.network_name()
962
        # 2) try direct creation via RPC
963
        path = a_bzrdir._path_for_remote_call(a_bzrdir._client)
964
        verb = 'BzrDir.create_repository'
965
        if shared:
966
            shared_str = 'True'
967
        else:
968
            shared_str = 'False'
969
        try:
970
            response = a_bzrdir._call(verb, path, network_name, shared_str)
971
        except errors.UnknownSmartMethod:
4017.3.3 by Robert Collins
Review feedback - make RemoteRepository.initialize use helpers, and version-lock the new method to not attempt the method on older servers.
972
            # Fallback - use vfs methods
4094.1.1 by Andrew Bennetts
Add some medium._remember_is_before((1, 13)) calls.
973
            medium._remember_remote_is_before((1, 13))
4017.3.3 by Robert Collins
Review feedback - make RemoteRepository.initialize use helpers, and version-lock the new method to not attempt the method on older servers.
974
            return self._vfs_initialize(a_bzrdir, shared)
4017.3.2 by Robert Collins
Reduce the number of round trips required to create a repository over the network.
975
        else:
976
            # Turn the response into a RemoteRepository object.
4032.3.2 by Robert Collins
Create and use a RPC call to create branches on bzr servers rather than using VFS calls.
977
            format = response_tuple_to_repo_format(response[1:])
4017.3.2 by Robert Collins
Reduce the number of round trips required to create a repository over the network.
978
            # Used to support creating a real format instance when needed.
979
            format._creating_bzrdir = a_bzrdir
980
            remote_repo = RemoteRepository(a_bzrdir, format)
981
            format._creating_repo = remote_repo
982
            return remote_repo
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
983
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
984
    def open(self, a_bzrdir):
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
985
        if not isinstance(a_bzrdir, RemoteBzrDir):
986
            raise AssertionError('%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.
987
        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.
988
4053.1.4 by Robert Collins
Move the fetch control attributes from Repository to RepositoryFormat.
989
    def _ensure_real(self):
990
        if self._custom_format is None:
6305.4.1 by Jelmer Vernooij
Print sensible error message when remote format is unknown.
991
            try:
992
                self._custom_format = _mod_repository.network_format_registry.get(
993
                    self._network_name)
994
            except KeyError:
995
                raise errors.UnknownFormatError(kind='repository',
996
                    format=self._network_name)
4053.1.4 by Robert Collins
Move the fetch control attributes from Repository to RepositoryFormat.
997
998
    @property
999
    def _fetch_order(self):
1000
        self._ensure_real()
1001
        return self._custom_format._fetch_order
1002
1003
    @property
1004
    def _fetch_uses_deltas(self):
1005
        self._ensure_real()
1006
        return self._custom_format._fetch_uses_deltas
1007
1008
    @property
1009
    def _fetch_reconcile(self):
1010
        self._ensure_real()
1011
        return self._custom_format._fetch_reconcile
1012
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
1013
    def get_format_description(self):
4792.1.1 by Andrew Bennetts
Show real branch/repo format description in 'info -v' over HPSS.
1014
        self._ensure_real()
1015
        return 'Remote: ' + self._custom_format.get_format_description()
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
1016
1017
    def __eq__(self, other):
4088.3.1 by Benjamin Peterson
compare types with 'is' not ==
1018
        return self.__class__ is other.__class__
1752.2.87 by Andrew Bennetts
Make tests pass.
1019
3990.5.1 by Andrew Bennetts
Add network_name() to RepositoryFormat.
1020
    def network_name(self):
4017.3.2 by Robert Collins
Reduce the number of round trips required to create a repository over the network.
1021
        if self._network_name:
1022
            return self._network_name
3990.5.1 by Andrew Bennetts
Add network_name() to RepositoryFormat.
1023
        self._creating_repo._ensure_real()
1024
        return self._creating_repo._real_repository._format.network_name()
1025
4022.1.1 by Robert Collins
Refactoring of fetch to have a sender and sink component enabling splitting the logic over a network stream. (Robert Collins, Andrew Bennetts)
1026
    @property
4431.3.7 by Jonathan Lange
Cherrypick bzr.dev 4470, resolving conflicts.
1027
    def pack_compresses(self):
1028
        self._ensure_real()
1029
        return self._custom_format.pack_compresses
1030
1031
    @property
4022.1.1 by Robert Collins
Refactoring of fetch to have a sender and sink component enabling splitting the logic over a network stream. (Robert Collins, Andrew Bennetts)
1032
    def _serializer(self):
4053.1.4 by Robert Collins
Move the fetch control attributes from Repository to RepositoryFormat.
1033
        self._ensure_real()
1034
        return self._custom_format._serializer
4022.1.1 by Robert Collins
Refactoring of fetch to have a sender and sink component enabling splitting the logic over a network stream. (Robert Collins, Andrew Bennetts)
1035
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
1036
6289.1.1 by Jelmer Vernooij
Make Repository a base class of RemoteRepository
1037
class RemoteRepository(_mod_repository.Repository, _RpcHelper,
1038
        lock._RelockDebugMixin):
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
1039
    """Repository accessed over rpc.
1040
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
1041
    For the moment most operations are performed using local transport-backed
1042
    Repository objects.
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
1043
    """
1044
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
1045
    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.
1046
        """Create a RemoteRepository instance.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1047
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
1048
        :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.
1049
        :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.
1050
        :param real_repository: If not None, a local implementation of the
1051
            repository logic for the repository, usually accessing the data
1052
            via the VFS.
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
1053
        :param _client: Private testing parameter - override the smart client
1054
            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.
1055
        """
1056
        if real_repository:
2018.5.36 by Andrew Bennetts
Fix typo, and clean up some ununsed import warnings from pyflakes at the same time.
1057
            self._real_repository = real_repository
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
1058
        else:
1059
            self._real_repository = None
1752.2.50 by Andrew Bennetts
Implement RemoteBzrDir.create_{branch,workingtree}
1060
        self.bzrdir = remote_bzrdir
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
1061
        if _client is None:
3313.2.1 by Andrew Bennetts
Change _SmartClient's API to accept a medium and a base, rather than a _SharedConnection.
1062
            self._client = remote_bzrdir._client
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
1063
        else:
1064
            self._client = _client
2018.5.118 by Robert Collins
Fix RemoteRepositoryFormat to have appropriate rich_root_data and support_tree_reference.
1065
        self._format = format
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
1066
        self._lock_mode = None
1067
        self._lock_token = None
6280.7.2 by Jelmer Vernooij
Add HPSS calls ``Repository.start_write_group``, ``Repository.abort_write_group`` and ``Repository.commit_write_group``.
1068
        self._write_group_tokens = None
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
1069
        self._lock_count = 0
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1070
        self._leave_lock = False
4307.2.4 by Robert Collins
Enable caching of negative revision lookups in RemoteRepository write locks when no _real_repository has been constructed.
1071
        # Cache of revision parents; misses are cached during read locks, and
1072
        # write locks when no _real_repository has been set.
3835.1.12 by Aaron Bentley
Unify CachingExtraParentsProvider and CachingParentsProvider.
1073
        self._unstacked_provider = graph.CachingParentsProvider(
3896.1.1 by Andrew Bennetts
Remove broken debugging cruft, and some unused imports.
1074
            get_parent_map=self._get_parent_map_rpc)
3835.1.12 by Aaron Bentley
Unify CachingExtraParentsProvider and CachingParentsProvider.
1075
        self._unstacked_provider.disable_cache()
2951.1.10 by Robert Collins
Peer review feedback with Ian.
1076
        # For tests:
1077
        # These depend on the actual remote format, so force them off for
1078
        # maximum compatibility. XXX: In future these should depend on the
1079
        # remote repository instance, but this is irrelevant until we perform
1080
        # 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.
1081
        self._reconcile_does_inventory_gc = False
1082
        self._reconcile_fixes_text_parents = False
2951.1.3 by Robert Collins
Partial support for native reconcile with packs.
1083
        self._reconcile_backsup_inventory = False
2592.4.5 by Martin Pool
Add Repository.base on all repositories.
1084
        self.base = self.bzrdir.transport.base
3221.12.1 by Robert Collins
Backport development1 format (stackable packs) to before-shallow-branches.
1085
        # Additional places to query for data.
1086
        self._fallback_repositories = []
2592.4.5 by Martin Pool
Add Repository.base on all repositories.
1087
5158.6.4 by Martin Pool
Repository implements ControlComponent too
1088
    @property
1089
    def user_transport(self):
1090
        return self.bzrdir.user_transport
1091
1092
    @property
1093
    def control_transport(self):
1094
        # XXX: Normally you shouldn't directly get at the remote repository
1095
        # transport, but I'm not sure it's worth making this method
1096
        # optional -- mbp 2010-04-21
1097
        return self.bzrdir.get_repository_transport(None)
5712.3.13 by Jelmer Vernooij
Add Prober.known_formats().
1098
2592.4.5 by Martin Pool
Add Repository.base on all repositories.
1099
    def __str__(self):
1100
        return "%s(%s)" % (self.__class__.__name__, self.base)
1101
1102
    __repr__ = __str__
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
1103
3825.4.1 by Andrew Bennetts
Add suppress_errors to abort_write_group.
1104
    def abort_write_group(self, suppress_errors=False):
2617.6.7 by Robert Collins
More review feedback.
1105
        """Complete a write group on the decorated repository.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1106
4031.3.3 by Matt Nordhoff
Review tweaks from Ben Finney
1107
        Smart methods perform operations in a single step so this API
2617.6.6 by Robert Collins
Some review feedback.
1108
        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.
1109
        for older plugins that don't use e.g. the CommitBuilder
1110
        facility.
3825.4.6 by Andrew Bennetts
Document the suppress_errors flag in the docstring.
1111
1112
        :param suppress_errors: see Repository.abort_write_group.
2617.6.2 by Robert Collins
Add abort_write_group and wire write_groups into fetch and commit.
1113
        """
6280.7.5 by Jelmer Vernooij
Bunch of test fixes.
1114
        if self._real_repository:
6280.7.1 by Jelmer Vernooij
Implement RemoteRepository side of write group HPSS methods.
1115
            self._ensure_real()
1116
            return self._real_repository.abort_write_group(
1117
                suppress_errors=suppress_errors)
6280.7.6 by Jelmer Vernooij
Fix remaining tests.
1118
        if not self.is_in_write_group():
1119
            if suppress_errors:
1120
                mutter('(suppressed) not in write group')
1121
                return
1122
            raise errors.BzrError("not in write group")
6280.7.5 by Jelmer Vernooij
Bunch of test fixes.
1123
        path = self.bzrdir._path_for_remote_call(self._client)
1124
        try:
1125
            response = self._call('Repository.abort_write_group', path,
1126
                self._lock_token, self._write_group_tokens)
1127
        except Exception, exc:
1128
            self._write_group = None
1129
            if not suppress_errors:
1130
                raise
1131
            mutter('abort_write_group failed')
1132
            log_exception_quietly()
1133
            note(gettext('bzr: ERROR (ignored): %s'), exc)
1134
        else:
1135
            if response != ('ok', ):
1136
                raise errors.UnexpectedSmartServerResponse(response)
1137
            self._write_group_tokens = None
2617.6.2 by Robert Collins
Add abort_write_group and wire write_groups into fetch and commit.
1138
4253.1.1 by Robert Collins
Add chk_bytes property to RemoteRepository
1139
    @property
1140
    def chk_bytes(self):
1141
        """Decorate the real repository for now.
1142
1143
        In the long term a full blown network facility is needed to avoid
1144
        creating a real repository object locally.
1145
        """
1146
        self._ensure_real()
1147
        return self._real_repository.chk_bytes
1148
2617.6.2 by Robert Collins
Add abort_write_group and wire write_groups into fetch and commit.
1149
    def commit_write_group(self):
2617.6.7 by Robert Collins
More review feedback.
1150
        """Complete a write group on the decorated repository.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1151
4031.3.3 by Matt Nordhoff
Review tweaks from Ben Finney
1152
        Smart methods perform operations in a single step so this API
2617.6.6 by Robert Collins
Some review feedback.
1153
        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.
1154
        for older plugins that don't use e.g. the CommitBuilder
1155
        facility.
1156
        """
6280.7.5 by Jelmer Vernooij
Bunch of test fixes.
1157
        if self._real_repository:
6280.7.1 by Jelmer Vernooij
Implement RemoteRepository side of write group HPSS methods.
1158
            self._ensure_real()
1159
            return self._real_repository.commit_write_group()
6280.7.6 by Jelmer Vernooij
Fix remaining tests.
1160
        if not self.is_in_write_group():
1161
            raise errors.BzrError("not in write group")
6280.7.5 by Jelmer Vernooij
Bunch of test fixes.
1162
        path = self.bzrdir._path_for_remote_call(self._client)
1163
        response = self._call('Repository.commit_write_group', path,
1164
            self._lock_token, self._write_group_tokens)
6280.7.1 by Jelmer Vernooij
Implement RemoteRepository side of write group HPSS methods.
1165
        if response != ('ok', ):
1166
            raise errors.UnexpectedSmartServerResponse(response)
6280.7.4 by Jelmer Vernooij
pass write group tokens as list/tuple.
1167
        self._write_group_tokens = None
2617.6.1 by Robert Collins
* New method on Repository - ``start_write_group``, ``end_write_group``
1168
4002.1.1 by Andrew Bennetts
Implement suspend_write_group/resume_write_group.
1169
    def resume_write_group(self, tokens):
6280.7.2 by Jelmer Vernooij
Add HPSS calls ``Repository.start_write_group``, ``Repository.abort_write_group`` and ``Repository.commit_write_group``.
1170
        if self._real_repository:
6280.7.1 by Jelmer Vernooij
Implement RemoteRepository side of write group HPSS methods.
1171
            return self._real_repository.resume_write_group(tokens)
6280.7.6 by Jelmer Vernooij
Fix remaining tests.
1172
        path = self.bzrdir._path_for_remote_call(self._client)
1173
        try:
1174
            response = self._call('Repository.check_write_group', path,
1175
               self._lock_token, tokens)
1176
        except errors.UnknownSmartMethod:
1177
            self._ensure_real()
1178
            return self._real_repository.resume_write_group(tokens)
1179
        if response != ('ok', ):
1180
            raise errors.UnexpectedSmartServerResponse(response)
6280.7.5 by Jelmer Vernooij
Bunch of test fixes.
1181
        self._write_group_tokens = tokens
4002.1.1 by Andrew Bennetts
Implement suspend_write_group/resume_write_group.
1182
1183
    def suspend_write_group(self):
6280.7.2 by Jelmer Vernooij
Add HPSS calls ``Repository.start_write_group``, ``Repository.abort_write_group`` and ``Repository.commit_write_group``.
1184
        if self._real_repository:
6280.7.1 by Jelmer Vernooij
Implement RemoteRepository side of write group HPSS methods.
1185
            return self._real_repository.suspend_write_group()
6280.7.6 by Jelmer Vernooij
Fix remaining tests.
1186
        ret = self._write_group_tokens or []
6280.7.5 by Jelmer Vernooij
Bunch of test fixes.
1187
        self._write_group_tokens = None
1188
        return ret
4002.1.1 by Andrew Bennetts
Implement suspend_write_group/resume_write_group.
1189
4343.3.29 by John Arbash Meinel
Add 'check_for_missing_texts' flag to get_missing_parent_inv..
1190
    def get_missing_parent_inventories(self, check_for_missing_texts=True):
4257.4.6 by Andrew Bennetts
Make get_missing_parent_inventories work for all repo formats (it's a no-op for unstackable formats).
1191
        self._ensure_real()
4343.3.29 by John Arbash Meinel
Add 'check_for_missing_texts' flag to get_missing_parent_inv..
1192
        return self._real_repository.get_missing_parent_inventories(
1193
            check_for_missing_texts=check_for_missing_texts)
4257.4.6 by Andrew Bennetts
Make get_missing_parent_inventories work for all repo formats (it's a no-op for unstackable formats).
1194
4419.2.9 by Andrew Bennetts
Add per_repository_reference test for get_rev_id_for_revno, fix the bugs it revealed.
1195
    def _get_rev_id_for_revno_vfs(self, revno, known_pair):
1196
        self._ensure_real()
1197
        return self._real_repository.get_rev_id_for_revno(
1198
            revno, known_pair)
1199
4419.2.5 by Andrew Bennetts
Add Repository.get_rev_id_for_revno, and use it both as the _ensure_real fallback and as the server-side implementation.
1200
    def get_rev_id_for_revno(self, revno, known_pair):
1201
        """See Repository.get_rev_id_for_revno."""
1202
        path = self.bzrdir._path_for_remote_call(self._client)
1203
        try:
4476.3.33 by Andrew Bennetts
Revert some accidental s/17/18/ in remote.py.
1204
            if self._client._medium._is_remote_before((1, 17)):
4419.2.9 by Andrew Bennetts
Add per_repository_reference test for get_rev_id_for_revno, fix the bugs it revealed.
1205
                return self._get_rev_id_for_revno_vfs(revno, known_pair)
4419.2.5 by Andrew Bennetts
Add Repository.get_rev_id_for_revno, and use it both as the _ensure_real fallback and as the server-side implementation.
1206
            response = self._call(
1207
                'Repository.get_rev_id_for_revno', path, revno, known_pair)
1208
        except errors.UnknownSmartMethod:
4476.3.33 by Andrew Bennetts
Revert some accidental s/17/18/ in remote.py.
1209
            self._client._medium._remember_remote_is_before((1, 17))
4419.2.9 by Andrew Bennetts
Add per_repository_reference test for get_rev_id_for_revno, fix the bugs it revealed.
1210
            return self._get_rev_id_for_revno_vfs(revno, known_pair)
4419.2.5 by Andrew Bennetts
Add Repository.get_rev_id_for_revno, and use it both as the _ensure_real fallback and as the server-side implementation.
1211
        if response[0] == 'ok':
1212
            return True, response[1]
1213
        elif response[0] == 'history-incomplete':
4419.2.8 by Andrew Bennetts
Add unit test for RemoteRepository.get_rev_id_for_revno using fallbacks if it gets a history-incomplete response.
1214
            known_pair = response[1:3]
1215
            for fallback in self._fallback_repositories:
1216
                found, result = fallback.get_rev_id_for_revno(revno, known_pair)
1217
                if found:
1218
                    return True, result
1219
                else:
1220
                    known_pair = result
1221
            # Not found in any fallbacks
1222
            return False, known_pair
4419.2.5 by Andrew Bennetts
Add Repository.get_rev_id_for_revno, and use it both as the _ensure_real fallback and as the server-side implementation.
1223
        else:
1224
            raise errors.UnexpectedSmartServerResponse(response)
1225
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
1226
    def _ensure_real(self):
1227
        """Ensure that there is a _real_repository set.
1228
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
1229
        Used before calls to self._real_repository.
4145.1.1 by Robert Collins
Explicitly prevent fetching while the target repository is in a write group.
1230
1231
        Note that _ensure_real causes many roundtrips to the server which are
1232
        not desirable, and prevents the use of smart one-roundtrip RPC's to
1233
        perform complex operations (such as accessing parent data, streaming
1234
        revisions etc). Adding calls to _ensure_real should only be done when
1235
        bringing up new functionality, adding fallbacks for smart methods that
1236
        require a fallback path, and never to replace an existing smart method
1237
        invocation. If in doubt chat to the bzr network team.
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
1238
        """
3692.1.3 by Andrew Bennetts
Delete some cruft (like the _ensure_real call in RemoteBranch.lock_write), improve some comments, and wrap some long lines.
1239
        if self._real_repository is None:
4509.2.2 by Martin Pool
Use only -Dhpssvfs for tracebacks, and document -Dhpssdetail
1240
            if 'hpssvfs' in debug.debug_flags:
4347.1.1 by Robert Collins
Show a traceback when VFS operations are started on a smart server hosted repository.
1241
                import traceback
1242
                warning('VFS Repository access triggered\n%s',
1243
                    ''.join(traceback.format_stack()))
4307.2.4 by Robert Collins
Enable caching of negative revision lookups in RemoteRepository write locks when no _real_repository has been constructed.
1244
            self._unstacked_provider.missing_keys.clear()
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
1245
            self.bzrdir._ensure_real()
3692.1.3 by Andrew Bennetts
Delete some cruft (like the _ensure_real call in RemoteBranch.lock_write), improve some comments, and wrap some long lines.
1246
            self._set_real_repository(
1247
                self.bzrdir._real_bzrdir.open_repository())
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
1248
3533.3.1 by Andrew Bennetts
Remove duplication of error translation in bzrlib/remote.py.
1249
    def _translate_error(self, err, **context):
1250
        self.bzrdir._translate_error(err, repository=self, **context)
1251
2988.1.2 by Robert Collins
New Repository API find_text_key_references for use by reconcile and check.
1252
    def find_text_key_references(self):
1253
        """Find the text key references within the repository.
1254
1255
        :return: A dictionary mapping text keys ((fileid, revision_id) tuples)
1256
            to whether they were referred to by the inventory of the
1257
            revision_id that they contain. The inventory texts from all present
1258
            revision ids are assessed to generate this report.
1259
        """
1260
        self._ensure_real()
1261
        return self._real_repository.find_text_key_references()
1262
2988.1.3 by Robert Collins
Add a new repositoy method _generate_text_key_index for use by reconcile/check.
1263
    def _generate_text_key_index(self):
1264
        """Generate a new text key index for the repository.
1265
1266
        This is an expensive function that will take considerable time to run.
1267
1268
        :return: A dict mapping (file_id, revision_id) tuples to a list of
1269
            parents, also (file_id, revision_id) tuples.
1270
        """
1271
        self._ensure_real()
1272
        return self._real_repository._generate_text_key_index()
1273
3287.6.4 by Robert Collins
Fix up deprecation warnings for get_revision_graph.
1274
    def _get_revision_graph(self, revision_id):
1275
        """Private method for using with old (< 1.2) servers to fallback."""
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
1276
        if revision_id is None:
1277
            revision_id = ''
5712.3.13 by Jelmer Vernooij
Add Prober.known_formats().
1278
        elif _mod_revision.is_null(revision_id):
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
1279
            return {}
1280
1281
        path = self.bzrdir._path_for_remote_call(self._client)
3786.2.3 by Andrew Bennetts
Remove duplicated 'call & translate errors' code in bzrlib.remote.
1282
        response = self._call_expecting_body(
1283
            'Repository.get_revision_graph', path, revision_id)
3245.4.58 by Andrew Bennetts
Unpack call_expecting_body's return value into variables, to avoid lots of ugly subscripting.
1284
        response_tuple, response_handler = response
1285
        if response_tuple[0] != 'ok':
1286
            raise errors.UnexpectedSmartServerResponse(response_tuple)
1287
        coded = response_handler.read_body_bytes()
3245.4.24 by Andrew Bennetts
Consistently raise errors from the server as ErrorFromSmartServer exceptions.
1288
        if coded == '':
1289
            # no revisions in this repository!
1290
            return {}
1291
        lines = coded.split('\n')
1292
        revision_graph = {}
1293
        for line in lines:
1294
            d = tuple(line.split())
1295
            revision_graph[d[0]] = d[1:]
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1296
3245.4.24 by Andrew Bennetts
Consistently raise errors from the server as ErrorFromSmartServer exceptions.
1297
        return revision_graph
2018.5.67 by Wouter van Heyst
Implement RemoteRepository.get_revision_graph (Wouter van Heyst, Robert Collins)
1298
4022.1.1 by Robert Collins
Refactoring of fetch to have a sender and sink component enabling splitting the logic over a network stream. (Robert Collins, Andrew Bennetts)
1299
    def _get_sink(self):
1300
        """See Repository._get_sink()."""
4022.1.6 by Robert Collins
Cherrypick and polish the RemoteSink for streaming push.
1301
        return RemoteStreamSink(self)
4022.1.1 by Robert Collins
Refactoring of fetch to have a sender and sink component enabling splitting the logic over a network stream. (Robert Collins, Andrew Bennetts)
1302
4060.1.3 by Robert Collins
Implement the separate source component for fetch - repository.StreamSource.
1303
    def _get_source(self, to_format):
1304
        """Return a source for streaming from this repository."""
1305
        return RemoteStreamSource(self, to_format)
1306
4307.2.3 by Robert Collins
Change RemoteRepository.has_revision to use get_parent_map to leverage the caching.
1307
    @needs_read_lock
5815.5.8 by Jelmer Vernooij
Use traditional (fileid, revision) entries in file graph.
1308
    def get_file_graph(self):
1309
        return graph.Graph(self.texts)
5815.5.3 by Jelmer Vernooij
Add basic test for per file graph.
1310
1311
    @needs_read_lock
2018.5.40 by Robert Collins
Implement a remote Repository.has_revision method.
1312
    def has_revision(self, revision_id):
4307.2.3 by Robert Collins
Change RemoteRepository.has_revision to use get_parent_map to leverage the caching.
1313
        """True if this repository has a copy of the revision."""
1314
        # Copy of bzrlib.repository.Repository.has_revision
1315
        return revision_id in self.has_revisions((revision_id,))
2018.5.40 by Robert Collins
Implement a remote Repository.has_revision method.
1316
4307.2.3 by Robert Collins
Change RemoteRepository.has_revision to use get_parent_map to leverage the caching.
1317
    @needs_read_lock
3172.3.1 by Robert Collins
Repository has a new method ``has_revisions`` which signals the presence
1318
    def has_revisions(self, revision_ids):
4307.2.3 by Robert Collins
Change RemoteRepository.has_revision to use get_parent_map to leverage the caching.
1319
        """Probe to find out the presence of multiple revisions.
1320
1321
        :param revision_ids: An iterable of revision_ids.
1322
        :return: A set of the revision_ids that were present.
1323
        """
1324
        # Copy of bzrlib.repository.Repository.has_revisions
1325
        parent_map = self.get_parent_map(revision_ids)
1326
        result = set(parent_map)
1327
        if _mod_revision.NULL_REVISION in revision_ids:
1328
            result.add(_mod_revision.NULL_REVISION)
3172.3.1 by Robert Collins
Repository has a new method ``has_revisions`` which signals the presence
1329
        return result
1330
4509.3.37 by Martin Pool
Remove RepositoryBase; make _has_same_location private
1331
    def _has_same_fallbacks(self, other_repo):
1332
        """Returns true if the repositories have the same fallbacks."""
1333
        # XXX: copied from Repository; it should be unified into a base class
5243.1.2 by Martin
Point launchpad links in comments at production server rather than edge
1334
        # <https://bugs.launchpad.net/bzr/+bug/401622>
4509.3.37 by Martin Pool
Remove RepositoryBase; make _has_same_location private
1335
        my_fb = self._fallback_repositories
1336
        other_fb = other_repo._fallback_repositories
1337
        if len(my_fb) != len(other_fb):
1338
            return False
1339
        for f, g in zip(my_fb, other_fb):
1340
            if not f.has_same_location(g):
1341
                return False
1342
        return True
1343
2617.6.9 by Robert Collins
Merge bzr.dev.
1344
    def has_same_location(self, other):
4509.3.23 by Martin Pool
Comment on has_same_location variation
1345
        # TODO: Move to RepositoryBase and unify with the regular Repository
1346
        # one; unfortunately the tests rely on slightly different behaviour at
1347
        # present -- mbp 20090710
4088.3.1 by Benjamin Peterson
compare types with 'is' not ==
1348
        return (self.__class__ is other.__class__ and
2592.3.162 by Robert Collins
Remove some arbitrary differences from bzr.dev.
1349
                self.bzrdir.transport.base == other.bzrdir.transport.base)
3835.1.1 by Aaron Bentley
Stack get_parent_map on fallback repos
1350
2490.2.21 by Aaron Bentley
Rename graph to deprecated_graph
1351
    def get_graph(self, other_repository=None):
1352
        """Return the graph for this repository format"""
3835.1.17 by Aaron Bentley
Fix stacking bug
1353
        parents_provider = self._make_parents_provider(other_repository)
3441.5.24 by Andrew Bennetts
Remove RemoteGraph experiment.
1354
        return graph.Graph(parents_provider)
2490.2.5 by Aaron Bentley
Use GraphWalker.unique_ancestor to determine merge base
1355
4913.4.2 by Jelmer Vernooij
Add Repository.get_known_graph_ancestry.
1356
    @needs_read_lock
1357
    def get_known_graph_ancestry(self, revision_ids):
1358
        """Return the known graph for a set of revision ids and their ancestors.
1359
        """
1360
        st = static_tuple.StaticTuple
1361
        revision_keys = [st(r_id).intern() for r_id in revision_ids]
1362
        known_graph = self.revisions.get_known_graph_ancestry(revision_keys)
1363
        return graph.GraphThunkIdsToKeys(known_graph)
1364
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1365
    def gather_stats(self, revid=None, committers=None):
2018.5.62 by Robert Collins
Stub out RemoteRepository.gather_stats while its implemented in parallel.
1366
        """See Repository.gather_stats()."""
2018.10.3 by v.ladeuil+lp at free
more tests for gather_stats
1367
        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.
1368
        # revid can be None to indicate no revisions, not just NULL_REVISION
5712.3.13 by Jelmer Vernooij
Add Prober.known_formats().
1369
        if revid is None or _mod_revision.is_null(revid):
2018.10.3 by v.ladeuil+lp at free
more tests for gather_stats
1370
            fmt_revid = ''
1371
        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.
1372
            fmt_revid = revid
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1373
        if committers is None or not committers:
2018.10.3 by v.ladeuil+lp at free
more tests for gather_stats
1374
            fmt_committers = 'no'
1375
        else:
1376
            fmt_committers = 'yes'
3786.2.3 by Andrew Bennetts
Remove duplicated 'call & translate errors' code in bzrlib.remote.
1377
        response_tuple, response_handler = self._call_expecting_body(
2018.5.153 by Andrew Bennetts
Rename call2 to call_expecting_body, and other small changes prompted by review.
1378
            'Repository.gather_stats', path, fmt_revid, fmt_committers)
3245.4.58 by Andrew Bennetts
Unpack call_expecting_body's return value into variables, to avoid lots of ugly subscripting.
1379
        if response_tuple[0] != 'ok':
1380
            raise errors.UnexpectedSmartServerResponse(response_tuple)
2018.10.3 by v.ladeuil+lp at free
more tests for gather_stats
1381
3245.4.58 by Andrew Bennetts
Unpack call_expecting_body's return value into variables, to avoid lots of ugly subscripting.
1382
        body = response_handler.read_body_bytes()
2018.10.3 by v.ladeuil+lp at free
more tests for gather_stats
1383
        result = {}
1384
        for line in body.split('\n'):
1385
            if not line:
1386
                continue
1387
            key, val_text = line.split(':')
1388
            if key in ('revisions', 'size', 'committers'):
1389
                result[key] = int(val_text)
1390
            elif key in ('firstrev', 'latestrev'):
1391
                values = val_text.split(' ')[1:]
1392
                result[key] = (float(values[0]), long(values[1]))
1393
1394
        return result
2018.5.62 by Robert Collins
Stub out RemoteRepository.gather_stats while its implemented in parallel.
1395
3140.1.2 by Aaron Bentley
Add ability to find branches inside repositories
1396
    def find_branches(self, using=False):
1397
        """See Repository.find_branches()."""
1398
        # should be an API call to the server.
1399
        self._ensure_real()
1400
        return self._real_repository.find_branches(using=using)
1401
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
1402
    def get_physical_lock_status(self):
1403
        """See Repository.get_physical_lock_status()."""
6280.6.1 by Jelmer Vernooij
Implement remote side of {Branch,Repository}.get_physical_lock_status.
1404
        path = self.bzrdir._path_for_remote_call(self._client)
1405
        try:
1406
            response = self._call('Repository.get_physical_lock_status', path)
1407
        except errors.UnknownSmartMethod:
1408
            self._ensure_real()
1409
            return self._real_repository.get_physical_lock_status()
1410
        if response[0] not in ('yes', 'no'):
1411
            raise errors.UnexpectedSmartServerResponse(response)
6280.6.2 by Jelmer Vernooij
Add HPSS calls Repository.get_physical_lock_status and Branch.get_physical_lock_status.
1412
        return (response[0] == 'yes')
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
1413
2617.6.1 by Robert Collins
* New method on Repository - ``start_write_group``, ``end_write_group``
1414
    def is_in_write_group(self):
1415
        """Return True if there is an open write group.
1416
1417
        write groups are only applicable locally for the smart server..
1418
        """
6280.7.3 by Jelmer Vernooij
Fix RemoteRepository.is_in_write_group.
1419
        if self._write_group_tokens is not None:
1420
            return True
2617.6.1 by Robert Collins
* New method on Repository - ``start_write_group``, ``end_write_group``
1421
        if self._real_repository:
1422
            return self._real_repository.is_in_write_group()
1423
1424
    def is_locked(self):
1425
        return self._lock_count >= 1
1426
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
1427
    def is_shared(self):
1428
        """See Repository.is_shared()."""
1429
        path = self.bzrdir._path_for_remote_call(self._client)
3786.2.3 by Andrew Bennetts
Remove duplicated 'call & translate errors' code in bzrlib.remote.
1430
        response = self._call('Repository.is_shared', path)
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
1431
        if response[0] not in ('yes', 'no'):
1432
            raise SmartProtocolError('unexpected response code %s' % (response,))
2018.5.57 by Robert Collins
Implement RemoteRepository.is_shared (Robert Collins, Vincent Ladeuil).
1433
        return response[0] == 'yes'
1434
2904.1.1 by Robert Collins
* New method ``bzrlib.repository.Repository.is_write_locked`` useful for
1435
    def is_write_locked(self):
1436
        return self._lock_mode == 'w'
1437
5675.2.2 by Jelmer Vernooij
Revert unnecessary bzrlib.remote changes.
1438
    def _warn_if_deprecated(self, branch=None):
1439
        # If we have a real repository, the check will be done there, if we
1440
        # don't the check will be done remotely.
1441
        pass
1442
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
1443
    def lock_read(self):
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
1444
        """Lock the repository for read operations.
1445
5200.3.6 by Robert Collins
Make all lock methods return Result objects, rather than lock_read returning self, as per John's review.
1446
        :return: A bzrlib.lock.LogicalLockResult.
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
1447
        """
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
1448
        # wrong eventually - want a local lock cache context
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
1449
        if not self._lock_mode:
4731.1.2 by Andrew Bennetts
Refactor to reduce duplication.
1450
            self._note_lock('r')
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
1451
            self._lock_mode = 'r'
1452
            self._lock_count = 1
4190.1.1 by Robert Collins
Negatively cache misses during read-locks in RemoteRepository.
1453
            self._unstacked_provider.enable_cache(cache_misses=True)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1454
            if self._real_repository is not None:
1455
                self._real_repository.lock_read()
4379.2.1 by John Arbash Meinel
Change the fallback repository code to only lock/unlock on transition.
1456
            for repo in self._fallback_repositories:
1457
                repo.lock_read()
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
1458
        else:
1459
            self._lock_count += 1
5200.3.6 by Robert Collins
Make all lock methods return Result objects, rather than lock_read returning self, as per John's review.
1460
        return lock.LogicalLockResult(self.unlock)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1461
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1462
    def _remote_lock_write(self, token):
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1463
        path = self.bzrdir._path_for_remote_call(self._client)
1464
        if token is None:
1465
            token = ''
3786.2.3 by Andrew Bennetts
Remove duplicated 'call & translate errors' code in bzrlib.remote.
1466
        err_context = {'token': token}
1467
        response = self._call('Repository.lock_write', path, token,
1468
                              **err_context)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1469
        if response[0] == 'ok':
1470
            ok, token = response
1471
            return token
1472
        else:
2555.1.1 by Martin Pool
Remove use of 'assert False' to raise an exception unconditionally
1473
            raise errors.UnexpectedSmartServerResponse(response)
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
1474
3692.1.1 by Andrew Bennetts
Make RemoteBranch.lock_write lock the repository too.
1475
    def lock_write(self, token=None, _skip_rpc=False):
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
1476
        if not self._lock_mode:
4731.1.2 by Andrew Bennetts
Refactor to reduce duplication.
1477
            self._note_lock('w')
3692.1.1 by Andrew Bennetts
Make RemoteBranch.lock_write lock the repository too.
1478
            if _skip_rpc:
1479
                if self._lock_token is not None:
1480
                    if token != self._lock_token:
3695.1.1 by Andrew Bennetts
Remove some unused imports and fix a couple of trivially broken raise statements.
1481
                        raise errors.TokenMismatch(token, self._lock_token)
3692.1.1 by Andrew Bennetts
Make RemoteBranch.lock_write lock the repository too.
1482
                self._lock_token = token
1483
            else:
1484
                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.
1485
            # if self._lock_token is None, then this is something like packs or
1486
            # svn where we don't get to lock the repo, or a weave style repository
1487
            # where we cannot lock it over the wire and attempts to do so will
1488
            # fail.
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1489
            if self._real_repository is not None:
1490
                self._real_repository.lock_write(token=self._lock_token)
1491
            if token is not None:
1492
                self._leave_lock = True
1493
            else:
1494
                self._leave_lock = False
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
1495
            self._lock_mode = 'w'
1496
            self._lock_count = 1
4307.2.4 by Robert Collins
Enable caching of negative revision lookups in RemoteRepository write locks when no _real_repository has been constructed.
1497
            cache_misses = self._real_repository is None
1498
            self._unstacked_provider.enable_cache(cache_misses=cache_misses)
4379.2.1 by John Arbash Meinel
Change the fallback repository code to only lock/unlock on transition.
1499
            for repo in self._fallback_repositories:
1500
                # Writes don't affect fallback repos
1501
                repo.lock_read()
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
1502
        elif self._lock_mode == 'r':
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1503
            raise errors.ReadOnlyError(self)
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
1504
        else:
1505
            self._lock_count += 1
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
1506
        return RepositoryWriteLockResult(self.unlock, self._lock_token or None)
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
1507
1508
    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.
1509
        if not self._lock_token:
1510
            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
1511
        self._leave_lock = True
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
1512
1513
    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.
1514
        if not self._lock_token:
3015.2.15 by Robert Collins
Review feedback.
1515
            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
1516
        self._leave_lock = False
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
1517
1518
    def _set_real_repository(self, repository):
1519
        """Set the _real_repository for this repository.
1520
1521
        :param repository: The repository to fallback to for non-hpss
1522
            implemented operations.
1523
        """
4053.1.5 by Robert Collins
Review feedback on RemoteRepository._set_real_revision.
1524
        if self._real_repository is not None:
1525
            # Replacing an already set real repository.
1526
            # We cannot do this [currently] if the repository is locked -
1527
            # synchronised state might be lost.
1528
            if self.is_locked():
1529
                raise AssertionError('_real_repository is already set')
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
1530
        if isinstance(repository, RemoteRepository):
1531
            raise AssertionError()
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
1532
        self._real_repository = repository
4226.2.5 by Robert Collins
Fix handling of fallback repositories some more.
1533
        # three code paths happen here:
1534
        # 1) old servers, RemoteBranch.open() calls _ensure_real before setting
1535
        # up stacking. In this case self._fallback_repositories is [], and the
1536
        # real repo is already setup. Preserve the real repo and
1537
        # RemoteRepository.add_fallback_repository will avoid adding
1538
        # duplicates.
1539
        # 2) new servers, RemoteBranch.open() sets up stacking, and when
1540
        # ensure_real is triggered from a branch, the real repository to
1541
        # set already has a matching list with separate instances, but
1542
        # as they are also RemoteRepositories we don't worry about making the
1543
        # lists be identical.
1544
        # 3) new servers, RemoteRepository.ensure_real is triggered before
1545
        # RemoteBranch.ensure real, in this case we get a repo with no fallbacks
1546
        # and need to populate it.
1547
        if (self._fallback_repositories and
1548
            len(self._real_repository._fallback_repositories) !=
4226.2.2 by Robert Collins
Fix setting config options to support unicode values and don't attempt to reset repositories _fallback_repositories as the simple approach fails to work.
1549
            len(self._fallback_repositories)):
1550
            if len(self._real_repository._fallback_repositories):
1551
                raise AssertionError(
1552
                    "cannot cleanly remove existing _fallback_repositories")
3691.2.12 by Martin Pool
Add test for coping without Branch.get_stacked_on_url
1553
        for fb in self._fallback_repositories:
1554
            self._real_repository.add_fallback_repository(fb)
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
1555
        if self._lock_mode == 'w':
1556
            # if we are already locked, the real repository must be able to
1557
            # acquire the lock with our token.
1558
            self._real_repository.lock_write(self._lock_token)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1559
        elif self._lock_mode == 'r':
1560
            self._real_repository.lock_read()
6280.7.5 by Jelmer Vernooij
Bunch of test fixes.
1561
        if self._write_group_tokens is not None:
1562
            # if we are already in a write group, resume it
1563
            self._real_repository.resume_write_group(self._write_group_tokens)
1564
            self._write_group_tokens = None
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
1565
2617.6.1 by Robert Collins
* New method on Repository - ``start_write_group``, ``end_write_group``
1566
    def start_write_group(self):
1567
        """Start a write group on the decorated repository.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1568
4031.3.3 by Matt Nordhoff
Review tweaks from Ben Finney
1569
        Smart methods perform operations in a single step so this API
2617.6.6 by Robert Collins
Some review feedback.
1570
        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``
1571
        for older plugins that don't use e.g. the CommitBuilder
1572
        facility.
1573
        """
6280.7.5 by Jelmer Vernooij
Bunch of test fixes.
1574
        if self._real_repository:
1575
            self._ensure_real()
1576
            return self._real_repository.start_write_group()
1577
        if not self.is_write_locked():
1578
            raise errors.NotWriteLocked(self)
1579
        if self._write_group_tokens is not None:
1580
            raise errors.BzrError('already in a write group')
6280.7.1 by Jelmer Vernooij
Implement RemoteRepository side of write group HPSS methods.
1581
        path = self.bzrdir._path_for_remote_call(self._client)
1582
        try:
6280.7.2 by Jelmer Vernooij
Add HPSS calls ``Repository.start_write_group``, ``Repository.abort_write_group`` and ``Repository.commit_write_group``.
1583
            response = self._call('Repository.start_write_group', path,
1584
                self._lock_token)
6280.7.8 by Jelmer Vernooij
make sure start_write_group falls back to real_repository if write groups aren't suspendable.
1585
        except (errors.UnknownSmartMethod, errors.UnsuspendableWriteGroup):
6280.7.1 by Jelmer Vernooij
Implement RemoteRepository side of write group HPSS methods.
1586
            self._ensure_real()
1587
            return self._real_repository.start_write_group()
6280.7.2 by Jelmer Vernooij
Add HPSS calls ``Repository.start_write_group``, ``Repository.abort_write_group`` and ``Repository.commit_write_group``.
1588
        if response[0] != 'ok':
6280.7.1 by Jelmer Vernooij
Implement RemoteRepository side of write group HPSS methods.
1589
            raise errors.UnexpectedSmartServerResponse(response)
6280.7.6 by Jelmer Vernooij
Fix remaining tests.
1590
        self._write_group_tokens = response[1]
2617.6.1 by Robert Collins
* New method on Repository - ``start_write_group``, ``end_write_group``
1591
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1592
    def _unlock(self, token):
1593
        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.
1594
        if not token:
1595
            # with no token the remote repository is not persistently locked.
1596
            return
3786.2.3 by Andrew Bennetts
Remove duplicated 'call & translate errors' code in bzrlib.remote.
1597
        err_context = {'token': token}
1598
        response = self._call('Repository.unlock', path, token,
1599
                              **err_context)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1600
        if response == ('ok',):
1601
            return
1602
        else:
2555.1.1 by Martin Pool
Remove use of 'assert False' to raise an exception unconditionally
1603
            raise errors.UnexpectedSmartServerResponse(response)
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1604
4634.85.9 by Andrew Bennetts
Add some experimental decorators: @only_raises(..) and @cleanup_method.
1605
    @only_raises(errors.LockNotHeld, errors.LockBroken)
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
1606
    def unlock(self):
4032.3.2 by Robert Collins
Create and use a RPC call to create branches on bzr servers rather than using VFS calls.
1607
        if not self._lock_count:
4509.3.25 by Martin Pool
Add an option for unlock errors to be non-fatal
1608
            return lock.cant_unlock_not_held(self)
2018.5.75 by Andrew Bennetts
Add Repository.{dont_,}leave_lock_in_place.
1609
        self._lock_count -= 1
2592.3.244 by Martin Pool
unlock while in a write group now aborts the write group, unlocks, and errors.
1610
        if self._lock_count > 0:
1611
            return
3835.1.8 by Aaron Bentley
Make UnstackedParentsProvider manage the cache
1612
        self._unstacked_provider.disable_cache()
2592.3.244 by Martin Pool
unlock while in a write group now aborts the write group, unlocks, and errors.
1613
        old_mode = self._lock_mode
1614
        self._lock_mode = None
1615
        try:
1616
            # The real repository is responsible at present for raising an
1617
            # exception if it's in an unfinished write group.  However, it
1618
            # normally will *not* actually remove the lock from disk - that's
1619
            # done by the server on receiving the Repository.unlock call.
1620
            # 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
1621
            if self._real_repository is not None:
1622
                self._real_repository.unlock()
6280.7.6 by Jelmer Vernooij
Fix remaining tests.
1623
            elif self._write_group_tokens is not None:
1624
                self.abort_write_group()
2592.3.244 by Martin Pool
unlock while in a write group now aborts the write group, unlocks, and errors.
1625
        finally:
1626
            # The rpc-level lock should be released even if there was a
1627
            # problem releasing the vfs-based lock.
1628
            if old_mode == 'w':
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
1629
                # Only write-locked repositories need to make a remote method
4031.3.1 by Frank Aspell
Fixing various typos
1630
                # call to perform the unlock.
2592.3.244 by Martin Pool
unlock while in a write group now aborts the write group, unlocks, and errors.
1631
                old_token = self._lock_token
1632
                self._lock_token = None
1633
                if not self._leave_lock:
1634
                    self._unlock(old_token)
4379.2.1 by John Arbash Meinel
Change the fallback repository code to only lock/unlock on transition.
1635
        # Fallbacks are always 'lock_read()' so we don't pay attention to
1636
        # self._leave_lock
1637
        for repo in self._fallback_repositories:
1638
            repo.unlock()
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
1639
1640
    def break_lock(self):
2018.5.78 by Andrew Bennetts
Implement RemoteRepository.lock_write/unlock to expect and send tokens over the
1641
        # should hand off to the network
6280.4.5 by Jelmer Vernooij
Fix tests.
1642
        path = self.bzrdir._path_for_remote_call(self._client)
6280.4.1 by Jelmer Vernooij
Add remote side of Repository.break_lock.
1643
        try:
6280.4.5 by Jelmer Vernooij
Fix tests.
1644
            response = self._call("Repository.break_lock", path)
6280.4.1 by Jelmer Vernooij
Add remote side of Repository.break_lock.
1645
        except errors.UnknownSmartMethod:
1646
            self._ensure_real()
1647
            return self._real_repository.break_lock()
1648
        if response != ('ok',):
1649
            raise errors.UnexpectedSmartServerResponse(response)
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
1650
2018.18.8 by Ian Clatworthy
Tarball proxy code & tests
1651
    def _get_tarball(self, compression):
2814.10.2 by Andrew Bennetts
Make the fallback a little tidier.
1652
        """Return a TemporaryFile containing a repository tarball.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1653
2814.10.2 by Andrew Bennetts
Make the fallback a little tidier.
1654
        Returns None if the server does not support sending tarballs.
1655
        """
2018.18.25 by Martin Pool
Repository.tarball fixes for python2.4
1656
        import tempfile
2018.18.8 by Ian Clatworthy
Tarball proxy code & tests
1657
        path = self.bzrdir._path_for_remote_call(self._client)
3297.3.3 by Andrew Bennetts
SmartClientRequestProtocol*.read_response_tuple can now raise UnknownSmartMethod. Callers no longer need to do their own ad hoc unknown smart method error detection.
1658
        try:
3786.2.3 by Andrew Bennetts
Remove duplicated 'call & translate errors' code in bzrlib.remote.
1659
            response, protocol = self._call_expecting_body(
3297.3.3 by Andrew Bennetts
SmartClientRequestProtocol*.read_response_tuple can now raise UnknownSmartMethod. Callers no longer need to do their own ad hoc unknown smart method error detection.
1660
                'Repository.tarball', path, compression)
1661
        except errors.UnknownSmartMethod:
1662
            protocol.cancel_read_body()
1663
            return None
2018.18.8 by Ian Clatworthy
Tarball proxy code & tests
1664
        if response[0] == 'ok':
1665
            # Extract the tarball and return it
2018.18.25 by Martin Pool
Repository.tarball fixes for python2.4
1666
            t = tempfile.NamedTemporaryFile()
1667
            # TODO: rpc layer should read directly into it...
1668
            t.write(protocol.read_body_bytes())
1669
            t.seek(0)
1670
            return t
2814.10.1 by Andrew Bennetts
Cope gracefully if the server doesn't support the Repository.tarball smart request.
1671
        raise errors.UnexpectedSmartServerResponse(response)
2018.18.8 by Ian Clatworthy
Tarball proxy code & tests
1672
6267.1.2 by Jelmer Vernooij
Avoid _ensure_real in some more calls.
1673
    @needs_read_lock
2440.1.1 by Martin Pool
Add new Repository.sprout,
1674
    def sprout(self, to_bzrdir, revision_id=None):
6267.1.2 by Jelmer Vernooij
Avoid _ensure_real in some more calls.
1675
        """Create a descendent repository for new development.
1676
1677
        Unlike clone, this does not copy the settings of the repository.
1678
        """
1679
        dest_repo = self._create_sprouting_repo(to_bzrdir, shared=False)
2535.3.17 by Andrew Bennetts
[broken] Closer to a working Repository.fetch_revisions smart request.
1680
        dest_repo.fetch(self, revision_id=revision_id)
1681
        return dest_repo
2440.1.1 by Martin Pool
Add new Repository.sprout,
1682
6267.1.2 by Jelmer Vernooij
Avoid _ensure_real in some more calls.
1683
    def _create_sprouting_repo(self, a_bzrdir, shared):
1684
        if not isinstance(a_bzrdir._format, self.bzrdir._format.__class__):
1685
            # use target default format.
1686
            dest_repo = a_bzrdir.create_repository()
1687
        else:
1688
            # Most control formats need the repository to be specifically
1689
            # created, but on some old all-in-one formats it's not needed
1690
            try:
1691
                dest_repo = self._format.initialize(a_bzrdir, shared=shared)
1692
            except errors.UninitializableFormat:
1693
                dest_repo = a_bzrdir.open_repository()
1694
        return dest_repo
1695
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1696
    ### These methods are just thin shims to the VFS object for now.
1697
6267.1.3 by Jelmer Vernooij
Fix tests.
1698
    @needs_read_lock
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1699
    def revision_tree(self, revision_id):
6267.1.3 by Jelmer Vernooij
Fix tests.
1700
        revision_id = _mod_revision.ensure_null(revision_id)
1701
        if revision_id == _mod_revision.NULL_REVISION:
1702
            return InventoryRevisionTree(self,
1703
                Inventory(root_id=None), _mod_revision.NULL_REVISION)
1704
        else:
1705
            return list(self.revision_trees([revision_id]))[0]
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1706
2520.4.113 by Aaron Bentley
Avoid peeking at Repository._serializer
1707
    def get_serializer_format(self):
6280.5.1 by Jelmer Vernooij
Add client side of Repository.get_serializer_format.
1708
        path = self.bzrdir._path_for_remote_call(self._client)
1709
        try:
1710
            response = self._call('VersionedFileRepository.get_serializer_format',
1711
                path)
1712
        except errors.UnknownSmartMethod:
1713
            self._ensure_real()
1714
            return self._real_repository.get_serializer_format()
1715
        if response[0] != 'ok':
1716
            raise errors.UnexpectedSmartServerResponse(response)
6280.5.2 by Jelmer Vernooij
New HPSS call VersionedFileRepository.get_serializer_format.
1717
        return response[1]
2520.4.113 by Aaron Bentley
Avoid peeking at Repository._serializer
1718
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1719
    def get_commit_builder(self, branch, parents, config, timestamp=None,
1720
                           timezone=None, committer=None, revprops=None,
5777.6.1 by Jelmer Vernooij
Add --lossy option to 'bzr commit'.
1721
                           revision_id=None, lossy=False):
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1722
        # FIXME: It ought to be possible to call this without immediately
1723
        # triggering _ensure_real.  For now it's the easiest thing to do.
1724
        self._ensure_real()
3692.1.3 by Andrew Bennetts
Delete some cruft (like the _ensure_real call in RemoteBranch.lock_write), improve some comments, and wrap some long lines.
1725
        real_repo = self._real_repository
1726
        builder = real_repo.get_commit_builder(branch, parents,
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1727
                config, timestamp=timestamp, timezone=timezone,
5777.6.1 by Jelmer Vernooij
Add --lossy option to 'bzr commit'.
1728
                committer=committer, revprops=revprops,
1729
                revision_id=revision_id, lossy=lossy)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1730
        return builder
1731
3221.12.1 by Robert Collins
Backport development1 format (stackable packs) to before-shallow-branches.
1732
    def add_fallback_repository(self, repository):
1733
        """Add a repository to use for looking up data not held locally.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1734
3221.12.1 by Robert Collins
Backport development1 format (stackable packs) to before-shallow-branches.
1735
        :param repository: A repository.
1736
        """
4118.1.1 by Andrew Bennetts
Fix performance regression (many small round-trips) when pushing to a remote pack, and tidy the tests.
1737
        if not self._format.supports_external_lookups:
1738
            raise errors.UnstackableRepositoryFormat(
1739
                self._format.network_name(), self.base)
3221.12.1 by Robert Collins
Backport development1 format (stackable packs) to before-shallow-branches.
1740
        # We need to accumulate additional repositories here, to pass them in
1741
        # on various RPC's.
4035.2.3 by Robert Collins
Fix trailing whitespace.
1742
        #
5609.54.1 by Gary Poster
repositories should not be locked in add_fallback_repository if they will not be used.
1743
        # Make the check before we lock: this raises an exception.
1744
        self._check_fallback_repository(repository)
4379.2.2 by John Arbash Meinel
Change the Repository.add_fallback_repository() contract slightly.
1745
        if self.is_locked():
1746
            # We will call fallback.unlock() when we transition to the unlocked
1747
            # state, so always add a lock here. If a caller passes us a locked
1748
            # repository, they are responsible for unlocking it later.
1749
            repository.lock_read()
3221.12.1 by Robert Collins
Backport development1 format (stackable packs) to before-shallow-branches.
1750
        self._fallback_repositories.append(repository)
4035.2.2 by Robert Collins
Minor tweaks to fix failing tests.
1751
        # If self._real_repository was parameterised already (e.g. because a
1752
        # _real_branch had its get_stacked_on_url method called), then the
1753
        # repository to be added may already be in the _real_repositories list.
4035.2.1 by Andrew Bennetts
Fix unnecessary get_parent_map calls after insert_stream during push.
1754
        if self._real_repository is not None:
5158.6.7 by Martin Pool
More conversions to using user_url
1755
            fallback_locations = [repo.user_url for repo in
4226.2.5 by Robert Collins
Fix handling of fallback repositories some more.
1756
                self._real_repository._fallback_repositories]
5158.6.7 by Martin Pool
More conversions to using user_url
1757
            if repository.user_url not in fallback_locations:
4035.2.2 by Robert Collins
Minor tweaks to fix failing tests.
1758
                self._real_repository.add_fallback_repository(repository)
3221.12.1 by Robert Collins
Backport development1 format (stackable packs) to before-shallow-branches.
1759
5158.4.1 by Andrew Bennetts
Don't allow RemoteRepository to stack on incompatible formats.
1760
    def _check_fallback_repository(self, repository):
1761
        """Check that this repository can fallback to repository safely.
1762
1763
        Raise an error if not.
1764
1765
        :param repository: A repository to fallback to.
1766
        """
1767
        return _mod_repository.InterRepository._assert_same_model(
1768
            self, repository)
1769
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1770
    def add_inventory(self, revid, inv, parents):
1771
        self._ensure_real()
1772
        return self._real_repository.add_inventory(revid, inv, parents)
1773
3879.2.2 by John Arbash Meinel
Rename add_inventory_delta to add_inventory_by_delta.
1774
    def add_inventory_by_delta(self, basis_revision_id, delta, new_revision_id,
5076.1.1 by Jelmer Vernooij
Allow additional arguments to RemoteRepository.add_inventory_by_delta().
1775
            parents, basis_inv=None, propagate_caches=False):
3775.2.1 by Robert Collins
Create bzrlib.repository.Repository.add_inventory_delta for adding inventories via deltas.
1776
        self._ensure_real()
3879.2.2 by John Arbash Meinel
Rename add_inventory_delta to add_inventory_by_delta.
1777
        return self._real_repository.add_inventory_by_delta(basis_revision_id,
5076.1.2 by Jelmer Vernooij
pass the keyword args as keyword args, per Rob's review.
1778
            delta, new_revision_id, parents, basis_inv=basis_inv,
1779
            propagate_caches=propagate_caches)
3775.2.1 by Robert Collins
Create bzrlib.repository.Repository.add_inventory_delta for adding inventories via deltas.
1780
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1781
    def add_revision(self, rev_id, rev, inv=None, config=None):
1782
        self._ensure_real()
1783
        return self._real_repository.add_revision(
1784
            rev_id, rev, inv=inv, config=config)
1785
1786
    @needs_read_lock
1787
    def get_inventory(self, revision_id):
6280.11.1 by Jelmer Vernooij
Implement RemoteRepository.get_inventory using RemoteRepository.iter_inventories
1788
        return list(self.iter_inventories([revision_id]))[0]
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1789
4476.3.86 by Andrew Bennetts
Fix bug in declaration of RemoteRepository.iter_inventories that was causing intermittent failures in test_iter_inventories_is_ordered.
1790
    def iter_inventories(self, revision_ids, ordering=None):
3169.2.1 by Robert Collins
New method ``iter_inventories`` on Repository for access to many
1791
        self._ensure_real()
4476.3.15 by Andrew Bennetts
Partially working fallback for pre-1.17 servers.
1792
        return self._real_repository.iter_inventories(revision_ids, ordering)
3169.2.1 by Robert Collins
New method ``iter_inventories`` on Repository for access to many
1793
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1794
    @needs_read_lock
1795
    def get_revision(self, revision_id):
6267.1.1 by Jelmer Vernooij
Avoid _ensure_real in a couple more places.
1796
        return self.get_revisions([revision_id])[0]
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1797
1798
    def get_transaction(self):
1799
        self._ensure_real()
1800
        return self._real_repository.get_transaction()
1801
1802
    @needs_read_lock
2018.5.138 by Robert Collins
Merge bzr.dev.
1803
    def clone(self, a_bzrdir, revision_id=None):
6267.1.2 by Jelmer Vernooij
Avoid _ensure_real in some more calls.
1804
        dest_repo = self._create_sprouting_repo(
6267.1.3 by Jelmer Vernooij
Fix tests.
1805
            a_bzrdir, shared=self.is_shared())
6267.1.2 by Jelmer Vernooij
Avoid _ensure_real in some more calls.
1806
        self.copy_content_into(dest_repo, revision_id)
1807
        return dest_repo
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1808
1809
    def make_working_trees(self):
3349.1.1 by Aaron Bentley
Enable setting and getting make_working_trees for all repositories
1810
        """See Repository.make_working_trees"""
6263.2.1 by Jelmer Vernooij
Add hpss call ``Repository.make_working_trees``
1811
        path = self.bzrdir._path_for_remote_call(self._client)
1812
        try:
1813
            response = self._call('Repository.make_working_trees', path)
1814
        except errors.UnknownSmartMethod:
1815
            self._ensure_real()
1816
            return self._real_repository.make_working_trees()
1817
        if response[0] not in ('yes', 'no'):
1818
            raise SmartProtocolError('unexpected response code %s' % (response,))
1819
        return response[0] == 'yes'
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1820
4145.1.2 by Robert Collins
Add a refresh_data method on Repository allowing cleaner handling of insertions into RemoteRepository objects with _real_repository instances.
1821
    def refresh_data(self):
5199.1.3 by Andrew Bennetts
Use Robert's text for the refresh_data docstring.
1822
        """Re-read any data needed to synchronise with disk.
4145.1.2 by Robert Collins
Add a refresh_data method on Repository allowing cleaner handling of insertions into RemoteRepository objects with _real_repository instances.
1823
1824
        This method is intended to be called after another repository instance
1825
        (such as one used by a smart server) has inserted data into the
5199.1.3 by Andrew Bennetts
Use Robert's text for the refresh_data docstring.
1826
        repository. On all repositories this will work outside of write groups.
1827
        Some repository formats (pack and newer for bzrlib native formats)
1828
        support refresh_data inside write groups. If called inside a write
1829
        group on a repository that does not support refreshing in a write group
1830
        IsInWriteGroupError will be raised.
4145.1.2 by Robert Collins
Add a refresh_data method on Repository allowing cleaner handling of insertions into RemoteRepository objects with _real_repository instances.
1831
        """
1832
        if self._real_repository is not None:
1833
            self._real_repository.refresh_data()
1834
3184.1.9 by Robert Collins
* ``Repository.get_data_stream`` is now deprecated in favour of
1835
    def revision_ids_to_search_result(self, result_set):
1836
        """Convert a set of revision ids to a graph SearchResult."""
1837
        result_parents = set()
1838
        for parents in self.get_graph().get_parent_map(
1839
            result_set).itervalues():
1840
            result_parents.update(parents)
1841
        included_keys = result_set.intersection(result_parents)
1842
        start_keys = result_set.difference(included_keys)
1843
        exclude_keys = result_parents.difference(result_set)
1844
        result = graph.SearchResult(start_keys, exclude_keys,
1845
            len(result_set), result_set)
1846
        return result
1847
1848
    @needs_read_lock
5539.2.10 by Andrew Bennetts
s/NotInOtherForRev/NotInOtherForRevs/, and allow passing multiple revision_ids to search_missing_revision_ids.
1849
    def search_missing_revision_ids(self, other,
1850
            revision_id=symbol_versioning.DEPRECATED_PARAMETER,
5852.1.6 by Jelmer Vernooij
Add extra test for Repository.search_missing_revision_ids.
1851
            find_ghosts=True, revision_ids=None, if_present_ids=None,
1852
            limit=None):
3184.1.9 by Robert Collins
* ``Repository.get_data_stream`` is now deprecated in favour of
1853
        """Return the revision ids that other has that this does not.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1854
3184.1.9 by Robert Collins
* ``Repository.get_data_stream`` is now deprecated in favour of
1855
        These are returned in topological order.
1856
1857
        revision_id: only return revision ids included by revision_id.
1858
        """
5539.2.10 by Andrew Bennetts
s/NotInOtherForRev/NotInOtherForRevs/, and allow passing multiple revision_ids to search_missing_revision_ids.
1859
        if symbol_versioning.deprecated_passed(revision_id):
1860
            symbol_versioning.warn(
1861
                'search_missing_revision_ids(revision_id=...) was '
5536.3.3 by Andrew Bennetts
Merge lp:bzr.
1862
                'deprecated in 2.4.  Use revision_ids=[...] instead.',
5539.2.10 by Andrew Bennetts
s/NotInOtherForRev/NotInOtherForRevs/, and allow passing multiple revision_ids to search_missing_revision_ids.
1863
                DeprecationWarning, stacklevel=2)
1864
            if revision_ids is not None:
1865
                raise AssertionError(
1866
                    'revision_ids is mutually exclusive with revision_id')
1867
            if revision_id is not None:
1868
                revision_ids = [revision_id]
5712.3.13 by Jelmer Vernooij
Add Prober.known_formats().
1869
        inter_repo = _mod_repository.InterRepository.get(other, self)
5539.2.10 by Andrew Bennetts
s/NotInOtherForRev/NotInOtherForRevs/, and allow passing multiple revision_ids to search_missing_revision_ids.
1870
        return inter_repo.search_missing_revision_ids(
5535.3.32 by Andrew Bennetts
Implement if_present_ids behaviour in all implementations and code paths of searching_missing_revision_ids
1871
            find_ghosts=find_ghosts, revision_ids=revision_ids,
5852.1.6 by Jelmer Vernooij
Add extra test for Repository.search_missing_revision_ids.
1872
            if_present_ids=if_present_ids, limit=limit)
3184.1.9 by Robert Collins
* ``Repository.get_data_stream`` is now deprecated in favour of
1873
5670.1.1 by Jelmer Vernooij
Remove all methods and arguments that were deprecated before bzr 2.0.0.
1874
    def fetch(self, source, revision_id=None, find_ghosts=False,
4070.9.2 by Andrew Bennetts
Rough prototype of allowing a SearchResult to be passed to fetch, and using that to improve network conversations.
1875
            fetch_spec=None):
4145.1.1 by Robert Collins
Explicitly prevent fetching while the target repository is in a write group.
1876
        # No base implementation to use as RemoteRepository is not a subclass
1877
        # of Repository; so this is a copy of Repository.fetch().
4070.9.2 by Andrew Bennetts
Rough prototype of allowing a SearchResult to be passed to fetch, and using that to improve network conversations.
1878
        if fetch_spec is not None and revision_id is not None:
1879
            raise AssertionError(
1880
                "fetch_spec and revision_id are mutually exclusive.")
4145.1.1 by Robert Collins
Explicitly prevent fetching while the target repository is in a write group.
1881
        if self.is_in_write_group():
4145.1.3 by Robert Collins
NEWS conflicts.
1882
            raise errors.InternalBzrError(
1883
                "May not fetch while in a write group.")
4145.1.1 by Robert Collins
Explicitly prevent fetching while the target repository is in a write group.
1884
        # fast path same-url fetch operations
4509.3.19 by Martin Pool
RemoteRepository.fetch is not a no-op if there's different stacking
1885
        if (self.has_same_location(source)
1886
            and fetch_spec is None
4509.3.37 by Martin Pool
Remove RepositoryBase; make _has_same_location private
1887
            and self._has_same_fallbacks(source)):
2881.4.1 by Robert Collins
Move responsibility for detecting same-repo fetching from the
1888
            # check that last_revision is in 'from' and then return a
1889
            # no-operation.
1890
            if (revision_id is not None and
5712.3.13 by Jelmer Vernooij
Add Prober.known_formats().
1891
                not _mod_revision.is_null(revision_id)):
2881.4.1 by Robert Collins
Move responsibility for detecting same-repo fetching from the
1892
                self.get_revision(revision_id)
2592.4.5 by Martin Pool
Add Repository.base on all repositories.
1893
            return 0, []
4145.1.1 by Robert Collins
Explicitly prevent fetching while the target repository is in a write group.
1894
        # if there is no specific appropriate InterRepository, this will get
1895
        # the InterRepository base class, which raises an
1896
        # IncompatibleRepositories when asked to fetch.
5712.3.13 by Jelmer Vernooij
Add Prober.known_formats().
1897
        inter = _mod_repository.InterRepository.get(source, self)
5670.1.1 by Jelmer Vernooij
Remove all methods and arguments that were deprecated before bzr 2.0.0.
1898
        return inter.fetch(revision_id=revision_id,
4145.1.1 by Robert Collins
Explicitly prevent fetching while the target repository is in a write group.
1899
            find_ghosts=find_ghosts, fetch_spec=fetch_spec)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1900
2520.4.54 by Aaron Bentley
Hang a create_bundle method off repository
1901
    def create_bundle(self, target, base, fileobj, format=None):
1902
        self._ensure_real()
1903
        self._real_repository.create_bundle(target, base, fileobj, format)
1904
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
1905
    @needs_read_lock
5972.3.10 by Jelmer Vernooij
Deprecate Repository.get_ancestry.
1906
    @symbol_versioning.deprecated_method(
1907
        symbol_versioning.deprecated_in((2, 4, 0)))
2530.1.1 by Aaron Bentley
Make topological sorting optional for get_ancestry
1908
    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.
1909
        self._ensure_real()
2530.1.1 by Aaron Bentley
Make topological sorting optional for get_ancestry
1910
        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.
1911
1912
    def fileids_altered_by_revision_ids(self, revision_ids):
1913
        self._ensure_real()
1914
        return self._real_repository.fileids_altered_by_revision_ids(revision_ids)
1915
3036.1.3 by Robert Collins
Privatise VersionedFileChecker.
1916
    def _get_versioned_file_checker(self, revisions, revision_versions_cache):
2745.6.1 by Aaron Bentley
Initial checking of knit graphs
1917
        self._ensure_real()
3036.1.3 by Robert Collins
Privatise VersionedFileChecker.
1918
        return self._real_repository._get_versioned_file_checker(
2745.6.50 by Andrew Bennetts
Remove find_bad_ancestors; it's not needed anymore.
1919
            revisions, revision_versions_cache)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
1920
6280.10.12 by Jelmer Vernooij
Handle stacking.
1921
    def _iter_files_bytes_rpc(self, desired_files, absent):
6280.10.7 by Jelmer Vernooij
Fix remote.
1922
        path = self.bzrdir._path_for_remote_call(self._client)
1923
        lines = []
1924
        identifiers = []
1925
        for (file_id, revid, identifier) in desired_files:
6280.10.18 by Jelmer Vernooij
Ensure file ids are always utf8.
1926
            lines.append("%s\0%s" % (
1927
                osutils.safe_file_id(file_id),
1928
                osutils.safe_revision_id(revid)))
6280.10.7 by Jelmer Vernooij
Fix remote.
1929
            identifiers.append(identifier)
1930
        (response_tuple, response_handler) = (
1931
            self._call_with_body_bytes_expecting_body(
6280.10.19 by Jelmer Vernooij
Convert remote side to zlib.
1932
            "Repository.iter_files_bytes", (path, ), "\n".join(lines)))
6280.10.7 by Jelmer Vernooij
Fix remote.
1933
        if response_tuple != ('ok', ):
1934
            response_handler.cancel_read_body()
1935
            raise errors.UnexpectedSmartServerResponse(response_tuple)
1936
        byte_stream = response_handler.read_streamed_body()
6280.10.10 by Jelmer Vernooij
Use streaming.
1937
        def decompress_stream(start, byte_stream, unused):
6280.10.19 by Jelmer Vernooij
Convert remote side to zlib.
1938
            decompressor = zlib.decompressobj()
6280.10.10 by Jelmer Vernooij
Use streaming.
1939
            yield decompressor.decompress(start)
6280.10.8 by Jelmer Vernooij
Fix iterator handling.
1940
            while decompressor.unused_data == "":
1941
                try:
6280.10.9 by Jelmer Vernooij
Works.
1942
                    data = byte_stream.next()
1943
                except StopIteration:
6280.10.8 by Jelmer Vernooij
Fix iterator handling.
1944
                    break
6280.10.22 by Jelmer Vernooij
Simplify code a bit.
1945
                yield decompressor.decompress(data)
1946
            yield decompressor.flush()
6280.10.10 by Jelmer Vernooij
Use streaming.
1947
            unused.append(decompressor.unused_data)
6280.10.8 by Jelmer Vernooij
Fix iterator handling.
1948
        unused = ""
6280.10.7 by Jelmer Vernooij
Fix remote.
1949
        while True:
6280.10.8 by Jelmer Vernooij
Fix iterator handling.
1950
            while not "\n" in unused:
1951
                unused += byte_stream.next()
6280.10.11 by Jelmer Vernooij
mark absent entries.
1952
            header, rest = unused.split("\n", 1)
1953
            args = header.split("\0")
1954
            if args[0] == "absent":
6280.10.12 by Jelmer Vernooij
Handle stacking.
1955
                absent[identifiers[int(args[3])]] = (args[1], args[2])
6280.10.13 by Jelmer Vernooij
Handle absent.
1956
                unused = rest
1957
                continue
6280.10.11 by Jelmer Vernooij
mark absent entries.
1958
            elif args[0] == "ok":
1959
                idx = int(args[1])
1960
            else:
1961
                raise errors.UnexpectedSmartServerResponse(args)
6280.10.22 by Jelmer Vernooij
Simplify code a bit.
1962
            unused_chunks = []
6280.10.11 by Jelmer Vernooij
mark absent entries.
1963
            yield (identifiers[idx],
6280.10.22 by Jelmer Vernooij
Simplify code a bit.
1964
                decompress_stream(rest, byte_stream, unused_chunks))
1965
            unused = "".join(unused_chunks)
6280.10.1 by Jelmer Vernooij
Add remote side of Repository.iter_file_bytes.
1966
2708.1.7 by Aaron Bentley
Rename extract_files_bytes to iter_files_bytes
1967
    def iter_files_bytes(self, desired_files):
2708.1.9 by Aaron Bentley
Clean-up docs and imports
1968
        """See Repository.iter_file_bytes.
2708.1.3 by Aaron Bentley
Implement extract_files_bytes on Repository
1969
        """
6280.10.1 by Jelmer Vernooij
Add remote side of Repository.iter_file_bytes.
1970
        try:
6280.10.12 by Jelmer Vernooij
Handle stacking.
1971
            absent = {}
6280.10.1 by Jelmer Vernooij
Add remote side of Repository.iter_file_bytes.
1972
            for (identifier, bytes_iterator) in self._iter_files_bytes_rpc(
6280.10.12 by Jelmer Vernooij
Handle stacking.
1973
                    desired_files, absent):
6280.10.1 by Jelmer Vernooij
Add remote side of Repository.iter_file_bytes.
1974
                yield identifier, bytes_iterator
6280.10.13 by Jelmer Vernooij
Handle absent.
1975
            for fallback in self._fallback_repositories:
1976
                if not absent:
1977
                    break
1978
                desired_files = [(key[0], key[1], identifier) for
1979
                    (identifier, key) in absent.iteritems()]
6280.10.23 by Jelmer Vernooij
Fix access to fallback repositories.
1980
                for (identifier, bytes_iterator) in fallback.iter_files_bytes(desired_files):
6280.10.13 by Jelmer Vernooij
Handle absent.
1981
                    del absent[identifier]
1982
                    yield identifier, bytes_iterator
1983
            if absent:
1984
                # There may be more missing items, but raise an exception
1985
                # for just one.
1986
                missing_identifier = absent.keys()[0]
1987
                missing_key = absent[missing_identifier]
6280.10.23 by Jelmer Vernooij
Fix access to fallback repositories.
1988
                raise errors.RevisionNotPresent(revision_id=missing_key[1],
1989
                    file_id=missing_key[0])
6280.10.1 by Jelmer Vernooij
Add remote side of Repository.iter_file_bytes.
1990
        except errors.UnknownSmartMethod:
1991
            self._ensure_real()
1992
            for (identifier, bytes_iterator) in (
1993
                self._real_repository.iter_files_bytes(desired_files)):
1994
                yield identifier, bytes_iterator
2708.1.3 by Aaron Bentley
Implement extract_files_bytes on Repository
1995
6015.24.4 by John Arbash Meinel
For it to all work properly, we have to expose get_parent_map_cached on RemoteRepository.
1996
    def get_cached_parent_map(self, revision_ids):
1997
        """See bzrlib.CachingParentsProvider.get_cached_parent_map"""
1998
        return self._unstacked_provider.get_cached_parent_map(revision_ids)
1999
3835.1.1 by Aaron Bentley
Stack get_parent_map on fallback repos
2000
    def get_parent_map(self, revision_ids):
3835.1.6 by Aaron Bentley
Reduce inefficiency when doing make_parents_provider frequently
2001
        """See bzrlib.Graph.get_parent_map()."""
3835.1.5 by Aaron Bentley
Fix make_parents_provider
2002
        return self._make_parents_provider().get_parent_map(revision_ids)
3835.1.1 by Aaron Bentley
Stack get_parent_map on fallback repos
2003
2004
    def _get_parent_map_rpc(self, keys):
3172.5.6 by Robert Collins
Create new smart server verb Repository.get_parent_map.
2005
        """Helper for get_parent_map that performs the RPC."""
3313.2.1 by Andrew Bennetts
Change _SmartClient's API to accept a medium and a base, rather than a _SharedConnection.
2006
        medium = self._client._medium
3453.4.10 by Andrew Bennetts
Change _is_remote_at_least to _is_remote_before.
2007
        if medium._is_remote_before((1, 2)):
3213.1.1 by Andrew Bennetts
Recover (by reconnecting) if the server turns out not to understand the new requests in 1.2 that send bodies.
2008
            # We already found out that the server can't understand
3213.1.3 by Andrew Bennetts
Fix typo in comment.
2009
            # Repository.get_parent_map requests, so just fetch the whole
3213.1.1 by Andrew Bennetts
Recover (by reconnecting) if the server turns out not to understand the new requests in 1.2 that send bodies.
2010
            # graph.
3948.3.7 by Martin Pool
Updated tests for RemoteRepository.get_parent_map on old servers.
2011
            #
2012
            # Note that this reads the whole graph, when only some keys are
2013
            # wanted.  On this old server there's no way (?) to get them all
2014
            # in one go, and the user probably will have seen a warning about
2015
            # the server being old anyhow.
2016
            rg = self._get_revision_graph(None)
4031.3.3 by Matt Nordhoff
Review tweaks from Ben Finney
2017
            # There is an API discrepancy between get_parent_map and
3389.1.1 by John Arbash Meinel
Fix bug #214894. Fix RemoteRepository.get_parent_map() when server is <v1.2
2018
            # get_revision_graph. Specifically, a "key:()" pair in
2019
            # get_revision_graph just means a node has no parents. For
2020
            # "get_parent_map" it means the node is a ghost. So fix up the
2021
            # graph to correct this.
2022
            #   https://bugs.launchpad.net/bzr/+bug/214894
2023
            # There is one other "bug" which is that ghosts in
2024
            # get_revision_graph() are not returned at all. But we won't worry
2025
            # about that for now.
2026
            for node_id, parent_ids in rg.iteritems():
2027
                if parent_ids == ():
2028
                    rg[node_id] = (NULL_REVISION,)
2029
            rg[NULL_REVISION] = ()
2030
            return rg
3213.1.1 by Andrew Bennetts
Recover (by reconnecting) if the server turns out not to understand the new requests in 1.2 that send bodies.
2031
3172.5.6 by Robert Collins
Create new smart server verb Repository.get_parent_map.
2032
        keys = set(keys)
3373.5.2 by John Arbash Meinel
Add repository_implementation tests for get_parent_map
2033
        if None in keys:
2034
            raise ValueError('get_parent_map(None) is not valid')
3172.5.6 by Robert Collins
Create new smart server verb Repository.get_parent_map.
2035
        if NULL_REVISION in keys:
2036
            keys.discard(NULL_REVISION)
2037
            found_parents = {NULL_REVISION:()}
2038
            if not keys:
2039
                return found_parents
2040
        else:
2041
            found_parents = {}
3211.5.1 by Robert Collins
Change the smart server get_parents method to take a graph search to exclude already recieved parents from. This prevents history shortcuts causing huge numbers of duplicates.
2042
        # TODO(Needs analysis): We could assume that the keys being requested
2043
        # from get_parent_map are in a breadth first search, so typically they
2044
        # will all be depth N from some common parent, and we don't have to
2045
        # have the server iterate from the root parent, but rather from the
2046
        # keys we're searching; and just tell the server the keyspace we
2047
        # already have; but this may be more traffic again.
2048
2049
        # Transform self._parents_map into a search request recipe.
2050
        # TODO: Manage this incrementally to avoid covering the same path
2051
        # repeatedly. (The server will have to on each request, but the less
2052
        # work done the better).
4190.1.3 by Robert Collins
Allow optional inclusion of ghost data in server get_parent_map calls.
2053
        #
2054
        # Negative caching notes:
2055
        # new server sends missing when a request including the revid
2056
        # 'include-missing:' is present in the request.
2057
        # missing keys are serialised as missing:X, and we then call
2058
        # provider.note_missing(X) for-all X
3835.1.8 by Aaron Bentley
Make UnstackedParentsProvider manage the cache
2059
        parents_map = self._unstacked_provider.get_cached_map()
3213.1.8 by Andrew Bennetts
Merge from bzr.dev.
2060
        if parents_map is None:
2061
            # Repository is not locked, so there's no cache.
2062
            parents_map = {}
6015.23.11 by John Arbash Meinel
allow a bit more flexibilty in how we walk the searches.
2063
        if _DEFAULT_SEARCH_DEPTH <= 0:
2064
            (start_set, stop_keys,
2065
             key_count) = graph.search_result_from_parent_map(
2066
                parents_map, self._unstacked_provider.missing_keys)
2067
        else:
6015.23.8 by John Arbash Meinel
Play around with when to activate how much history searching.
2068
            (start_set, stop_keys,
2069
             key_count) = graph.limited_search_result_from_parent_map(
2070
                parents_map, self._unstacked_provider.missing_keys,
6015.23.11 by John Arbash Meinel
allow a bit more flexibilty in how we walk the searches.
2071
                keys, depth=_DEFAULT_SEARCH_DEPTH)
6015.23.3 by John Arbash Meinel
Start refactoring code into graph.py code for easier testing.
2072
        recipe = ('manual', start_set, stop_keys, key_count)
3842.3.20 by Andrew Bennetts
Re-revert changes from another thread that accidentally got reinstated here.
2073
        body = self._serialise_search_recipe(recipe)
3172.5.6 by Robert Collins
Create new smart server verb Repository.get_parent_map.
2074
        path = self.bzrdir._path_for_remote_call(self._client)
2075
        for key in keys:
3360.2.8 by Martin Pool
Change assertion to a plain raise
2076
            if type(key) is not str:
2077
                raise ValueError(
2078
                    "key %r not a plain string" % (key,))
3172.5.8 by Robert Collins
Review feedback.
2079
        verb = 'Repository.get_parent_map'
4190.1.4 by Robert Collins
Cache ghosts when we can get them from a RemoteRepository in get_parent_map.
2080
        args = (path, 'include-missing:') + tuple(keys)
3297.3.3 by Andrew Bennetts
SmartClientRequestProtocol*.read_response_tuple can now raise UnknownSmartMethod. Callers no longer need to do their own ad hoc unknown smart method error detection.
2081
        try:
3786.2.3 by Andrew Bennetts
Remove duplicated 'call & translate errors' code in bzrlib.remote.
2082
            response = self._call_with_body_bytes_expecting_body(
3842.3.20 by Andrew Bennetts
Re-revert changes from another thread that accidentally got reinstated here.
2083
                verb, args, body)
3297.3.3 by Andrew Bennetts
SmartClientRequestProtocol*.read_response_tuple can now raise UnknownSmartMethod. Callers no longer need to do their own ad hoc unknown smart method error detection.
2084
        except errors.UnknownSmartMethod:
3213.1.2 by Andrew Bennetts
Add test for reconnection if get_parent_map is unknown by the server.
2085
            # Server does not support this method, so get the whole graph.
3213.1.1 by Andrew Bennetts
Recover (by reconnecting) if the server turns out not to understand the new requests in 1.2 that send bodies.
2086
            # Worse, we have to force a disconnection, because the server now
2087
            # doesn't realise it has a body on the wire to consume, so the
2088
            # only way to recover is to abandon the connection.
3213.1.6 by Andrew Bennetts
Emit warnings when forcing a reconnect.
2089
            warning(
2090
                'Server is too old for fast get_parent_map, reconnecting.  '
2091
                '(Upgrade the server to Bazaar 1.2 to avoid this)')
3213.1.1 by Andrew Bennetts
Recover (by reconnecting) if the server turns out not to understand the new requests in 1.2 that send bodies.
2092
            medium.disconnect()
2093
            # To avoid having to disconnect repeatedly, we keep track of the
2094
            # fact the server doesn't understand remote methods added in 1.2.
3453.4.9 by Andrew Bennetts
Rename _remote_is_not to _remember_remote_is_before.
2095
            medium._remember_remote_is_before((1, 2))
3948.3.7 by Martin Pool
Updated tests for RemoteRepository.get_parent_map on old servers.
2096
            # Recurse just once and we should use the fallback code.
2097
            return self._get_parent_map_rpc(keys)
3245.4.58 by Andrew Bennetts
Unpack call_expecting_body's return value into variables, to avoid lots of ugly subscripting.
2098
        response_tuple, response_handler = response
2099
        if response_tuple[0] not in ['ok']:
2100
            response_handler.cancel_read_body()
2101
            raise errors.UnexpectedSmartServerResponse(response_tuple)
2102
        if response_tuple[0] == 'ok':
2103
            coded = bz2.decompress(response_handler.read_body_bytes())
3172.5.6 by Robert Collins
Create new smart server verb Repository.get_parent_map.
2104
            if coded == '':
2105
                # no revisions found
2106
                return {}
2107
            lines = coded.split('\n')
2108
            revision_graph = {}
2109
            for line in lines:
2110
                d = tuple(line.split())
2111
                if len(d) > 1:
2112
                    revision_graph[d[0]] = d[1:]
2113
                else:
4190.1.4 by Robert Collins
Cache ghosts when we can get them from a RemoteRepository in get_parent_map.
2114
                    # No parents:
2115
                    if d[0].startswith('missing:'):
2116
                        revid = d[0][8:]
2117
                        self._unstacked_provider.note_missing_key(revid)
2118
                    else:
2119
                        # no parents - so give the Graph result
2120
                        # (NULL_REVISION,).
2121
                        revision_graph[d[0]] = (NULL_REVISION,)
3172.5.6 by Robert Collins
Create new smart server verb Repository.get_parent_map.
2122
            return revision_graph
2123
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
2124
    @needs_read_lock
2125
    def get_signature_text(self, revision_id):
6263.3.2 by Jelmer Vernooij
Add new HPSS call 'Repository.get_revision_signature_text'.
2126
        path = self.bzrdir._path_for_remote_call(self._client)
2127
        try:
2128
            response_tuple, response_handler = self._call_expecting_body(
2129
                'Repository.get_revision_signature_text', path, revision_id)
6263.3.5 by Jelmer Vernooij
Add support for fallback repositories.
2130
        except errors.UnknownSmartMethod:
2131
            self._ensure_real()
2132
            return self._real_repository.get_signature_text(revision_id)
2133
        except errors.NoSuchRevision, err:
2134
            for fallback in self._fallback_repositories:
2135
                try:
2136
                    return fallback.get_signature_text(revision_id)
2137
                except errors.NoSuchRevision:
2138
                    pass
2139
            raise err
2140
        else:
6263.3.2 by Jelmer Vernooij
Add new HPSS call 'Repository.get_revision_signature_text'.
2141
            if response_tuple[0] != 'ok':
2142
                raise errors.UnexpectedSmartServerResponse(response_tuple)
2143
            return response_handler.read_body_bytes()
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
2144
2145
    @needs_read_lock
4988.5.1 by Jelmer Vernooij
Rename Repository.get_inventory_xml -> Repository._get_inventory_xml.
2146
    def _get_inventory_xml(self, revision_id):
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
2147
        self._ensure_real()
4988.5.1 by Jelmer Vernooij
Rename Repository.get_inventory_xml -> Repository._get_inventory_xml.
2148
        return self._real_repository._get_inventory_xml(revision_id)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
2149
2150
    def reconcile(self, other=None, thorough=False):
2151
        self._ensure_real()
2152
        return self._real_repository.reconcile(other=other, thorough=thorough)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
2153
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
2154
    def all_revision_ids(self):
6280.3.1 by Jelmer Vernooij
Add remote side of Repository.all_revision_ids.
2155
        path = self.bzrdir._path_for_remote_call(self._client)
2156
        try:
2157
            response_tuple, response_handler = self._call_expecting_body(
2158
                "Repository.all_revision_ids", path)
2159
        except errors.UnknownSmartMethod:
2160
            self._ensure_real()
2161
            return self._real_repository.all_revision_ids()
2162
        if response_tuple != ("ok", ):
2163
            raise errors.UnexpectedSmartServerResponse(response_tuple)
6280.3.3 by Jelmer Vernooij
Cope with fallback repositories.
2164
        revids = set(response_handler.read_body_bytes().splitlines())
2165
        for fallback in self._fallback_repositories:
2166
            revids.update(set(fallback.all_revision_ids()))
2167
        return list(revids)
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
2168
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
2169
    @needs_read_lock
4137.3.2 by Ian Clatworthy
Repository.get_deltas_for_revisions() now supports file-id filtering
2170
    def get_deltas_for_revisions(self, revisions, specific_fileids=None):
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
2171
        self._ensure_real()
4137.3.2 by Ian Clatworthy
Repository.get_deltas_for_revisions() now supports file-id filtering
2172
        return self._real_repository.get_deltas_for_revisions(revisions,
2173
            specific_fileids=specific_fileids)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
2174
2175
    @needs_read_lock
4137.3.2 by Ian Clatworthy
Repository.get_deltas_for_revisions() now supports file-id filtering
2176
    def get_revision_delta(self, revision_id, specific_fileids=None):
6267.1.2 by Jelmer Vernooij
Avoid _ensure_real in some more calls.
2177
        r = self.get_revision(revision_id)
2178
        return list(self.get_deltas_for_revisions([r],
2179
            specific_fileids=specific_fileids))[0]
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
2180
2181
    @needs_read_lock
2182
    def revision_trees(self, revision_ids):
6280.11.2 by Jelmer Vernooij
Implement RemoteRepository.revision_trees() using RemoteRepository.iter_inventories()
2183
        inventories = self.iter_inventories(revision_ids)
2184
        for inv in inventories:
2185
            yield InventoryRevisionTree(self, inv, inv.revision_id)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
2186
2187
    @needs_read_lock
2188
    def get_revision_reconcile(self, revision_id):
2189
        self._ensure_real()
2190
        return self._real_repository.get_revision_reconcile(revision_id)
2191
2192
    @needs_read_lock
4332.3.35 by Robert Collins
Fix failing tests.
2193
    def check(self, revision_ids=None, callback_refs=None, check_repo=True):
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
2194
        self._ensure_real()
4332.3.11 by Robert Collins
Move tree and back callbacks into the repository check core.
2195
        return self._real_repository.check(revision_ids=revision_ids,
4332.3.35 by Robert Collins
Fix failing tests.
2196
            callback_refs=callback_refs, check_repo=check_repo)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
2197
2018.5.138 by Robert Collins
Merge bzr.dev.
2198
    def copy_content_into(self, destination, revision_id=None):
6267.1.1 by Jelmer Vernooij
Avoid _ensure_real in a couple more places.
2199
        """Make a complete copy of the content in self into destination.
2200
2201
        This is a destructive operation! Do not use it on existing
2202
        repositories.
2203
        """
2204
        interrepo = _mod_repository.InterRepository.get(self, destination)
2205
        return interrepo.copy_content(revision_id)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
2206
2814.10.2 by Andrew Bennetts
Make the fallback a little tidier.
2207
    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.
2208
        # get a tarball of the remote repository, and copy from that into the
2209
        # destination
2018.18.9 by Martin Pool
remote Repository.tarball builds a temporary directory and tars that
2210
        import tarfile
2018.18.20 by Martin Pool
Route branch operations through remote copy_content_into
2211
        # TODO: Maybe a progress bar while streaming the tarball?
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
2212
        note(gettext("Copying repository content as tarball..."))
2018.18.25 by Martin Pool
Repository.tarball fixes for python2.4
2213
        tar_file = self._get_tarball('bz2')
2814.10.2 by Andrew Bennetts
Make the fallback a little tidier.
2214
        if tar_file is None:
2215
            return None
2216
        destination = to_bzrdir.create_repository()
2018.18.10 by Martin Pool
copy_content_into from Remote repositories by using temporary directories on both ends.
2217
        try:
2018.18.25 by Martin Pool
Repository.tarball fixes for python2.4
2218
            tar = tarfile.open('repository', fileobj=tar_file,
2219
                mode='r|bz2')
3638.3.2 by Vincent Ladeuil
Fix all calls to tempfile.mkdtemp to osutils.mkdtemp.
2220
            tmpdir = osutils.mkdtemp()
2018.18.25 by Martin Pool
Repository.tarball fixes for python2.4
2221
            try:
2222
                _extract_tar(tar, tmpdir)
5712.3.13 by Jelmer Vernooij
Add Prober.known_formats().
2223
                tmp_bzrdir = _mod_bzrdir.BzrDir.open(tmpdir)
2018.18.25 by Martin Pool
Repository.tarball fixes for python2.4
2224
                tmp_repo = tmp_bzrdir.open_repository()
2225
                tmp_repo.copy_content_into(destination, revision_id)
2226
            finally:
2227
                osutils.rmtree(tmpdir)
2018.18.10 by Martin Pool
copy_content_into from Remote repositories by using temporary directories on both ends.
2228
        finally:
2018.18.25 by Martin Pool
Repository.tarball fixes for python2.4
2229
            tar_file.close()
2814.10.2 by Andrew Bennetts
Make the fallback a little tidier.
2230
        return destination
2018.18.23 by Martin Pool
review cleanups
2231
        # TODO: Suggestion from john: using external tar is much faster than
2232
        # 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.
2233
3842.3.20 by Andrew Bennetts
Re-revert changes from another thread that accidentally got reinstated here.
2234
    @property
2235
    def inventories(self):
2236
        """Decorate the real repository for now.
2237
2238
        In the long term a full blown network facility is needed to
2239
        avoid creating a real repository object locally.
2240
        """
2241
        self._ensure_real()
2242
        return self._real_repository.inventories
2243
2604.2.1 by Robert Collins
(robertc) Introduce a pack command.
2244
    @needs_write_lock
5108.1.1 by Parth Malwankar
initial support for 'pack --clean-obsolete-packs'. tested only manually.
2245
    def pack(self, hint=None, clean_obsolete_packs=False):
2604.2.1 by Robert Collins
(robertc) Introduce a pack command.
2246
        """Compress the data within the repository.
2247
        """
6305.2.3 by Jelmer Vernooij
Store hint in body.
2248
        if hint is None:
2249
            body = ""
2250
        else:
2251
            body = "".join([l+"\n" for l in hint])
6305.2.1 by Jelmer Vernooij
add remote call for Repository.pack.
2252
        path = self.bzrdir._path_for_remote_call(self._client)
2253
        try:
6305.2.3 by Jelmer Vernooij
Store hint in body.
2254
            response, handler = self._call_with_body_bytes_expecting_body(
2255
                'Repository.pack', (path, self._lock_token,
6305.2.4 by Jelmer Vernooij
Fix tests.
2256
                    str(clean_obsolete_packs)), body)
6305.2.1 by Jelmer Vernooij
add remote call for Repository.pack.
2257
        except errors.UnknownSmartMethod:
2258
            self._ensure_real()
2259
            return self._real_repository.pack(hint=hint,
2260
                clean_obsolete_packs=clean_obsolete_packs)
6305.2.3 by Jelmer Vernooij
Store hint in body.
2261
        handler.cancel_read_body()
6305.2.1 by Jelmer Vernooij
add remote call for Repository.pack.
2262
        if response != ('ok', ):
2263
            raise errors.UnexpectedSmartServerResponse(response)
2604.2.1 by Robert Collins
(robertc) Introduce a pack command.
2264
3842.3.20 by Andrew Bennetts
Re-revert changes from another thread that accidentally got reinstated here.
2265
    @property
2266
    def revisions(self):
2267
        """Decorate the real repository for now.
2268
2269
        In the long term a full blown network facility is needed.
2270
        """
2271
        self._ensure_real()
2272
        return self._real_repository.revisions
2273
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
2274
    def set_make_working_trees(self, new_value):
4017.3.4 by Robert Collins
Create a verb for Repository.set_make_working_trees.
2275
        if new_value:
2276
            new_value_str = "True"
2277
        else:
2278
            new_value_str = "False"
2279
        path = self.bzrdir._path_for_remote_call(self._client)
2280
        try:
2281
            response = self._call(
2282
                'Repository.set_make_working_trees', path, new_value_str)
2283
        except errors.UnknownSmartMethod:
2284
            self._ensure_real()
2285
            self._real_repository.set_make_working_trees(new_value)
2286
        else:
2287
            if response[0] != 'ok':
2288
                raise errors.UnexpectedSmartServerResponse(response)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
2289
3842.3.20 by Andrew Bennetts
Re-revert changes from another thread that accidentally got reinstated here.
2290
    @property
2291
    def signatures(self):
2292
        """Decorate the real repository for now.
2293
2294
        In the long term a full blown network facility is needed to avoid
2295
        creating a real repository object locally.
2296
        """
2297
        self._ensure_real()
2298
        return self._real_repository.signatures
2299
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
2300
    @needs_write_lock
2301
    def sign_revision(self, revision_id, gpg_strategy):
6280.8.1 by Jelmer Vernooij
Avoid _ensure_real in RemoteRepository.verify_revision_signature and RemoteRepository.sign_revision.
2302
        testament = _mod_testament.Testament.from_revision(self, revision_id)
2303
        plaintext = testament.as_short_text()
2304
        self.store_revision_signature(gpg_strategy, plaintext, revision_id)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
2305
3842.3.20 by Andrew Bennetts
Re-revert changes from another thread that accidentally got reinstated here.
2306
    @property
2307
    def texts(self):
2308
        """Decorate the real repository for now.
2309
2310
        In the long term a full blown network facility is needed to avoid
2311
        creating a real repository object locally.
2312
        """
2313
        self._ensure_real()
2314
        return self._real_repository.texts
2315
6280.9.1 by Jelmer Vernooij
Add remote side of Repository.iter_revisions.
2316
    def _iter_revisions_rpc(self, revision_ids):
2317
        body = "\n".join(revision_ids)
2318
        path = self.bzrdir._path_for_remote_call(self._client)
2319
        response_tuple, response_handler = (
2320
            self._call_with_body_bytes_expecting_body(
2321
            "Repository.iter_revisions", (path, ), body))
2322
        if response_tuple[0] != "ok":
2323
            raise errors.UnexpectedSmartServerResponse(response_tuple)
2324
        serializer_format = response_tuple[1]
2325
        serializer = serializer_format_registry.get(serializer_format)
2326
        byte_stream = response_handler.read_streamed_body()
6280.9.4 by Jelmer Vernooij
use zlib instead.
2327
        decompressor = zlib.decompressobj()
6280.9.1 by Jelmer Vernooij
Add remote side of Repository.iter_revisions.
2328
        chunks = []
2329
        for bytes in byte_stream:
6280.9.4 by Jelmer Vernooij
use zlib instead.
2330
            chunks.append(decompressor.decompress(bytes))
6280.9.1 by Jelmer Vernooij
Add remote side of Repository.iter_revisions.
2331
            if decompressor.unused_data != "":
6280.9.4 by Jelmer Vernooij
use zlib instead.
2332
                chunks.append(decompressor.flush())
6280.9.1 by Jelmer Vernooij
Add remote side of Repository.iter_revisions.
2333
                yield serializer.read_revision_from_string("".join(chunks))
6280.9.4 by Jelmer Vernooij
use zlib instead.
2334
                unused = decompressor.unused_data
2335
                decompressor = zlib.decompressobj()
2336
                chunks = [decompressor.decompress(unused)]
2337
        chunks.append(decompressor.flush())
6280.9.1 by Jelmer Vernooij
Add remote side of Repository.iter_revisions.
2338
        text = "".join(chunks)
2339
        if text != "":
2340
            yield serializer.read_revision_from_string("".join(chunks))
2341
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
2342
    @needs_read_lock
2343
    def get_revisions(self, revision_ids):
6280.9.5 by Jelmer Vernooij
Cope with invalid arguments being specified to Repository.get_revisions.
2344
        if revision_ids is None:
2345
            revision_ids = self.all_revision_ids()
2346
        else:
2347
            for rev_id in revision_ids:
2348
                if not rev_id or not isinstance(rev_id, basestring):
2349
                    raise errors.InvalidRevisionId(
2350
                        revision_id=rev_id, branch=self)
6280.9.1 by Jelmer Vernooij
Add remote side of Repository.iter_revisions.
2351
        try:
6280.9.7 by Jelmer Vernooij
Fix compatibility code.
2352
            missing = set(revision_ids)
2353
            revs = {}
2354
            for rev in self._iter_revisions_rpc(revision_ids):
2355
                missing.remove(rev.revision_id)
2356
                revs[rev.revision_id] = rev
6280.9.1 by Jelmer Vernooij
Add remote side of Repository.iter_revisions.
2357
        except errors.UnknownSmartMethod:
2358
            self._ensure_real()
2359
            return self._real_repository.get_revisions(revision_ids)
2360
        for fallback in self._fallback_repositories:
2361
            if not missing:
2362
                break
2363
            for revid in list(missing):
2364
                # XXX JRV 2011-11-20: It would be nice if there was a
2365
                # public method on Repository that could be used to query
2366
                # for revision objects *without* failing completely if one
2367
                # was missing. There is VersionedFileRepository._iter_revisions,
2368
                # but unfortunately that's private and not provided by
2369
                # all repository implementations.
2370
                try:
2371
                    revs[revid] = fallback.get_revision(revid)
2372
                except errors.NoSuchRevision:
2373
                    pass
2374
                else:
2375
                    missing.remove(revid)
2376
        if missing:
2377
            raise errors.NoSuchRevision(self, list(missing)[0])
2378
        return [revs[revid] for revid in revision_ids]
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
2379
2380
    def supports_rich_root(self):
4053.1.4 by Robert Collins
Move the fetch control attributes from Repository to RepositoryFormat.
2381
        return self._format.rich_root_data
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
2382
5972.2.1 by Jelmer Vernooij
Deprecate Repository.iter_reverse_revision_history.
2383
    @symbol_versioning.deprecated_method(symbol_versioning.deprecated_in((2, 4, 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.
2384
    def iter_reverse_revision_history(self, revision_id):
2385
        self._ensure_real()
2386
        return self._real_repository.iter_reverse_revision_history(revision_id)
2387
2018.5.96 by Andrew Bennetts
Merge from bzr.dev, resolving the worst of the semantic conflicts, but there's
2388
    @property
2389
    def _serializer(self):
4053.1.4 by Robert Collins
Move the fetch control attributes from Repository to RepositoryFormat.
2390
        return self._format._serializer
2018.5.96 by Andrew Bennetts
Merge from bzr.dev, resolving the worst of the semantic conflicts, but there's
2391
6267.1.1 by Jelmer Vernooij
Avoid _ensure_real in a couple more places.
2392
    @needs_write_lock
2018.5.97 by Andrew Bennetts
Fix more tests.
2393
    def store_revision_signature(self, gpg_strategy, plaintext, revision_id):
6267.1.1 by Jelmer Vernooij
Avoid _ensure_real in a couple more places.
2394
        signature = gpg_strategy.sign(plaintext)
2395
        self.add_signature_text(revision_id, signature)
2018.5.97 by Andrew Bennetts
Fix more tests.
2396
2996.2.8 by Aaron Bentley
Fix add_signature discrepancies
2397
    def add_signature_text(self, revision_id, signature):
6268.1.10 by Jelmer Vernooij
Use real repository if it is already present.
2398
        if self._real_repository:
2399
            # If there is a real repository the write group will
2400
            # be in the real repository as well, so use that:
6268.1.2 by Jelmer Vernooij
Initial work on Repository.add_signature_text.
2401
            self._ensure_real()
2402
            return self._real_repository.add_signature_text(
2403
                revision_id, signature)
6268.1.10 by Jelmer Vernooij
Use real repository if it is already present.
2404
        path = self.bzrdir._path_for_remote_call(self._client)
6280.10.39 by Jelmer Vernooij
Merge bzr.dev.
2405
        response, handler = self._call_with_body_bytes_expecting_body(
6280.10.32 by Jelmer Vernooij
Merge bzr.dev.
2406
            'Repository.add_signature_text', (path, self._lock_token,
2407
                revision_id) + tuple(self._write_group_tokens), signature)
6280.10.39 by Jelmer Vernooij
Merge bzr.dev.
2408
        handler.cancel_read_body()
6268.1.2 by Jelmer Vernooij
Initial work on Repository.add_signature_text.
2409
        self.refresh_data()
2410
        if response[0] != 'ok':
2411
            raise errors.UnexpectedSmartServerResponse(response)
6280.10.36 by Jelmer Vernooij
Use new write group tokens.
2412
        self._write_group_tokens = response[1:]
2996.2.3 by Aaron Bentley
Add tests for install_revisions and add_signature
2413
2018.5.97 by Andrew Bennetts
Fix more tests.
2414
    def has_signature_for_revision_id(self, revision_id):
6265.1.1 by Jelmer Vernooij
Add new HPSS call ``Repository.has_signature_for_revision_id``.
2415
        path = self.bzrdir._path_for_remote_call(self._client)
2416
        try:
2417
            response = self._call('Repository.has_signature_for_revision_id',
2418
                path, revision_id)
2419
        except errors.UnknownSmartMethod:
2420
            self._ensure_real()
2421
            return self._real_repository.has_signature_for_revision_id(
2422
                revision_id)
2423
        if response[0] not in ('yes', 'no'):
2424
            raise SmartProtocolError('unexpected response code %s' % (response,))
6263.3.7 by Jelmer Vernooij
Fallback for RemoteRepository.has_signature_for_revision_id.
2425
        if response[0] == 'yes':
2426
            return True
2427
        for fallback in self._fallback_repositories:
2428
            if fallback.has_signature_for_revision_id(revision_id):
2429
                return True
2430
        return False
2018.5.97 by Andrew Bennetts
Fix more tests.
2431
6280.8.5 by Jelmer Vernooij
Add needs_read_lock for verify_revision_signature.
2432
    @needs_read_lock
6257.3.1 by Jelmer Vernooij
Support verifying remote signatures.
2433
    def verify_revision_signature(self, revision_id, gpg_strategy):
6280.8.1 by Jelmer Vernooij
Avoid _ensure_real in RemoteRepository.verify_revision_signature and RemoteRepository.sign_revision.
2434
        if not self.has_signature_for_revision_id(revision_id):
2435
            return gpg.SIGNATURE_NOT_SIGNED, None
2436
        signature = self.get_signature_text(revision_id)
2437
2438
        testament = _mod_testament.Testament.from_revision(self, revision_id)
2439
        plaintext = testament.as_short_text()
2440
2441
        return gpg_strategy.verify(signature, plaintext)
6257.3.1 by Jelmer Vernooij
Support verifying remote signatures.
2442
2535.3.45 by Andrew Bennetts
Add item_keys_introduced_by to RemoteRepository.
2443
    def item_keys_introduced_by(self, revision_ids, _files_pb=None):
2444
        self._ensure_real()
2445
        return self._real_repository.item_keys_introduced_by(revision_ids,
2446
            _files_pb=_files_pb)
2447
4332.3.34 by Robert Collins
Delete obsolete pack tuned find_inconsistent_revisions as the generic code path permits the same optimisation.
2448
    def _find_inconsistent_revision_parents(self, revisions_iterator=None):
2819.2.5 by Andrew Bennetts
Make reconcile abort gracefully if the revision index has bad parents.
2449
        self._ensure_real()
4332.3.34 by Robert Collins
Delete obsolete pack tuned find_inconsistent_revisions as the generic code path permits the same optimisation.
2450
        return self._real_repository._find_inconsistent_revision_parents(
2451
            revisions_iterator)
2819.2.5 by Andrew Bennetts
Make reconcile abort gracefully if the revision index has bad parents.
2452
2453
    def _check_for_inconsistent_revision_parents(self):
2454
        self._ensure_real()
2455
        return self._real_repository._check_for_inconsistent_revision_parents()
2456
3835.1.17 by Aaron Bentley
Fix stacking bug
2457
    def _make_parents_provider(self, other=None):
3835.1.8 by Aaron Bentley
Make UnstackedParentsProvider manage the cache
2458
        providers = [self._unstacked_provider]
3835.1.17 by Aaron Bentley
Fix stacking bug
2459
        if other is not None:
2460
            providers.insert(0, other)
5816.8.3 by Andrew Bennetts
Add test for calling add_fallback_repository after _make_parents_provider, and make it work.
2461
        return graph.StackedParentsProvider(_LazyListJoin(
2462
            providers, self._fallback_repositories))
3172.5.1 by Robert Collins
Create a RemoteRepository get_graph implementation and delegate get_parents_map to the real repository.
2463
3842.3.20 by Andrew Bennetts
Re-revert changes from another thread that accidentally got reinstated here.
2464
    def _serialise_search_recipe(self, recipe):
2465
        """Serialise a graph search recipe.
2466
2467
        :param recipe: A search recipe (start, stop, count).
2468
        :return: Serialised bytes.
2469
        """
4152.1.2 by Robert Collins
Add streaming from a stacked branch when the sort order is compatible with doing so.
2470
        start_keys = ' '.join(recipe[1])
2471
        stop_keys = ' '.join(recipe[2])
2472
        count = str(recipe[3])
3842.3.20 by Andrew Bennetts
Re-revert changes from another thread that accidentally got reinstated here.
2473
        return '\n'.join((start_keys, stop_keys, count))
2474
4070.9.5 by Andrew Bennetts
Better wire protocol: don't shoehorn MiniSearchResult serialisation into previous serialisation format.
2475
    def _serialise_search_result(self, search_result):
5539.2.2 by Andrew Bennetts
Add support for 'everything' fetch spec to RemoteStreamSource.
2476
        parts = search_result.get_network_struct()
4070.9.5 by Andrew Bennetts
Better wire protocol: don't shoehorn MiniSearchResult serialisation into previous serialisation format.
2477
        return '\n'.join(parts)
2478
3842.3.2 by Andrew Bennetts
Revert the RemoteVersionedFiles.get_parent_map implementation, leaving just the skeleton of RemoteVersionedFiles.
2479
    def autopack(self):
2480
        path = self.bzrdir._path_for_remote_call(self._client)
2481
        try:
2482
            response = self._call('PackRepository.autopack', path)
2483
        except errors.UnknownSmartMethod:
2484
            self._ensure_real()
2485
            self._real_repository._pack_collection.autopack()
2486
            return
4145.1.2 by Robert Collins
Add a refresh_data method on Repository allowing cleaner handling of insertions into RemoteRepository objects with _real_repository instances.
2487
        self.refresh_data()
3842.3.2 by Andrew Bennetts
Revert the RemoteVersionedFiles.get_parent_map implementation, leaving just the skeleton of RemoteVersionedFiles.
2488
        if response[0] != 'ok':
2489
            raise errors.UnexpectedSmartServerResponse(response)
2490
2491
5815.4.1 by Jelmer Vernooij
Split versionedfile-specific stuff out into VersionedFileRepository.
2492
class RemoteStreamSink(vf_repository.StreamSink):
4022.1.6 by Robert Collins
Cherrypick and polish the RemoteSink for streaming push.
2493
4032.3.7 by Robert Collins
Move write locking and write group responsibilities into the Sink objects themselves, allowing complete avoidance of unnecessary calls when the sink is a RemoteSink.
2494
    def _insert_real(self, stream, src_format, resume_tokens):
4022.1.6 by Robert Collins
Cherrypick and polish the RemoteSink for streaming push.
2495
        self.target_repo._ensure_real()
2496
        sink = self.target_repo._real_repository._get_sink()
4032.3.7 by Robert Collins
Move write locking and write group responsibilities into the Sink objects themselves, allowing complete avoidance of unnecessary calls when the sink is a RemoteSink.
2497
        result = sink.insert_stream(stream, src_format, resume_tokens)
4029.2.1 by Robert Collins
Support streaming push to stacked branches.
2498
        if not result:
2499
            self.target_repo.autopack()
2500
        return result
4022.1.6 by Robert Collins
Cherrypick and polish the RemoteSink for streaming push.
2501
4032.3.7 by Robert Collins
Move write locking and write group responsibilities into the Sink objects themselves, allowing complete avoidance of unnecessary calls when the sink is a RemoteSink.
2502
    def insert_stream(self, stream, src_format, resume_tokens):
4144.3.2 by Andrew Bennetts
Use Repository.insert_stream_locked if there is a lock_token for the remote repo.
2503
        target = self.target_repo
4307.2.4 by Robert Collins
Enable caching of negative revision lookups in RemoteRepository write locks when no _real_repository has been constructed.
2504
        target._unstacked_provider.missing_keys.clear()
4476.3.82 by Andrew Bennetts
Mention another bug fix in NEWS, and update verb name, comments, and NEWS additions for landing on 1.19 rather than 1.18.
2505
        candidate_calls = [('Repository.insert_stream_1.19', (1, 19))]
4144.3.2 by Andrew Bennetts
Use Repository.insert_stream_locked if there is a lock_token for the remote repo.
2506
        if target._lock_token:
4476.3.15 by Andrew Bennetts
Partially working fallback for pre-1.17 servers.
2507
            candidate_calls.append(('Repository.insert_stream_locked', (1, 14)))
2508
            lock_args = (target._lock_token or '',)
4144.3.2 by Andrew Bennetts
Use Repository.insert_stream_locked if there is a lock_token for the remote repo.
2509
        else:
4476.3.15 by Andrew Bennetts
Partially working fallback for pre-1.17 servers.
2510
            candidate_calls.append(('Repository.insert_stream', (1, 13)))
2511
            lock_args = ()
4144.3.2 by Andrew Bennetts
Use Repository.insert_stream_locked if there is a lock_token for the remote repo.
2512
        client = target._client
4022.1.9 by Robert Collins
Fix critical issue in bzr.dev - pushing to an old bzr:// server fails because the stream being consumed before the fallback code occurs, which makes it fail to do the fetch. (Robert Collins, Andrew Bennetts, #332314)
2513
        medium = client._medium
4144.3.2 by Andrew Bennetts
Use Repository.insert_stream_locked if there is a lock_token for the remote repo.
2514
        path = target.bzrdir._path_for_remote_call(client)
4476.3.70 by Andrew Bennetts
Review tweaks.
2515
        # Probe for the verb to use with an empty stream before sending the
2516
        # real stream to it.  We do this both to avoid the risk of sending a
2517
        # large request that is then rejected, and because we don't want to
2518
        # implement a way to buffer, rewind, or restart the stream.
4476.3.15 by Andrew Bennetts
Partially working fallback for pre-1.17 servers.
2519
        found_verb = False
2520
        for verb, required_version in candidate_calls:
2521
            if medium._is_remote_before(required_version):
2522
                continue
4476.3.25 by Andrew Bennetts
Reinstate don't-reprobe-with-resume-tokens optimisation, fixing acceptance test.
2523
            if resume_tokens:
2524
                # We've already done the probing (and set _is_remote_before) on
2525
                # a previous insert.
2526
                found_verb = True
2527
                break
4060.1.4 by Robert Collins
Streaming fetch from remote servers.
2528
            byte_stream = smart_repo._stream_to_byte_stream([], src_format)
4029.2.1 by Robert Collins
Support streaming push to stacked branches.
2529
            try:
2530
                response = client.call_with_body_stream(
4476.3.15 by Andrew Bennetts
Partially working fallback for pre-1.17 servers.
2531
                    (verb, path, '') + lock_args, byte_stream)
4029.2.1 by Robert Collins
Support streaming push to stacked branches.
2532
            except errors.UnknownSmartMethod:
4144.3.2 by Andrew Bennetts
Use Repository.insert_stream_locked if there is a lock_token for the remote repo.
2533
                medium._remember_remote_is_before(required_version)
4476.3.15 by Andrew Bennetts
Partially working fallback for pre-1.17 servers.
2534
            else:
2535
                found_verb = True
2536
                break
2537
        if not found_verb:
2538
            # Have to use VFS.
2539
            return self._insert_real(stream, src_format, resume_tokens)
2540
        self._last_inv_record = None
2541
        self._last_substream = None
4476.3.82 by Andrew Bennetts
Mention another bug fix in NEWS, and update verb name, comments, and NEWS additions for landing on 1.19 rather than 1.18.
2542
        if required_version < (1, 19):
4476.3.35 by Andrew Bennetts
Expand comment.
2543
            # Remote side doesn't support inventory deltas.  Wrap the stream to
2544
            # make sure we don't send any.  If the stream contains inventory
2545
            # deltas we'll interrupt the smart insert_stream request and
2546
            # fallback to VFS.
4476.3.15 by Andrew Bennetts
Partially working fallback for pre-1.17 servers.
2547
            stream = self._stop_stream_if_inventory_delta(stream)
4060.1.4 by Robert Collins
Streaming fetch from remote servers.
2548
        byte_stream = smart_repo._stream_to_byte_stream(
2549
            stream, src_format)
4032.3.7 by Robert Collins
Move write locking and write group responsibilities into the Sink objects themselves, allowing complete avoidance of unnecessary calls when the sink is a RemoteSink.
2550
        resume_tokens = ' '.join(resume_tokens)
4022.1.9 by Robert Collins
Fix critical issue in bzr.dev - pushing to an old bzr:// server fails because the stream being consumed before the fallback code occurs, which makes it fail to do the fetch. (Robert Collins, Andrew Bennetts, #332314)
2551
        response = client.call_with_body_stream(
4476.3.15 by Andrew Bennetts
Partially working fallback for pre-1.17 servers.
2552
            (verb, path, resume_tokens) + lock_args, byte_stream)
4029.2.1 by Robert Collins
Support streaming push to stacked branches.
2553
        if response[0][0] not in ('ok', 'missing-basis'):
4022.1.9 by Robert Collins
Fix critical issue in bzr.dev - pushing to an old bzr:// server fails because the stream being consumed before the fallback code occurs, which makes it fail to do the fetch. (Robert Collins, Andrew Bennetts, #332314)
2554
            raise errors.UnexpectedSmartServerResponse(response)
4476.3.54 by Andrew Bennetts
Update fallback-to-VFS in remote.py for the inventory-deltas substream.
2555
        if self._last_substream is not None:
4476.3.21 by Andrew Bennetts
Clarify some code and comments, and s/1.17/1.18/ in a few places.
2556
            # The stream included an inventory-delta record, but the remote
2557
            # side isn't new enough to support them.  So we need to send the
2558
            # rest of the stream via VFS.
4634.35.15 by Andrew Bennetts
Fix 'fallback to vfs if RPC does not support inventory-deltas' case to refresh the vfs pack names before starting the fallback.
2559
            self.target_repo.refresh_data()
4476.3.21 by Andrew Bennetts
Clarify some code and comments, and s/1.17/1.18/ in a few places.
2560
            return self._resume_stream_with_vfs(response, src_format)
4029.2.1 by Robert Collins
Support streaming push to stacked branches.
2561
        if response[0][0] == 'missing-basis':
2562
            tokens, missing_keys = bencode.bdecode_as_tuple(response[0][1])
4032.3.7 by Robert Collins
Move write locking and write group responsibilities into the Sink objects themselves, allowing complete avoidance of unnecessary calls when the sink is a RemoteSink.
2563
            resume_tokens = tokens
4257.3.3 by Andrew Bennetts
missing_keys from sink.insert_stream should be a set, not a tuple.
2564
            return resume_tokens, set(missing_keys)
4029.2.1 by Robert Collins
Support streaming push to stacked branches.
2565
        else:
4145.1.2 by Robert Collins
Add a refresh_data method on Repository allowing cleaner handling of insertions into RemoteRepository objects with _real_repository instances.
2566
            self.target_repo.refresh_data()
4032.3.7 by Robert Collins
Move write locking and write group responsibilities into the Sink objects themselves, allowing complete avoidance of unnecessary calls when the sink is a RemoteSink.
2567
            return [], set()
4032.1.1 by John Arbash Meinel
Merge the removal of all trailing whitespace, and resolve conflicts.
2568
4476.3.21 by Andrew Bennetts
Clarify some code and comments, and s/1.17/1.18/ in a few places.
2569
    def _resume_stream_with_vfs(self, response, src_format):
2570
        """Resume sending a stream via VFS, first resending the record and
2571
        substream that couldn't be sent via an insert_stream verb.
2572
        """
4476.3.15 by Andrew Bennetts
Partially working fallback for pre-1.17 servers.
2573
        if response[0][0] == 'missing-basis':
2574
            tokens, missing_keys = bencode.bdecode_as_tuple(response[0][1])
2575
            # Ignore missing_keys, we haven't finished inserting yet
2576
        else:
2577
            tokens = []
4476.3.21 by Andrew Bennetts
Clarify some code and comments, and s/1.17/1.18/ in a few places.
2578
        def resume_substream():
4476.3.54 by Andrew Bennetts
Update fallback-to-VFS in remote.py for the inventory-deltas substream.
2579
            # Yield the substream that was interrupted.
4476.3.21 by Andrew Bennetts
Clarify some code and comments, and s/1.17/1.18/ in a few places.
2580
            for record in self._last_substream:
2581
                yield record
2582
            self._last_substream = None
4476.3.15 by Andrew Bennetts
Partially working fallback for pre-1.17 servers.
2583
        def resume_stream():
4476.3.21 by Andrew Bennetts
Clarify some code and comments, and s/1.17/1.18/ in a few places.
2584
            # Finish sending the interrupted substream
4476.3.54 by Andrew Bennetts
Update fallback-to-VFS in remote.py for the inventory-deltas substream.
2585
            yield ('inventory-deltas', resume_substream())
4476.3.21 by Andrew Bennetts
Clarify some code and comments, and s/1.17/1.18/ in a few places.
2586
            # Then simply continue sending the rest of the stream.
4476.3.15 by Andrew Bennetts
Partially working fallback for pre-1.17 servers.
2587
            for substream_kind, substream in self._last_stream:
2588
                yield substream_kind, substream
2589
        return self._insert_real(resume_stream(), src_format, tokens)
2590
2591
    def _stop_stream_if_inventory_delta(self, stream):
4476.3.21 by Andrew Bennetts
Clarify some code and comments, and s/1.17/1.18/ in a few places.
2592
        """Normally this just lets the original stream pass-through unchanged.
2593
4476.3.54 by Andrew Bennetts
Update fallback-to-VFS in remote.py for the inventory-deltas substream.
2594
        However if any 'inventory-deltas' substream occurs it will stop
2595
        streaming, and store the interrupted substream and stream in
2596
        self._last_substream and self._last_stream so that the stream can be
2597
        resumed by _resume_stream_with_vfs.
4476.3.21 by Andrew Bennetts
Clarify some code and comments, and s/1.17/1.18/ in a few places.
2598
        """
5712.3.13 by Jelmer Vernooij
Add Prober.known_formats().
2599
4476.3.15 by Andrew Bennetts
Partially working fallback for pre-1.17 servers.
2600
        stream_iter = iter(stream)
2601
        for substream_kind, substream in stream_iter:
4476.3.54 by Andrew Bennetts
Update fallback-to-VFS in remote.py for the inventory-deltas substream.
2602
            if substream_kind == 'inventory-deltas':
2603
                self._last_substream = substream
2604
                self._last_stream = stream_iter
2605
                return
4476.3.15 by Andrew Bennetts
Partially working fallback for pre-1.17 servers.
2606
            else:
2607
                yield substream_kind, substream
5712.3.13 by Jelmer Vernooij
Add Prober.known_formats().
2608
2609
5815.4.1 by Jelmer Vernooij
Split versionedfile-specific stuff out into VersionedFileRepository.
2610
class RemoteStreamSource(vf_repository.StreamSource):
4060.1.3 by Robert Collins
Implement the separate source component for fetch - repository.StreamSource.
2611
    """Stream data from a remote server."""
2612
4060.1.4 by Robert Collins
Streaming fetch from remote servers.
2613
    def get_stream(self, search):
4152.1.2 by Robert Collins
Add streaming from a stacked branch when the sort order is compatible with doing so.
2614
        if (self.from_repository._fallback_repositories and
2615
            self.to_format._fetch_order == 'topological'):
2616
            return self._real_stream(self.from_repository, search)
4577.1.1 by Robert Collins
Fix fetching from smart servers where there is a chain of stacked repositories rather than a single stacking point. (Robert Collins, bug #406597)
2617
        sources = []
2618
        seen = set()
2619
        repos = [self.from_repository]
2620
        while repos:
2621
            repo = repos.pop(0)
2622
            if repo in seen:
2623
                continue
2624
            seen.add(repo)
2625
            repos.extend(repo._fallback_repositories)
2626
            sources.append(repo)
2627
        return self.missing_parents_chain(search, sources)
4152.1.2 by Robert Collins
Add streaming from a stacked branch when the sort order is compatible with doing so.
2628
4476.3.16 by Andrew Bennetts
Only make inv deltas against bases we've already sent, and other tweaks.
2629
    def get_stream_for_missing_keys(self, missing_keys):
2630
        self.from_repository._ensure_real()
2631
        real_repo = self.from_repository._real_repository
2632
        real_source = real_repo._get_source(self.to_format)
2633
        return real_source.get_stream_for_missing_keys(missing_keys)
2634
4152.1.2 by Robert Collins
Add streaming from a stacked branch when the sort order is compatible with doing so.
2635
    def _real_stream(self, repo, search):
2636
        """Get a stream for search from repo.
6263.3.1 by Jelmer Vernooij
Some formatting fixes.
2637
2638
        This never called RemoteStreamSource.get_stream, and is a helper
2639
        for RemoteStreamSource._get_stream to allow getting a stream
4152.1.2 by Robert Collins
Add streaming from a stacked branch when the sort order is compatible with doing so.
2640
        reliably whether fallback back because of old servers or trying
2641
        to stream from a non-RemoteRepository (which the stacked support
2642
        code will do).
2643
        """
2644
        source = repo._get_source(self.to_format)
2645
        if isinstance(source, RemoteStreamSource):
4600.1.1 by Robert Collins
Fix fetching from 2a branches over bzr-v2.
2646
            repo._ensure_real()
2647
            source = repo._real_repository._get_source(self.to_format)
4152.1.2 by Robert Collins
Add streaming from a stacked branch when the sort order is compatible with doing so.
2648
        return source.get_stream(search)
2649
2650
    def _get_stream(self, repo, search):
2651
        """Core worker to get a stream from repo for search.
2652
2653
        This is used by both get_stream and the stacking support logic. It
2654
        deliberately gets a stream for repo which does not need to be
2655
        self.from_repository. In the event that repo is not Remote, or
2656
        cannot do a smart stream, a fallback is made to the generic
2657
        repository._get_stream() interface, via self._real_stream.
2658
2659
        In the event of stacking, streams from _get_stream will not
2660
        contain all the data for search - this is normal (see get_stream).
2661
2662
        :param repo: A repository.
2663
        :param search: A search.
2664
        """
2665
        # Fallbacks may be non-smart
2666
        if not isinstance(repo, RemoteRepository):
2667
            return self._real_stream(repo, search)
4060.1.4 by Robert Collins
Streaming fetch from remote servers.
2668
        client = repo._client
2669
        medium = client._medium
2670
        path = repo.bzrdir._path_for_remote_call(client)
4476.3.29 by Andrew Bennetts
Add Repository.get_stream_1.18 verb.
2671
        search_bytes = repo._serialise_search_result(search)
2672
        args = (path, self.to_format.network_name())
2673
        candidate_verbs = [
4476.3.82 by Andrew Bennetts
Mention another bug fix in NEWS, and update verb name, comments, and NEWS additions for landing on 1.19 rather than 1.18.
2674
            ('Repository.get_stream_1.19', (1, 19)),
4476.3.29 by Andrew Bennetts
Add Repository.get_stream_1.18 verb.
2675
            ('Repository.get_stream', (1, 13))]
5539.2.2 by Andrew Bennetts
Add support for 'everything' fetch spec to RemoteStreamSource.
2676
4476.3.29 by Andrew Bennetts
Add Repository.get_stream_1.18 verb.
2677
        found_verb = False
2678
        for verb, version in candidate_verbs:
2679
            if medium._is_remote_before(version):
2680
                continue
2681
            try:
2682
                response = repo._call_with_body_bytes_expecting_body(
2683
                    verb, args, search_bytes)
2684
            except errors.UnknownSmartMethod:
2685
                medium._remember_remote_is_before(version)
5539.2.14 by Andrew Bennetts
Don't add a new verb; instead just teach the client to fallback if it gets a BadSearch error.
2686
            except errors.UnknownErrorFromSmartServer, e:
2687
                if isinstance(search, graph.EverythingResult):
2688
                    error_verb = e.error_from_smart_server.error_verb
2689
                    if error_verb == 'BadSearch':
5536.3.3 by Andrew Bennetts
Merge lp:bzr.
2690
                        # Pre-2.4 servers don't support this sort of search.
5539.2.14 by Andrew Bennetts
Don't add a new verb; instead just teach the client to fallback if it gets a BadSearch error.
2691
                        # XXX: perhaps falling back to VFS on BadSearch is a
2692
                        # good idea in general?  It might provide a little bit
2693
                        # of protection against client-side bugs.
5536.3.3 by Andrew Bennetts
Merge lp:bzr.
2694
                        medium._remember_remote_is_before((2, 4))
5539.2.14 by Andrew Bennetts
Don't add a new verb; instead just teach the client to fallback if it gets a BadSearch error.
2695
                        break
2696
                raise
4476.3.29 by Andrew Bennetts
Add Repository.get_stream_1.18 verb.
2697
            else:
2698
                response_tuple, response_handler = response
2699
                found_verb = True
2700
                break
2701
        if not found_verb:
4152.1.2 by Robert Collins
Add streaming from a stacked branch when the sort order is compatible with doing so.
2702
            return self._real_stream(repo, search)
4060.1.4 by Robert Collins
Streaming fetch from remote servers.
2703
        if response_tuple[0] != 'ok':
2704
            raise errors.UnexpectedSmartServerResponse(response_tuple)
2705
        byte_stream = response_handler.read_streamed_body()
5195.3.23 by Parth Malwankar
moved progress bar logic to SourceStream.
2706
        src_format, stream = smart_repo._byte_stream_to_stream(byte_stream,
2707
            self._record_counter)
4060.1.4 by Robert Collins
Streaming fetch from remote servers.
2708
        if src_format.network_name() != repo._format.network_name():
2709
            raise AssertionError(
2710
                "Mismatched RemoteRepository and stream src %r, %r" % (
2711
                src_format.network_name(), repo._format.network_name()))
2712
        return stream
2713
4152.1.2 by Robert Collins
Add streaming from a stacked branch when the sort order is compatible with doing so.
2714
    def missing_parents_chain(self, search, sources):
2715
        """Chain multiple streams together to handle stacking.
2716
2717
        :param search: The overall search to satisfy with streams.
2718
        :param sources: A list of Repository objects to query.
2719
        """
4634.61.2 by Andrew Bennetts
Variable rename suggested by Robert.
2720
        self.from_serialiser = self.from_repository._format._serializer
4152.1.2 by Robert Collins
Add streaming from a stacked branch when the sort order is compatible with doing so.
2721
        self.seen_revs = set()
2722
        self.referenced_revs = set()
2723
        # If there are heads in the search, or the key count is > 0, we are not
2724
        # done.
2725
        while not search.is_empty() and len(sources) > 1:
2726
            source = sources.pop(0)
2727
            stream = self._get_stream(source, search)
2728
            for kind, substream in stream:
2729
                if kind != 'revisions':
2730
                    yield kind, substream
2731
                else:
2732
                    yield kind, self.missing_parents_rev_handler(substream)
2733
            search = search.refine(self.seen_revs, self.referenced_revs)
2734
            self.seen_revs = set()
2735
            self.referenced_revs = set()
2736
        if not search.is_empty():
2737
            for kind, stream in self._get_stream(sources[0], search):
2738
                yield kind, stream
2739
2740
    def missing_parents_rev_handler(self, substream):
2741
        for content in substream:
2742
            revision_bytes = content.get_bytes_as('fulltext')
4634.61.2 by Andrew Bennetts
Variable rename suggested by Robert.
2743
            revision = self.from_serialiser.read_revision_from_string(
2744
                revision_bytes)
4152.1.2 by Robert Collins
Add streaming from a stacked branch when the sort order is compatible with doing so.
2745
            self.seen_revs.add(content.key[-1])
2746
            self.referenced_revs.update(revision.parent_ids)
2747
            yield content
2748
4060.1.3 by Robert Collins
Implement the separate source component for fetch - repository.StreamSource.
2749
2018.5.127 by Andrew Bennetts
Fix most of the lockable_files tests for RemoteBranchLockableFiles.
2750
class RemoteBranchLockableFiles(LockableFiles):
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
2751
    """A 'LockableFiles' implementation that talks to a smart server.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
2752
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
2753
    This is not a public interface class.
2754
    """
2755
2756
    def __init__(self, bzrdir, _client):
2757
        self.bzrdir = bzrdir
2758
        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.
2759
        self._need_find_modes = True
2018.5.133 by Andrew Bennetts
All TestLockableFiles_RemoteLockDir tests passing.
2760
        LockableFiles.__init__(
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
2761
            self, bzrdir.get_branch_transport(None),
2018.5.133 by Andrew Bennetts
All TestLockableFiles_RemoteLockDir tests passing.
2762
            'lock', lockdir.LockDir)
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
2763
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.
2764
    def _find_modes(self):
2765
        # RemoteBranches don't let the client set the mode of control files.
2766
        self._dir_mode = None
2767
        self._file_mode = None
2768
2018.5.59 by Robert Collins
Get BranchConfig working somewhat on RemoteBranches (Robert Collins, Vincent Ladeuil).
2769
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
2770
class RemoteBranchFormat(branch.BranchFormat):
2771
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
2772
    def __init__(self, network_name=None):
3834.5.2 by John Arbash Meinel
Track down the various BranchFormats that weren't setting the branch format as part of the _matchingbzrdir format.
2773
        super(RemoteBranchFormat, self).__init__()
2774
        self._matchingbzrdir = RemoteBzrDirFormat()
2775
        self._matchingbzrdir.set_branch_format(self)
4032.3.2 by Robert Collins
Create and use a RPC call to create branches on bzr servers rather than using VFS calls.
2776
        self._custom_format = None
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
2777
        self._network_name = network_name
3834.5.2 by John Arbash Meinel
Track down the various BranchFormats that weren't setting the branch format as part of the _matchingbzrdir format.
2778
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.
2779
    def __eq__(self, other):
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
2780
        return (isinstance(other, RemoteBranchFormat) and
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.
2781
            self.__dict__ == other.__dict__)
2782
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
2783
    def _ensure_real(self):
2784
        if self._custom_format is None:
6305.4.1 by Jelmer Vernooij
Print sensible error message when remote format is unknown.
2785
            try:
2786
                self._custom_format = branch.network_format_registry.get(
2787
                    self._network_name)
2788
            except KeyError:
2789
                raise errors.UnknownFormatError(kind='branch',
2790
                    format=self._network_name)
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
2791
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
2792
    def get_format_description(self):
4792.1.1 by Andrew Bennetts
Show real branch/repo format description in 'info -v' over HPSS.
2793
        self._ensure_real()
2794
        return 'Remote: ' + self._custom_format.get_format_description()
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
2795
4032.3.1 by Robert Collins
Add a BranchFormat.network_name() method as preparation for creating branches via RPC calls.
2796
    def network_name(self):
2797
        return self._network_name
2798
5051.3.10 by Jelmer Vernooij
Pass colocated branch name around in more places.
2799
    def open(self, a_bzrdir, name=None, ignore_fallbacks=False):
2800
        return a_bzrdir.open_branch(name=name, 
2801
            ignore_fallbacks=ignore_fallbacks)
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
2802
6123.9.12 by Jelmer Vernooij
Add append_revisions_only argument to BranchFormat.initialize.
2803
    def _vfs_initialize(self, a_bzrdir, name, append_revisions_only):
4032.3.2 by Robert Collins
Create and use a RPC call to create branches on bzr servers rather than using VFS calls.
2804
        # Initialisation when using a local bzrdir object, or a non-vfs init
2805
        # method is not available on the server.
2806
        # self._custom_format is always set - the start of initialize ensures
2807
        # that.
2808
        if isinstance(a_bzrdir, RemoteBzrDir):
2809
            a_bzrdir._ensure_real()
5051.3.10 by Jelmer Vernooij
Pass colocated branch name around in more places.
2810
            result = self._custom_format.initialize(a_bzrdir._real_bzrdir,
6123.9.12 by Jelmer Vernooij
Add append_revisions_only argument to BranchFormat.initialize.
2811
                name, append_revisions_only=append_revisions_only)
4032.3.2 by Robert Collins
Create and use a RPC call to create branches on bzr servers rather than using VFS calls.
2812
        else:
2813
            # We assume the bzrdir is parameterised; it may not be.
6123.9.12 by Jelmer Vernooij
Add append_revisions_only argument to BranchFormat.initialize.
2814
            result = self._custom_format.initialize(a_bzrdir, name,
2815
                append_revisions_only=append_revisions_only)
4032.3.2 by Robert Collins
Create and use a RPC call to create branches on bzr servers rather than using VFS calls.
2816
        if (isinstance(a_bzrdir, RemoteBzrDir) and
2817
            not isinstance(result, RemoteBranch)):
5051.3.10 by Jelmer Vernooij
Pass colocated branch name around in more places.
2818
            result = RemoteBranch(a_bzrdir, a_bzrdir.find_repository(), result,
2819
                                  name=name)
4032.3.2 by Robert Collins
Create and use a RPC call to create branches on bzr servers rather than using VFS calls.
2820
        return result
2821
6123.9.12 by Jelmer Vernooij
Add append_revisions_only argument to BranchFormat.initialize.
2822
    def initialize(self, a_bzrdir, name=None, repository=None,
2823
                   append_revisions_only=None):
4032.3.2 by Robert Collins
Create and use a RPC call to create branches on bzr servers rather than using VFS calls.
2824
        # 1) get the network name to use.
2825
        if self._custom_format:
2826
            network_name = self._custom_format.network_name()
2827
        else:
2828
            # Select the current bzrlib default and ask for that.
5712.3.13 by Jelmer Vernooij
Add Prober.known_formats().
2829
            reference_bzrdir_format = _mod_bzrdir.format_registry.get('default')()
4032.3.2 by Robert Collins
Create and use a RPC call to create branches on bzr servers rather than using VFS calls.
2830
            reference_format = reference_bzrdir_format.get_branch_format()
2831
            self._custom_format = reference_format
2832
            network_name = reference_format.network_name()
2833
        # Being asked to create on a non RemoteBzrDir:
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
2834
        if not isinstance(a_bzrdir, RemoteBzrDir):
6123.9.12 by Jelmer Vernooij
Add append_revisions_only argument to BranchFormat.initialize.
2835
            return self._vfs_initialize(a_bzrdir, name=name,
2836
                append_revisions_only=append_revisions_only)
4032.3.2 by Robert Collins
Create and use a RPC call to create branches on bzr servers rather than using VFS calls.
2837
        medium = a_bzrdir._client._medium
2838
        if medium._is_remote_before((1, 13)):
6123.9.12 by Jelmer Vernooij
Add append_revisions_only argument to BranchFormat.initialize.
2839
            return self._vfs_initialize(a_bzrdir, name=name,
2840
                append_revisions_only=append_revisions_only)
4032.3.2 by Robert Collins
Create and use a RPC call to create branches on bzr servers rather than using VFS calls.
2841
        # Creating on a remote bzr dir.
2842
        # 2) try direct creation via RPC
2843
        path = a_bzrdir._path_for_remote_call(a_bzrdir._client)
5051.3.10 by Jelmer Vernooij
Pass colocated branch name around in more places.
2844
        if name is not None:
5051.3.11 by Jelmer Vernooij
add XXX for creating remote colocated branches.
2845
            # XXX JRV20100304: Support creating colocated branches
5051.3.10 by Jelmer Vernooij
Pass colocated branch name around in more places.
2846
            raise errors.NoColocatedBranchSupport(self)
4032.3.2 by Robert Collins
Create and use a RPC call to create branches on bzr servers rather than using VFS calls.
2847
        verb = 'BzrDir.create_branch'
2848
        try:
2849
            response = a_bzrdir._call(verb, path, network_name)
2850
        except errors.UnknownSmartMethod:
2851
            # Fallback - use vfs methods
4094.1.1 by Andrew Bennetts
Add some medium._remember_is_before((1, 13)) calls.
2852
            medium._remember_remote_is_before((1, 13))
6123.9.12 by Jelmer Vernooij
Add append_revisions_only argument to BranchFormat.initialize.
2853
            return self._vfs_initialize(a_bzrdir, name=name,
2854
                    append_revisions_only=append_revisions_only)
4032.3.2 by Robert Collins
Create and use a RPC call to create branches on bzr servers rather than using VFS calls.
2855
        if response[0] != 'ok':
2856
            raise errors.UnexpectedSmartServerResponse(response)
2857
        # Turn the response into a RemoteRepository object.
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
2858
        format = RemoteBranchFormat(network_name=response[1])
4032.3.2 by Robert Collins
Create and use a RPC call to create branches on bzr servers rather than using VFS calls.
2859
        repo_format = response_tuple_to_repo_format(response[3:])
5536.1.1 by Andrew Bennetts
Avoid reopening (and relocking) the same branches/repositories in ControlDir.sprout. Still a few rough edges, but the tests I've run are passing.
2860
        repo_path = response[2]
2861
        if repository is not None:
5609.21.1 by Andrew Bennetts
Possible fix for #726584, plus drive-by docstring fix.
2862
            remote_repo_url = urlutils.join(a_bzrdir.user_url, repo_path)
5535.3.7 by Andrew Bennetts
Allow for trailing-slash differences between local url path vs. remote url path for remote branch's repository.
2863
            url_diff = urlutils.relative_url(repository.user_url,
2864
                    remote_repo_url)
2865
            if url_diff != '.':
5536.1.1 by Andrew Bennetts
Avoid reopening (and relocking) the same branches/repositories in ControlDir.sprout. Still a few rough edges, but the tests I've run are passing.
2866
                raise AssertionError(
5536.1.10 by Andrew Bennetts
Give more helpful message in AssertionErrors, just in case.
2867
                    'repository.user_url %r does not match URL from server '
2868
                    'response (%r + %r)'
5609.21.1 by Andrew Bennetts
Possible fix for #726584, plus drive-by docstring fix.
2869
                    % (repository.user_url, a_bzrdir.user_url, repo_path))
5536.1.1 by Andrew Bennetts
Avoid reopening (and relocking) the same branches/repositories in ControlDir.sprout. Still a few rough edges, but the tests I've run are passing.
2870
            remote_repo = repository
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
2871
        else:
5536.1.1 by Andrew Bennetts
Avoid reopening (and relocking) the same branches/repositories in ControlDir.sprout. Still a few rough edges, but the tests I've run are passing.
2872
            if repo_path == '':
2873
                repo_bzrdir = a_bzrdir
2874
            else:
2875
                repo_bzrdir = RemoteBzrDir(
2876
                    a_bzrdir.root_transport.clone(repo_path), a_bzrdir._format,
2877
                    a_bzrdir._client)
2878
            remote_repo = RemoteRepository(repo_bzrdir, repo_format)
4032.3.2 by Robert Collins
Create and use a RPC call to create branches on bzr servers rather than using VFS calls.
2879
        remote_branch = RemoteBranch(a_bzrdir, remote_repo,
5051.3.10 by Jelmer Vernooij
Pass colocated branch name around in more places.
2880
            format=format, setup_stacking=False, name=name)
6123.9.12 by Jelmer Vernooij
Add append_revisions_only argument to BranchFormat.initialize.
2881
        if append_revisions_only:
2882
            remote_branch.set_append_revisions_only(append_revisions_only)
4044.1.4 by Robert Collins
Remove a wasted round trip determining the revno and revid of a newly created branch.
2883
        # XXX: We know this is a new branch, so it must have revno 0, revid
2884
        # NULL_REVISION. Creating the branch locked would make this be unable
2885
        # to be wrong; here its simply very unlikely to be wrong. RBC 20090225
2886
        remote_branch._last_revision_info_cache = 0, NULL_REVISION
4032.3.2 by Robert Collins
Create and use a RPC call to create branches on bzr servers rather than using VFS calls.
2887
        return remote_branch
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
2888
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
2889
    def make_tags(self, branch):
2890
        self._ensure_real()
2891
        return self._custom_format.make_tags(branch)
2892
2696.3.6 by Martin Pool
Mark RemoteBranch as (possibly) supporting tags
2893
    def supports_tags(self):
2894
        # Remote branches might support tags, but we won't know until we
2895
        # access the real remote branch.
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
2896
        self._ensure_real()
2897
        return self._custom_format.supports_tags()
2696.3.6 by Martin Pool
Mark RemoteBranch as (possibly) supporting tags
2898
4103.2.2 by Andrew Bennetts
Fix RemoteBranchFormat.supports_stacking()
2899
    def supports_stacking(self):
2900
        self._ensure_real()
2901
        return self._custom_format.supports_stacking()
2902
4301.3.3 by Andrew Bennetts
Move check onto base Branch class, and add a supports_set_append_revisions_only method to BranchFormat, as suggested by Robert.
2903
    def supports_set_append_revisions_only(self):
2904
        self._ensure_real()
2905
        return self._custom_format.supports_set_append_revisions_only()
2906
5672.1.7 by Andrew Bennetts
Use a more explicit method name.
2907
    def _use_default_local_heads_to_fetch(self):
5672.1.4 by Andrew Bennetts
Fix final bzr-loom test by adding RemoteBranch.heads_to_fetch that can ask the remote branch for the heads to fetch (but uses the cheaper default logic if it knows the remote format has an identical heads_to_fetch as Branch.heads_to_fetch).
2908
        # If the branch format is a metadir format *and* its heads_to_fetch
2909
        # implementation is not overridden vs the base class, we can use the
2910
        # base class logic rather than use the heads_to_fetch RPC.  This is
5672.1.5 by Andrew Bennetts
Add some tests for RemoteBranch.heads_to_fetch, and add release-note.
2911
        # usually cheaper in terms of net round trips, as the last-revision and
5672.1.4 by Andrew Bennetts
Fix final bzr-loom test by adding RemoteBranch.heads_to_fetch that can ask the remote branch for the heads to fetch (but uses the cheaper default logic if it knows the remote format has an identical heads_to_fetch as Branch.heads_to_fetch).
2912
        # tags info fetched is cached and would be fetched anyway.
2913
        self._ensure_real()
2914
        if isinstance(self._custom_format, branch.BranchFormatMetadir):
2915
            branch_class = self._custom_format._branch_class()
2916
            heads_to_fetch_impl = branch_class.heads_to_fetch.im_func
2917
            if heads_to_fetch_impl is branch.Branch.heads_to_fetch.im_func:
2918
                return True
2919
        return False
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
2920
6263.3.1 by Jelmer Vernooij
Some formatting fixes.
2921
6270.1.6 by Jelmer Vernooij
Provide RemoteControlStore and RemoteBranchStore.
2922
class RemoteBranchStore(config.IniFileStore):
2923
    """Branch store which attempts to use HPSS calls to retrieve branch store.
2924
2925
    Note that this is specific to bzr-based formats.
2926
    """
2927
2928
    def __init__(self, branch):
2929
        super(RemoteBranchStore, self).__init__()
2930
        self.branch = branch
6270.1.14 by Jelmer Vernooij
Set RemoteBranchStore.id.
2931
        self.id = "branch"
6270.1.7 by Jelmer Vernooij
Use _ensure_real.
2932
        self._real_store = None
6270.1.6 by Jelmer Vernooij
Provide RemoteControlStore and RemoteBranchStore.
2933
2934
    def lock_write(self, token=None):
2935
        return self.branch.lock_write(token)
2936
2937
    def unlock(self):
2938
        return self.branch.unlock()
2939
2940
    @needs_write_lock
2941
    def save(self):
2942
        # We need to be able to override the undecorated implementation
2943
        self.save_without_locking()
2944
2945
    def save_without_locking(self):
2946
        super(RemoteBranchStore, self).save()
2947
2948
    def external_url(self):
6270.1.15 by Jelmer Vernooij
Implement sensible .external_url().
2949
        return self.branch.user_url
6270.1.6 by Jelmer Vernooij
Provide RemoteControlStore and RemoteBranchStore.
2950
2951
    def _load_content(self):
2952
        path = self.branch._remote_path()
2953
        try:
6270.1.10 by Jelmer Vernooij
Fix testing Branch.set_config_file.
2954
            response, handler = self.branch._call_expecting_body(
6270.1.6 by Jelmer Vernooij
Provide RemoteControlStore and RemoteBranchStore.
2955
                'Branch.get_config_file', path)
2956
        except errors.UnknownSmartMethod:
6270.1.7 by Jelmer Vernooij
Use _ensure_real.
2957
            self._ensure_real()
2958
            return self._real_store._load_content()
6270.1.6 by Jelmer Vernooij
Provide RemoteControlStore and RemoteBranchStore.
2959
        if len(response) and response[0] != 'ok':
2960
            raise errors.UnexpectedSmartServerResponse(response)
2961
        return handler.read_body_bytes()
2962
2963
    def _save_content(self, content):
6270.1.7 by Jelmer Vernooij
Use _ensure_real.
2964
        path = self.branch._remote_path()
2965
        try:
6270.1.18 by Jelmer Vernooij
Fix a test.
2966
            response, handler = self.branch._call_with_body_bytes_expecting_body(
6270.1.17 by Jelmer Vernooij
s/set_config_file/put_config_file.
2967
                'Branch.put_config_file', (path,
6270.1.10 by Jelmer Vernooij
Fix testing Branch.set_config_file.
2968
                    self.branch._lock_token, self.branch._repo_lock_token),
2969
                content)
6270.1.7 by Jelmer Vernooij
Use _ensure_real.
2970
        except errors.UnknownSmartMethod:
2971
            self._ensure_real()
2972
            return self._real_store._save_content(content)
6270.1.18 by Jelmer Vernooij
Fix a test.
2973
        handler.cancel_read_body()
6270.1.16 by Jelmer Vernooij
Expect 'ok' response from set_config_file.
2974
        if response != ('ok', ):
6270.1.7 by Jelmer Vernooij
Use _ensure_real.
2975
            raise errors.UnexpectedSmartServerResponse(response)
2976
2977
    def _ensure_real(self):
2978
        self.branch._ensure_real()
6270.1.8 by Jelmer Vernooij
Fix RemoteControlStore.
2979
        if self._real_store is None:
2980
            self._real_store = config.BranchStore(self.branch)
6270.1.6 by Jelmer Vernooij
Provide RemoteControlStore and RemoteBranchStore.
2981
2982
4731.1.2 by Andrew Bennetts
Refactor to reduce duplication.
2983
class RemoteBranch(branch.Branch, _RpcHelper, lock._RelockDebugMixin):
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
2984
    """Branch stored on a server accessed by HPSS RPC.
2985
2986
    At the moment most operations are mapped down to simple file operations.
2987
    """
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
2988
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
2989
    def __init__(self, remote_bzrdir, remote_repository, real_branch=None,
6305.3.6 by Jelmer Vernooij
Pass possible_transports along for remote branches.
2990
        _client=None, format=None, setup_stacking=True, name=None,
2991
        possible_transports=None):
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
2992
        """Create a RemoteBranch instance.
2993
2994
        :param real_branch: An optional local implementation of the branch
2995
            format, usually accessing the data via the VFS.
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
2996
        :param _client: Private parameter for testing.
4032.3.2 by Robert Collins
Create and use a RPC call to create branches on bzr servers rather than using VFS calls.
2997
        :param format: A RemoteBranchFormat object, None to create one
2998
            automatically. If supplied it should have a network_name already
2999
            supplied.
3000
        :param setup_stacking: If True make an RPC call to determine the
3001
            stacked (or not) status of the branch. If False assume the branch
3002
            is not stacked.
5051.3.10 by Jelmer Vernooij
Pass colocated branch name around in more places.
3003
        :param name: Colocated branch name
2018.5.34 by Robert Collins
Get test_remote.BasicRemoteObjectTests.test_open_remote_branch passing by implementing a remote method BzrDir.find_repository.
3004
        """
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
3005
        # We intentionally don't call the parent class's __init__, because it
3006
        # will try to assign to self.tags, which is a property in this subclass.
3007
        # And the parent's __init__ doesn't do much anyway.
1752.2.64 by Andrew Bennetts
Improve how RemoteBzrDir.open_branch works to handle references and not double-open repositories.
3008
        self.bzrdir = remote_bzrdir
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
3009
        if _client is not None:
3010
            self._client = _client
3011
        else:
3313.2.1 by Andrew Bennetts
Change _SmartClient's API to accept a medium and a base, rather than a _SharedConnection.
3012
            self._client = remote_bzrdir._client
1752.2.64 by Andrew Bennetts
Improve how RemoteBzrDir.open_branch works to handle references and not double-open repositories.
3013
        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.
3014
        if real_branch is not None:
3015
            self._real_branch = real_branch
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
3016
            # Give the remote repository the matching real repo.
2018.5.97 by Andrew Bennetts
Fix more tests.
3017
            real_repo = self._real_branch.repository
3018
            if isinstance(real_repo, RemoteRepository):
3019
                real_repo._ensure_real()
3020
                real_repo = real_repo._real_repository
3021
            self.repository._set_real_repository(real_repo)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
3022
            # Give the branch the remote repository to let fast-pathing happen.
3023
            self._real_branch.repository = self.repository
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
3024
        else:
3025
            self._real_branch = None
4031.3.3 by Matt Nordhoff
Review tweaks from Ben Finney
3026
        # Fill out expected attributes of branch for bzrlib API users.
4419.2.2 by Andrew Bennetts
Read lock branch_from in cmd_pull, avoids refetching last_revision_info and so reduces test_pull acceptance ratchet.
3027
        self._clear_cached_state()
5158.6.9 by Martin Pool
Simplify various code to use user_url
3028
        # TODO: deprecate self.base in favor of user_url
3029
        self.base = self.bzrdir.user_url
5051.3.10 by Jelmer Vernooij
Pass colocated branch name around in more places.
3030
        self._name = name
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.
3031
        self._control_files = None
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
3032
        self._lock_mode = None
3033
        self._lock_token = None
2892.2.1 by Andrew Bennetts
Add Branch.set_last_revision_info smart method, and make the RemoteBranch client use it.
3034
        self._repo_lock_token = None
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
3035
        self._lock_count = 0
3036
        self._leave_lock = False
4032.3.2 by Robert Collins
Create and use a RPC call to create branches on bzr servers rather than using VFS calls.
3037
        # Setup a format: note that we cannot call _ensure_real until all the
3038
        # attributes above are set: This code cannot be moved higher up in this
3039
        # function.
3040
        if format is None:
3041
            self._format = RemoteBranchFormat()
3042
            if real_branch is not None:
3043
                self._format._network_name = \
3044
                    self._real_branch._format.network_name()
4032.3.1 by Robert Collins
Add a BranchFormat.network_name() method as preparation for creating branches via RPC calls.
3045
        else:
4032.3.2 by Robert Collins
Create and use a RPC call to create branches on bzr servers rather than using VFS calls.
3046
            self._format = format
4600.2.1 by Robert Collins
Make RemoteBranch honour ignore_fallbacks when _ensure_real is triggered.
3047
        # when we do _ensure_real we may need to pass ignore_fallbacks to the
3048
        # branch.open_branch method.
3049
        self._real_ignore_fallbacks = not setup_stacking
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
3050
        if not self._format._network_name:
3051
            # Did not get from open_branchV2 - old server.
3052
            self._ensure_real()
3053
            self._format._network_name = \
3054
                self._real_branch._format.network_name()
3055
        self.tags = self._format.make_tags(self)
3681.1.2 by Robert Collins
Adjust for trunk.
3056
        # The base class init is not called, so we duplicate this:
3681.1.1 by Robert Collins
Create a new hook Branch.open. (Robert Collins)
3057
        hooks = branch.Branch.hooks['open']
3058
        for hook in hooks:
3059
            hook(self)
4419.1.3 by Andrew Bennetts
Quick fix by using self._ensure_real.
3060
        self._is_stacked = False
4032.3.2 by Robert Collins
Create and use a RPC call to create branches on bzr servers rather than using VFS calls.
3061
        if setup_stacking:
6305.3.6 by Jelmer Vernooij
Pass possible_transports along for remote branches.
3062
            self._setup_stacking(possible_transports)
3691.2.1 by Martin Pool
RemoteBranch must configure stacking into the repository
3063
6305.3.6 by Jelmer Vernooij
Pass possible_transports along for remote branches.
3064
    def _setup_stacking(self, possible_transports):
3691.2.1 by Martin Pool
RemoteBranch must configure stacking into the repository
3065
        # configure stacking into the remote repository, by reading it from
3691.2.3 by Martin Pool
Factor out RemoteBranch._remote_path() and disable RemoteBranch stacking
3066
        # the vfs branch.
3691.2.1 by Martin Pool
RemoteBranch must configure stacking into the repository
3067
        try:
3068
            fallback_url = self.get_stacked_on_url()
3069
        except (errors.NotStacked, errors.UnstackableBranchFormat,
3070
            errors.UnstackableRepositoryFormat), e:
3691.2.7 by Martin Pool
FakeClient can know what calls to expect
3071
            return
4419.1.3 by Andrew Bennetts
Quick fix by using self._ensure_real.
3072
        self._is_stacked = True
6305.3.6 by Jelmer Vernooij
Pass possible_transports along for remote branches.
3073
        if possible_transports is None:
3074
            possible_transports = []
3075
        else:
3076
            possible_transports = list(possible_transports)
3077
        possible_transports.append(self.bzrdir.root_transport)
6305.3.3 by Jelmer Vernooij
Fix use of possible_transports.
3078
        self._activate_fallback_location(fallback_url,
6305.3.6 by Jelmer Vernooij
Pass possible_transports along for remote branches.
3079
            possible_transports=possible_transports)
1752.2.64 by Andrew Bennetts
Improve how RemoteBzrDir.open_branch works to handle references and not double-open repositories.
3080
4226.1.5 by Robert Collins
Reinstate the use of the Branch.get_config_file verb.
3081
    def _get_config(self):
3082
        return RemoteBranchConfig(self)
3083
6270.1.19 by Jelmer Vernooij
Some changes discussed with vila on IRC.
3084
    def _get_config_store(self):
3085
        return RemoteBranchStore(self)
6270.1.4 by Jelmer Vernooij
Add Branch.get_config_stack / BzrDir.get_config_stack.
3086
3407.2.17 by Martin Pool
better name: _get_real_transport
3087
    def _get_real_transport(self):
3407.2.16 by Martin Pool
Remove RemoteBranch reliance on control_files._transport
3088
        # if we try vfs access, return the real branch's vfs transport
3089
        self._ensure_real()
3090
        return self._real_branch._transport
3091
3407.2.17 by Martin Pool
better name: _get_real_transport
3092
    _transport = property(_get_real_transport)
3407.2.16 by Martin Pool
Remove RemoteBranch reliance on control_files._transport
3093
2477.1.1 by Martin Pool
Add RemoteBranch repr
3094
    def __str__(self):
3095
        return "%s(%s)" % (self.__class__.__name__, self.base)
3096
3097
    __repr__ = __str__
3098
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
3099
    def _ensure_real(self):
3100
        """Ensure that there is a _real_branch set.
3101
2018.5.163 by Andrew Bennetts
Deal with various review comments from Robert.
3102
        Used before calls to self._real_branch.
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
3103
        """
3407.2.16 by Martin Pool
Remove RemoteBranch reliance on control_files._transport
3104
        if self._real_branch is None:
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
3105
            if not vfs.vfs_enabled():
3106
                raise AssertionError('smart server vfs must be enabled '
3107
                    'to use vfs implementation')
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
3108
            self.bzrdir._ensure_real()
4600.2.1 by Robert Collins
Make RemoteBranch honour ignore_fallbacks when _ensure_real is triggered.
3109
            self._real_branch = self.bzrdir._real_bzrdir.open_branch(
5051.3.10 by Jelmer Vernooij
Pass colocated branch name around in more places.
3110
                ignore_fallbacks=self._real_ignore_fallbacks, name=self._name)
3692.1.3 by Andrew Bennetts
Delete some cruft (like the _ensure_real call in RemoteBranch.lock_write), improve some comments, and wrap some long lines.
3111
            if self.repository._real_repository is None:
3112
                # Give the remote repository the matching real repo.
3113
                real_repo = self._real_branch.repository
3114
                if isinstance(real_repo, RemoteRepository):
3115
                    real_repo._ensure_real()
3116
                    real_repo = real_repo._real_repository
3117
                self.repository._set_real_repository(real_repo)
3118
            # Give the real branch the remote repository to let fast-pathing
3119
            # happen.
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
3120
            self._real_branch.repository = self.repository
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
3121
            if self._lock_mode == 'r':
3122
                self._real_branch.lock_read()
3692.1.3 by Andrew Bennetts
Delete some cruft (like the _ensure_real call in RemoteBranch.lock_write), improve some comments, and wrap some long lines.
3123
            elif self._lock_mode == 'w':
3124
                self._real_branch.lock_write(token=self._lock_token)
2018.5.70 by Robert Collins
Only try to get real repositories when an operation requires them.
3125
3533.3.1 by Andrew Bennetts
Remove duplication of error translation in bzrlib/remote.py.
3126
    def _translate_error(self, err, **context):
3127
        self.repository._translate_error(err, branch=self, **context)
3128
3441.5.1 by Andrew Bennetts
Avoid necessarily calling get_parent_map when pushing.
3129
    def _clear_cached_state(self):
3130
        super(RemoteBranch, self)._clear_cached_state()
3441.5.5 by Andrew Bennetts
Some small tweaks and comments.
3131
        if self._real_branch is not None:
3132
            self._real_branch._clear_cached_state()
3441.5.29 by Andrew Bennetts
More review tweaks: whitespace nits in test_smart, add (and use) ._clear_cached_state_of_remote_branch_only method in bzrlib/remote.py.
3133
3134
    def _clear_cached_state_of_remote_branch_only(self):
3135
        """Like _clear_cached_state, but doesn't clear the cache of
3136
        self._real_branch.
3137
3138
        This is useful when falling back to calling a method of
3139
        self._real_branch that changes state.  In that case the underlying
3140
        branch changes, so we need to invalidate this RemoteBranch's cache of
3141
        it.  However, there's no need to invalidate the _real_branch's cache
3142
        too, in fact doing so might harm performance.
3143
        """
3144
        super(RemoteBranch, self)._clear_cached_state()
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
3145
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.
3146
    @property
3147
    def control_files(self):
3148
        # Defer actually creating RemoteBranchLockableFiles until its needed,
3149
        # because it triggers an _ensure_real that we otherwise might not need.
3150
        if self._control_files is None:
3151
            self._control_files = RemoteBranchLockableFiles(
3152
                self.bzrdir, self._client)
3153
        return self._control_files
3154
6127.1.9 by Jelmer Vernooij
Add lightweight option to _get_checkout_format().
3155
    def _get_checkout_format(self, lightweight=False):
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
3156
        self._ensure_real()
6127.1.9 by Jelmer Vernooij
Add lightweight option to _get_checkout_format().
3157
        if lightweight:
3158
            format = RemoteBzrDirFormat()
3159
            self.bzrdir._format._supply_sub_formats_to(format)
3160
            format.workingtree_format = self._real_branch._get_checkout_format(
3161
                lightweight=lightweight).workingtree_format
3162
            return format
3163
        else:
3164
            return self._real_branch._get_checkout_format(lightweight=False)
2018.5.166 by Andrew Bennetts
Small changes in response to Aaron's review.
3165
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
3166
    def get_physical_lock_status(self):
3167
        """See Branch.get_physical_lock_status()."""
6280.6.1 by Jelmer Vernooij
Implement remote side of {Branch,Repository}.get_physical_lock_status.
3168
        try:
3169
            response = self._client.call('Branch.get_physical_lock_status',
3170
                self._remote_path())
3171
        except errors.UnknownSmartMethod:
3172
            self._ensure_real()
3173
            return self._real_branch.get_physical_lock_status()
3174
        if response[0] not in ('yes', 'no'):
3175
            raise errors.UnexpectedSmartServerResponse(response)
3176
        return (response[0] == 'yes')
2018.5.60 by Robert Collins
More missing methods from RemoteBranch and RemoteRepository to let 'info' get further.
3177
3537.3.1 by Martin Pool
Rename branch.get_stacked_on to get_stacked_on_url
3178
    def get_stacked_on_url(self):
3221.11.2 by Robert Collins
Create basic stackable branch facility.
3179
        """Get the URL this branch is stacked against.
3180
3181
        :raises NotStacked: If the branch is not stacked.
3182
        :raises UnstackableBranchFormat: If the branch does not support
3183
            stacking.
3184
        :raises UnstackableRepositoryFormat: If the repository does not support
3185
            stacking.
3186
        """
3691.2.12 by Martin Pool
Add test for coping without Branch.get_stacked_on_url
3187
        try:
3786.2.3 by Andrew Bennetts
Remove duplicated 'call & translate errors' code in bzrlib.remote.
3188
            # there may not be a repository yet, so we can't use
3189
            # self._translate_error, so we can't use self._call either.
3691.2.12 by Martin Pool
Add test for coping without Branch.get_stacked_on_url
3190
            response = self._client.call('Branch.get_stacked_on_url',
3191
                self._remote_path())
3192
        except errors.ErrorFromSmartServer, err:
3193
            # there may not be a repository yet, so we can't call through
3194
            # its _translate_error
3195
            _translate_error(err, branch=self)
3196
        except errors.UnknownSmartMethod, err:
3197
            self._ensure_real()
3198
            return self._real_branch.get_stacked_on_url()
3786.2.3 by Andrew Bennetts
Remove duplicated 'call & translate errors' code in bzrlib.remote.
3199
        if response[0] != 'ok':
3200
            raise errors.UnexpectedSmartServerResponse(response)
3201
        return response[1]
3221.11.2 by Robert Collins
Create basic stackable branch facility.
3202
4419.1.3 by Andrew Bennetts
Quick fix by using self._ensure_real.
3203
    def set_stacked_on_url(self, url):
3204
        branch.Branch.set_stacked_on_url(self, url)
3205
        if not url:
3206
            self._is_stacked = False
3207
        else:
3208
            self._is_stacked = True
5712.3.13 by Jelmer Vernooij
Add Prober.known_formats().
3209
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
3210
    def _vfs_get_tags_bytes(self):
3211
        self._ensure_real()
3212
        return self._real_branch._get_tags_bytes()
3213
5535.2.1 by Andrew Bennetts
Cache a branch's tags during a read-lock.
3214
    @needs_read_lock
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
3215
    def _get_tags_bytes(self):
5535.2.1 by Andrew Bennetts
Cache a branch's tags during a read-lock.
3216
        if self._tags_bytes is None:
3217
            self._tags_bytes = self._get_tags_bytes_via_hpss()
3218
        return self._tags_bytes
3219
3220
    def _get_tags_bytes_via_hpss(self):
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
3221
        medium = self._client._medium
3222
        if medium._is_remote_before((1, 13)):
3223
            return self._vfs_get_tags_bytes()
3224
        try:
3225
            response = self._call('Branch.get_tags_bytes', self._remote_path())
3226
        except errors.UnknownSmartMethod:
4094.1.1 by Andrew Bennetts
Add some medium._remember_is_before((1, 13)) calls.
3227
            medium._remember_remote_is_before((1, 13))
4084.2.1 by Robert Collins
Make accessing a branch.tags.get_tag_dict use a smart[er] method rather than VFS calls and real objects.
3228
            return self._vfs_get_tags_bytes()
3229
        return response[0]
3230
4556.2.10 by Andrew Bennetts
Fix trivial bug in _vfs_set_tags_bytes.
3231
    def _vfs_set_tags_bytes(self, bytes):
4556.2.1 by Andrew Bennetts
Add Branch.set_tags_bytes RPC, with HPSS call count acceptance test. Also fixes serialisation of LockDir, and uses external_url() in LockDir's repr and contention message.
3232
        self._ensure_real()
4556.2.10 by Andrew Bennetts
Fix trivial bug in _vfs_set_tags_bytes.
3233
        return self._real_branch._set_tags_bytes(bytes)
4556.2.1 by Andrew Bennetts
Add Branch.set_tags_bytes RPC, with HPSS call count acceptance test. Also fixes serialisation of LockDir, and uses external_url() in LockDir's repr and contention message.
3234
3235
    def _set_tags_bytes(self, bytes):
5535.2.3 by Andrew Bennetts
Reset cached tags when mutating tags.
3236
        if self.is_locked():
3237
            self._tags_bytes = bytes
4556.2.1 by Andrew Bennetts
Add Branch.set_tags_bytes RPC, with HPSS call count acceptance test. Also fixes serialisation of LockDir, and uses external_url() in LockDir's repr and contention message.
3238
        medium = self._client._medium
3239
        if medium._is_remote_before((1, 18)):
3240
            self._vfs_set_tags_bytes(bytes)
4634.36.1 by Andrew Bennetts
Fix trivial bug in RemoteBranch._set_tags_bytes, and add some unit tests for it.
3241
            return
4556.2.1 by Andrew Bennetts
Add Branch.set_tags_bytes RPC, with HPSS call count acceptance test. Also fixes serialisation of LockDir, and uses external_url() in LockDir's repr and contention message.
3242
        try:
3243
            args = (
3244
                self._remote_path(), self._lock_token, self._repo_lock_token)
3245
            response = self._call_with_body_bytes(
3246
                'Branch.set_tags_bytes', args, bytes)
3247
        except errors.UnknownSmartMethod:
3248
            medium._remember_remote_is_before((1, 18))
3249
            self._vfs_set_tags_bytes(bytes)
3250
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
3251
    def lock_read(self):
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
3252
        """Lock the branch for read operations.
3253
5200.3.6 by Robert Collins
Make all lock methods return Result objects, rather than lock_read returning self, as per John's review.
3254
        :return: A bzrlib.lock.LogicalLockResult.
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
3255
        """
3692.1.1 by Andrew Bennetts
Make RemoteBranch.lock_write lock the repository too.
3256
        self.repository.lock_read()
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
3257
        if not self._lock_mode:
4731.1.2 by Andrew Bennetts
Refactor to reduce duplication.
3258
            self._note_lock('r')
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
3259
            self._lock_mode = 'r'
3260
            self._lock_count = 1
3261
            if self._real_branch is not None:
3262
                self._real_branch.lock_read()
3263
        else:
3264
            self._lock_count += 1
5200.3.6 by Robert Collins
Make all lock methods return Result objects, rather than lock_read returning self, as per John's review.
3265
        return lock.LogicalLockResult(self.unlock)
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
3266
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).
3267
    def _remote_lock_write(self, token):
3268
        if token is None:
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
3269
            branch_token = repo_token = ''
3270
        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).
3271
            branch_token = token
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
3272
            repo_token = self.repository.lock_write().repository_token
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).
3273
            self.repository.unlock()
3786.2.3 by Andrew Bennetts
Remove duplicated 'call & translate errors' code in bzrlib.remote.
3274
        err_context = {'token': token}
5284.6.1 by Parth Malwankar
initial implementation for better LockContention message.
3275
        try:
3276
            response = self._call(
3277
                'Branch.lock_write', self._remote_path(), branch_token,
3278
                repo_token or '', **err_context)
3279
        except errors.LockContention, e:
5284.6.3 by Parth Malwankar
fixed tests. closed review comments by mgz.
3280
            # The LockContention from the server doesn't have any
3281
            # information about the lock_url. We re-raise LockContention
3282
            # with valid lock_url.
3283
            raise errors.LockContention('(remote lock)',
3284
                self.repository.base.split('.bzr/')[0])
3245.4.24 by Andrew Bennetts
Consistently raise errors from the server as ErrorFromSmartServer exceptions.
3285
        if response[0] != 'ok':
2555.1.1 by Martin Pool
Remove use of 'assert False' to raise an exception unconditionally
3286
            raise errors.UnexpectedSmartServerResponse(response)
3245.4.24 by Andrew Bennetts
Consistently raise errors from the server as ErrorFromSmartServer exceptions.
3287
        ok, branch_token, repo_token = response
3288
        return branch_token, repo_token
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
3289
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).
3290
    def lock_write(self, token=None):
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
3291
        if not self._lock_mode:
4731.1.2 by Andrew Bennetts
Refactor to reduce duplication.
3292
            self._note_lock('w')
3692.1.3 by Andrew Bennetts
Delete some cruft (like the _ensure_real call in RemoteBranch.lock_write), improve some comments, and wrap some long lines.
3293
            # Lock the branch and repo in one remote call.
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).
3294
            remote_tokens = self._remote_lock_write(token)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
3295
            self._lock_token, self._repo_lock_token = remote_tokens
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
3296
            if not self._lock_token:
3297
                raise SmartProtocolError('Remote server did not return a token!')
3692.1.3 by Andrew Bennetts
Delete some cruft (like the _ensure_real call in RemoteBranch.lock_write), improve some comments, and wrap some long lines.
3298
            # Tell the self.repository object that it is locked.
3692.1.2 by Andrew Bennetts
Fix regression introduced by fix, and add a test for that regression.
3299
            self.repository.lock_write(
3300
                self._repo_lock_token, _skip_rpc=True)
3692.1.1 by Andrew Bennetts
Make RemoteBranch.lock_write lock the repository too.
3301
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
3302
            if self._real_branch is not None:
3692.1.5 by Andrew Bennetts
Fix bug revealed by removing _ensure_real call from RemoteBranch.lock_write.
3303
                self._real_branch.lock_write(token=self._lock_token)
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).
3304
            if token is not None:
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
3305
                self._leave_lock = True
3306
            else:
3307
                self._leave_lock = False
3308
            self._lock_mode = 'w'
3309
            self._lock_count = 1
3310
        elif self._lock_mode == 'r':
5241.1.1 by Andrew Bennetts
Fix AttributeError in RemoteBranch.lock_write after lock_read.
3311
            raise errors.ReadOnlyError(self)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
3312
        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).
3313
            if token is not None:
3692.1.3 by Andrew Bennetts
Delete some cruft (like the _ensure_real call in RemoteBranch.lock_write), improve some comments, and wrap some long lines.
3314
                # A token was given to lock_write, and we're relocking, so
3315
                # check that the given token actually matches the one we
3316
                # already have.
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).
3317
                if token != self._lock_token:
3318
                    raise errors.TokenMismatch(token, self._lock_token)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
3319
            self._lock_count += 1
3692.1.3 by Andrew Bennetts
Delete some cruft (like the _ensure_real call in RemoteBranch.lock_write), improve some comments, and wrap some long lines.
3320
            # Re-lock the repository too.
3692.1.2 by Andrew Bennetts
Fix regression introduced by fix, and add a test for that regression.
3321
            self.repository.lock_write(self._repo_lock_token)
5200.3.3 by Robert Collins
Lock methods on ``Tree``, ``Branch`` and ``Repository`` are now
3322
        return BranchWriteLockResult(self.unlock, self._lock_token or None)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
3323
3324
    def _unlock(self, branch_token, repo_token):
3786.2.3 by Andrew Bennetts
Remove duplicated 'call & translate errors' code in bzrlib.remote.
3325
        err_context = {'token': str((branch_token, repo_token))}
3326
        response = self._call(
3327
            'Branch.unlock', self._remote_path(), branch_token,
3328
            repo_token or '', **err_context)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
3329
        if response == ('ok',):
3330
            return
3245.4.24 by Andrew Bennetts
Consistently raise errors from the server as ErrorFromSmartServer exceptions.
3331
        raise errors.UnexpectedSmartServerResponse(response)
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
3332
4634.85.9 by Andrew Bennetts
Add some experimental decorators: @only_raises(..) and @cleanup_method.
3333
    @only_raises(errors.LockNotHeld, errors.LockBroken)
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
3334
    def unlock(self):
3692.1.1 by Andrew Bennetts
Make RemoteBranch.lock_write lock the repository too.
3335
        try:
3336
            self._lock_count -= 1
3337
            if not self._lock_count:
3338
                self._clear_cached_state()
3339
                mode = self._lock_mode
3340
                self._lock_mode = None
3341
                if self._real_branch is not None:
3342
                    if (not self._leave_lock and mode == 'w' and
3343
                        self._repo_lock_token):
3344
                        # If this RemoteBranch will remove the physical lock
3345
                        # for the repository, make sure the _real_branch
3346
                        # doesn't do it first.  (Because the _real_branch's
3347
                        # repository is set to be the RemoteRepository.)
3348
                        self._real_branch.repository.leave_lock_in_place()
3349
                    self._real_branch.unlock()
3350
                if mode != 'w':
3351
                    # Only write-locked branched need to make a remote method
4031.3.1 by Frank Aspell
Fixing various typos
3352
                    # call to perform the unlock.
3692.1.1 by Andrew Bennetts
Make RemoteBranch.lock_write lock the repository too.
3353
                    return
3354
                if not self._lock_token:
3355
                    raise AssertionError('Locked, but no token!')
3356
                branch_token = self._lock_token
3357
                repo_token = self._repo_lock_token
3358
                self._lock_token = None
3359
                self._repo_lock_token = None
3360
                if not self._leave_lock:
3361
                    self._unlock(branch_token, repo_token)
3362
        finally:
3363
            self.repository.unlock()
1752.2.52 by Andrew Bennetts
Flesh out more Remote* methods needed to open and initialise remote branches/trees/repositories.
3364
3365
    def break_lock(self):
6280.4.3 by Jelmer Vernooij
add Branch.break_lock.
3366
        try:
3367
            response = self._call(
3368
                'Branch.break_lock', self._remote_path())
3369
        except errors.UnknownSmartMethod:
3370
            self._ensure_real()
3371
            return self._real_branch.break_lock()
3372
        if response != ('ok',):
3373
            raise errors.UnexpectedSmartServerResponse(response)
1752.2.31 by Martin Pool
[broken] some support for write operations over hpss
3374
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
3375
    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.
3376
        if not self._lock_token:
3377
            raise NotImplementedError(self.leave_lock_in_place)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
3378
        self._leave_lock = True
3379
3380
    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.
3381
        if not self._lock_token:
3015.2.15 by Robert Collins
Review feedback.
3382
            raise NotImplementedError(self.dont_leave_lock_in_place)
2018.5.79 by Andrew Bennetts
Implement RemoteBranch.lock_write/unlock as smart operations.
3383
        self._leave_lock = False
3384
4634.69.1 by Andrew Bennetts
Apply @needs_read_lock to RemoteBranch.get_rev_id.
3385
    @needs_read_lock
4419.2.4 by Andrew Bennetts
Add Repository.get_rev_id_for_revno RPC, removes VFS calls from 'pull -r 123' case.
3386
    def get_rev_id(self, revno, history=None):
4419.2.17 by Andrew Bennetts
Fix test failures in test_lookup_revision_id_by_dotted.
3387
        if revno == 0:
3388
            return _mod_revision.NULL_REVISION
4419.2.4 by Andrew Bennetts
Add Repository.get_rev_id_for_revno RPC, removes VFS calls from 'pull -r 123' case.
3389
        last_revision_info = self.last_revision_info()
4419.2.15 by Andrew Bennetts
Simplify RemoteBranch.get_rev_id a little; get_rev_id_for_revno handles stacking for us.
3390
        ok, result = self.repository.get_rev_id_for_revno(
3391
            revno, last_revision_info)
3392
        if ok:
3393
            return result
3394
        missing_parent = result[1]
4419.2.17 by Andrew Bennetts
Fix test failures in test_lookup_revision_id_by_dotted.
3395
        # Either the revision named by the server is missing, or its parent
3396
        # is.  Call get_parent_map to determine which, so that we report a
3397
        # useful error.
3398
        parent_map = self.repository.get_parent_map([missing_parent])
3399
        if missing_parent in parent_map:
3400
            missing_parent = parent_map[missing_parent]
4419.2.4 by Andrew Bennetts
Add Repository.get_rev_id_for_revno RPC, removes VFS calls from 'pull -r 123' case.
3401
        raise errors.RevisionNotPresent(missing_parent, self.repository)
3402
5718.8.3 by Jelmer Vernooij
More branch restructuring.
3403
    def _read_last_revision_info(self):
3786.2.3 by Andrew Bennetts
Remove duplicated 'call & translate errors' code in bzrlib.remote.
3404
        response = self._call('Branch.last_revision_info', self._remote_path())
3376.2.4 by Martin Pool
Remove every assert statement from bzrlib!
3405
        if response[0] != 'ok':
3406
            raise SmartProtocolError('unexpected response code %s' % (response,))
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
3407
        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.
3408
        last_revision = response[2]
2018.5.51 by Wouter van Heyst
Test and implement RemoteBranch.last_revision_info()
3409
        return (revno, last_revision)
3410
2018.5.105 by Andrew Bennetts
Implement revision_history caching for RemoteBranch.
3411
    def _gen_revision_history(self):
3412
        """See Branch._gen_revision_history()."""
4419.1.3 by Andrew Bennetts
Quick fix by using self._ensure_real.
3413
        if self._is_stacked:
3414
            self._ensure_real()
3415
            return self._real_branch._gen_revision_history()
3786.2.3 by Andrew Bennetts
Remove duplicated 'call & translate errors' code in bzrlib.remote.
3416
        response_tuple, response_handler = self._call_expecting_body(
3691.2.3 by Martin Pool
Factor out RemoteBranch._remote_path() and disable RemoteBranch stacking
3417
            'Branch.revision_history', self._remote_path())
3245.4.58 by Andrew Bennetts
Unpack call_expecting_body's return value into variables, to avoid lots of ugly subscripting.
3418
        if response_tuple[0] != 'ok':
3452.2.2 by Andrew Bennetts
Experimental PackRepository.{check_references,autopack} RPCs.
3419
            raise errors.UnexpectedSmartServerResponse(response_tuple)
3245.4.58 by Andrew Bennetts
Unpack call_expecting_body's return value into variables, to avoid lots of ugly subscripting.
3420
        result = response_handler.read_body_bytes().split('\x00')
2018.5.38 by Robert Collins
Implement RemoteBranch.revision_history().
3421
        if result == ['']:
3422
            return []
3423
        return result
1752.2.30 by Martin Pool
Start adding a RemoteBzrDir, etc
3424
3691.2.3 by Martin Pool
Factor out RemoteBranch._remote_path() and disable RemoteBranch stacking
3425
    def _remote_path(self):
3426
        return self.bzrdir._path_for_remote_call(self._client)
3427
3441.5.18 by Andrew Bennetts
Fix some test failures.
3428
    def _set_last_revision_descendant(self, revision_id, other_branch,
3441.5.28 by Andrew Bennetts
Another review tweak: rename do_not_overwrite_descendant to allow_overwrite_descendant.
3429
            allow_diverged=False, allow_overwrite_descendant=False):
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
3430
        # This performs additional work to meet the hook contract; while its
3431
        # undesirable, we have to synthesise the revno to call the hook, and
3432
        # not calling the hook is worse as it means changes can't be prevented.
3433
        # Having calculated this though, we can't just call into
3434
        # set_last_revision_info as a simple call, because there is a set_rh
3435
        # hook that some folk may still be using.
3436
        old_revno, old_revid = self.last_revision_info()
3437
        history = self._lefthand_history(revision_id)
3438
        self._run_pre_change_branch_tip_hooks(len(history), revision_id)
3786.2.3 by Andrew Bennetts
Remove duplicated 'call & translate errors' code in bzrlib.remote.
3439
        err_context = {'other_branch': other_branch}
3440
        response = self._call('Branch.set_last_revision_ex',
3441
            self._remote_path(), self._lock_token, self._repo_lock_token,
3442
            revision_id, int(allow_diverged), int(allow_overwrite_descendant),
3443
            **err_context)
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
3444
        self._clear_cached_state()
3441.5.18 by Andrew Bennetts
Fix some test failures.
3445
        if len(response) != 3 and response[0] != 'ok':
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
3446
            raise errors.UnexpectedSmartServerResponse(response)
3441.5.18 by Andrew Bennetts
Fix some test failures.
3447
        new_revno, new_revision_id = response[1:]
3448
        self._last_revision_info_cache = new_revno, new_revision_id
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
3449
        self._run_post_change_branch_tip_hooks(old_revno, old_revid)
3692.1.5 by Andrew Bennetts
Fix bug revealed by removing _ensure_real call from RemoteBranch.lock_write.
3450
        if self._real_branch is not None:
3451
            cache = new_revno, new_revision_id
3452
            self._real_branch._last_revision_info_cache = cache
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
3453
3441.5.1 by Andrew Bennetts
Avoid necessarily calling get_parent_map when pushing.
3454
    def _set_last_revision(self, revision_id):
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
3455
        old_revno, old_revid = self.last_revision_info()
3456
        # This performs additional work to meet the hook contract; while its
3457
        # undesirable, we have to synthesise the revno to call the hook, and
3458
        # not calling the hook is worse as it means changes can't be prevented.
3459
        # Having calculated this though, we can't just call into
3460
        # set_last_revision_info as a simple call, because there is a set_rh
3461
        # hook that some folk may still be using.
3462
        history = self._lefthand_history(revision_id)
3463
        self._run_pre_change_branch_tip_hooks(len(history), revision_id)
3441.5.1 by Andrew Bennetts
Avoid necessarily calling get_parent_map when pushing.
3464
        self._clear_cached_state()
3786.2.3 by Andrew Bennetts
Remove duplicated 'call & translate errors' code in bzrlib.remote.
3465
        response = self._call('Branch.set_last_revision',
3466
            self._remote_path(), self._lock_token, self._repo_lock_token,
3467
            revision_id)
3441.5.1 by Andrew Bennetts
Avoid necessarily calling get_parent_map when pushing.
3468
        if response != ('ok',):
3469
            raise errors.UnexpectedSmartServerResponse(response)
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
3470
        self._run_post_change_branch_tip_hooks(old_revno, old_revid)
3441.5.1 by Andrew Bennetts
Avoid necessarily calling get_parent_map when pushing.
3471
5718.7.7 by Jelmer Vernooij
Implement stub RemoteBranch.revision_history.
3472
    @symbol_versioning.deprecated_method(symbol_versioning.deprecated_in((2, 4, 0)))
3473
    @needs_write_lock
3474
    def set_revision_history(self, rev_history):
3475
        """See Branch.set_revision_history."""
3476
        self._set_revision_history(rev_history)
3477
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
3478
    @needs_write_lock
5718.7.4 by Jelmer Vernooij
Branch.set_revision_history.
3479
    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.
3480
        # Send just the tip revision of the history; the server will generate
3481
        # the full history from that.  If the revision doesn't exist in this
3482
        # branch, NoSuchRevision will be raised.
3483
        if rev_history == []:
2018.5.170 by Andrew Bennetts
Use 'null:' instead of '' to mean NULL_REVISION on the wire.
3484
            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.
3485
        else:
3486
            rev_id = rev_history[-1]
3441.5.1 by Andrew Bennetts
Avoid necessarily calling get_parent_map when pushing.
3487
        self._set_last_revision(rev_id)
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
3488
        for hook in branch.Branch.hooks['set_rh']:
3489
            hook(self, rev_history)
2018.5.105 by Andrew Bennetts
Implement revision_history caching for RemoteBranch.
3490
        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.
3491
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
3492
    def _get_parent_location(self):
3493
        medium = self._client._medium
3494
        if medium._is_remote_before((1, 13)):
3495
            return self._vfs_get_parent_location()
3496
        try:
4083.1.4 by Andrew Bennetts
Fix trivial bug in get_parent RPC.
3497
            response = self._call('Branch.get_parent', self._remote_path())
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
3498
        except errors.UnknownSmartMethod:
4094.1.1 by Andrew Bennetts
Add some medium._remember_is_before((1, 13)) calls.
3499
            medium._remember_remote_is_before((1, 13))
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
3500
            return self._vfs_get_parent_location()
4083.1.4 by Andrew Bennetts
Fix trivial bug in get_parent RPC.
3501
        if len(response) != 1:
4083.1.6 by Andrew Bennetts
Fix trivial bug in my trivial bug fix :)
3502
            raise errors.UnexpectedSmartServerResponse(response)
4083.1.4 by Andrew Bennetts
Fix trivial bug in get_parent RPC.
3503
        parent_location = response[0]
3504
        if parent_location == '':
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
3505
            return None
4083.1.4 by Andrew Bennetts
Fix trivial bug in get_parent RPC.
3506
        return parent_location
4078.2.1 by Robert Collins
Add a Branch.get_parent remote call for RemoteBranch.
3507
3508
    def _vfs_get_parent_location(self):
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
3509
        self._ensure_real()
4083.1.5 by Andrew Bennetts
Fix trivial bug in get_parent RPC.
3510
        return self._real_branch._get_parent_location()
4032.1.1 by John Arbash Meinel
Merge the removal of all trailing whitespace, and resolve conflicts.
3511
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
3512
    def _set_parent_location(self, url):
4288.1.7 by Robert Collins
Add new remote server verb Branch.set_parent_location, dropping roundtrips further on push operations.
3513
        medium = self._client._medium
3514
        if medium._is_remote_before((1, 15)):
3515
            return self._vfs_set_parent_location(url)
3516
        try:
3517
            call_url = url or ''
3518
            if type(call_url) is not str:
3519
                raise AssertionError('url must be a str or None (%s)' % url)
3520
            response = self._call('Branch.set_parent_location',
3521
                self._remote_path(), self._lock_token, self._repo_lock_token,
3522
                call_url)
3523
        except errors.UnknownSmartMethod:
3524
            medium._remember_remote_is_before((1, 15))
3525
            return self._vfs_set_parent_location(url)
3526
        if response != ():
3527
            raise errors.UnexpectedSmartServerResponse(response)
3528
3529
    def _vfs_set_parent_location(self, url):
4288.1.4 by Robert Collins
Remove the explicit set_parent method on RemoteBranch in favour of inheriting from Branch.
3530
        self._ensure_real()
3531
        return self._real_branch._set_parent_location(url)
4032.1.1 by John Arbash Meinel
Merge the removal of all trailing whitespace, and resolve conflicts.
3532
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
3533
    @needs_write_lock
2477.1.2 by Martin Pool
Rename push/pull back to 'run_hooks' (jameinel)
3534
    def pull(self, source, overwrite=False, stop_revision=None,
2477.1.9 by Martin Pool
Review cleanups from John, mostly docs
3535
             **kwargs):
3441.5.29 by Andrew Bennetts
More review tweaks: whitespace nits in test_smart, add (and use) ._clear_cached_state_of_remote_branch_only method in bzrlib/remote.py.
3536
        self._clear_cached_state_of_remote_branch_only()
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
3537
        self._ensure_real()
3482.1.1 by John Arbash Meinel
Fix bug #238149, RemoteBranch.pull needs to return the _real_branch's pull result.
3538
        return self._real_branch.pull(
2477.1.2 by Martin Pool
Rename push/pull back to 'run_hooks' (jameinel)
3539
            source, overwrite=overwrite, stop_revision=stop_revision,
3489.2.4 by Andrew Bennetts
Fix all tests broken by fixing make_branch_and_tree.
3540
            _override_hook_target=self, **kwargs)
2018.14.1 by Andrew Bennetts
Update to current hpss branch? Fix lots of test failures.
3541
2018.14.3 by Andrew Bennetts
Make a couple more branch_implementations tests pass.
3542
    @needs_read_lock
5853.2.3 by Jelmer Vernooij
Fix lossy tests.
3543
    def push(self, target, overwrite=False, stop_revision=None, lossy=False):
2018.14.3 by Andrew Bennetts
Make a couple more branch_implementations tests pass.
3544
        self._ensure_real()
2018.5.97 by Andrew Bennetts
Fix more tests.
3545
        return self._real_branch.push(
5853.2.3 by Jelmer Vernooij
Fix lossy tests.
3546
            target, overwrite=overwrite, stop_revision=stop_revision, lossy=lossy,
2477.1.5 by Martin Pool
More cleanups of Branch.push to get the right behaviour with RemoteBranches
3547
            _override_hook_source_branch=self)
2018.14.3 by Andrew Bennetts
Make a couple more branch_implementations tests pass.
3548
3549
    def is_locked(self):
3550
        return self._lock_count >= 1
3551
3634.2.1 by John Arbash Meinel
Thunk over to the real branch's revision_id_to_revno.
3552
    @needs_read_lock
6263.1.2 by Jelmer Vernooij
Add ``Branch.revision_id_to_revno`` smart verb.
3553
    def revision_id_to_dotted_revno(self, revision_id):
3554
        """Given a revision id, return its dotted revno.
3555
3556
        :return: a tuple like (1,) or (400,1,3).
3557
        """
3558
        try:
3559
            response = self._call('Branch.revision_id_to_revno',
3560
                self._remote_path(), revision_id)
3561
        except errors.UnknownSmartMethod:
3562
            self._ensure_real()
6305.1.1 by Jelmer Vernooij
Add test for Branch.revision_id_to_dotted_revno fallback.
3563
            return self._real_branch.revision_id_to_dotted_revno(revision_id)
6263.1.2 by Jelmer Vernooij
Add ``Branch.revision_id_to_revno`` smart verb.
3564
        if response[0] == 'ok':
3565
            return tuple([int(x) for x in response[1:]])
3566
        else:
3567
            raise errors.UnexpectedSmartServerResponse(response)
3568
3569
    @needs_read_lock
3634.2.1 by John Arbash Meinel
Thunk over to the real branch's revision_id_to_revno.
3570
    def revision_id_to_revno(self, revision_id):
6263.1.2 by Jelmer Vernooij
Add ``Branch.revision_id_to_revno`` smart verb.
3571
        """Given a revision id on the branch mainline, return its revno.
3572
3573
        :return: an integer
3574
        """
3575
        try:
3576
            response = self._call('Branch.revision_id_to_revno',
3577
                self._remote_path(), revision_id)
3578
        except errors.UnknownSmartMethod:
3579
            self._ensure_real()
3580
            return self._real_branch.revision_id_to_revno(revision_id)
3581
        if response[0] == 'ok':
3582
            if len(response) == 2:
3583
                return int(response[1])
6263.1.6 by Jelmer Vernooij
Fix another test.
3584
            raise NoSuchRevision(self, revision_id)
6263.1.2 by Jelmer Vernooij
Add ``Branch.revision_id_to_revno`` smart verb.
3585
        else:
3586
            raise errors.UnexpectedSmartServerResponse(response)
3634.2.1 by John Arbash Meinel
Thunk over to the real branch's revision_id_to_revno.
3587
2892.2.1 by Andrew Bennetts
Add Branch.set_last_revision_info smart method, and make the RemoteBranch client use it.
3588
    @needs_write_lock
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
3589
    def set_last_revision_info(self, revno, revision_id):
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
3590
        # XXX: These should be returned by the set_last_revision_info verb
3591
        old_revno, old_revid = self.last_revision_info()
3592
        self._run_pre_change_branch_tip_hooks(revno, revision_id)
5803.1.1 by Jelmer Vernooij
Raise InvalidRevisionId on Branch.set_last_revision_info.
3593
        if not revision_id or not isinstance(revision_id, basestring):
3594
            raise errors.InvalidRevisionId(revision_id=revision_id, branch=self)
3297.4.2 by Andrew Bennetts
Add backwards compatibility for servers older than 1.4.
3595
        try:
3786.2.3 by Andrew Bennetts
Remove duplicated 'call & translate errors' code in bzrlib.remote.
3596
            response = self._call('Branch.set_last_revision_info',
3597
                self._remote_path(), self._lock_token, self._repo_lock_token,
3598
                str(revno), revision_id)
3297.4.2 by Andrew Bennetts
Add backwards compatibility for servers older than 1.4.
3599
        except errors.UnknownSmartMethod:
3600
            self._ensure_real()
3441.5.29 by Andrew Bennetts
More review tweaks: whitespace nits in test_smart, add (and use) ._clear_cached_state_of_remote_branch_only method in bzrlib/remote.py.
3601
            self._clear_cached_state_of_remote_branch_only()
3441.5.1 by Andrew Bennetts
Avoid necessarily calling get_parent_map when pushing.
3602
            self._real_branch.set_last_revision_info(revno, revision_id)
3603
            self._last_revision_info_cache = revno, revision_id
3604
            return
2892.2.1 by Andrew Bennetts
Add Branch.set_last_revision_info smart method, and make the RemoteBranch client use it.
3605
        if response == ('ok',):
3606
            self._clear_cached_state()
3441.5.1 by Andrew Bennetts
Avoid necessarily calling get_parent_map when pushing.
3607
            self._last_revision_info_cache = revno, revision_id
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
3608
            self._run_post_change_branch_tip_hooks(old_revno, old_revid)
3441.5.29 by Andrew Bennetts
More review tweaks: whitespace nits in test_smart, add (and use) ._clear_cached_state_of_remote_branch_only method in bzrlib/remote.py.
3609
            # Update the _real_branch's cache too.
3610
            if self._real_branch is not None:
3611
                cache = self._last_revision_info_cache
3612
                self._real_branch._last_revision_info_cache = cache
2892.2.1 by Andrew Bennetts
Add Branch.set_last_revision_info smart method, and make the RemoteBranch client use it.
3613
        else:
3614
            raise errors.UnexpectedSmartServerResponse(response)
2018.5.83 by Andrew Bennetts
Fix some test failures caused by the switch from unicode to UTF-8-encoded strs for revision IDs.
3615
3441.5.27 by Andrew Bennetts
Tweaks suggested by John's review: rename _check_if_descendant_or_diverged, move caching last_revision_info into base Branch, better use of lock decorators.
3616
    @needs_write_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.
3617
    def generate_revision_history(self, revision_id, last_rev=None,
3618
                                  other_branch=None):
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
3619
        medium = self._client._medium
3441.5.23 by Andrew Bennetts
Fix test failures.
3620
        if not medium._is_remote_before((1, 6)):
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
3621
            # Use a smart method for 1.6 and above servers
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
3622
            try:
3441.5.18 by Andrew Bennetts
Fix some test failures.
3623
                self._set_last_revision_descendant(revision_id, other_branch,
3441.5.28 by Andrew Bennetts
Another review tweak: rename do_not_overwrite_descendant to allow_overwrite_descendant.
3624
                    allow_diverged=True, allow_overwrite_descendant=True)
3441.5.6 by Andrew Bennetts
Greatly simplify RemoteBranch.update_revisions. Still needs more tests.
3625
                return
3441.5.18 by Andrew Bennetts
Fix some test failures.
3626
            except errors.UnknownSmartMethod:
3441.5.23 by Andrew Bennetts
Fix test failures.
3627
                medium._remember_remote_is_before((1, 6))
3441.5.29 by Andrew Bennetts
More review tweaks: whitespace nits in test_smart, add (and use) ._clear_cached_state_of_remote_branch_only method in bzrlib/remote.py.
3628
        self._clear_cached_state_of_remote_branch_only()
5718.7.4 by Jelmer Vernooij
Branch.set_revision_history.
3629
        self._set_revision_history(self._lefthand_history(revision_id,
4005.2.1 by Robert Collins
Fix RemoteBranch to be used correctly in tests using bzr+ssh, to fire off Branch hooks correctly, and improve the branch_implementations tests to check that making a branch gets the right format under test.
3630
            last_rev=last_rev,other_branch=other_branch))
2018.5.96 by Andrew Bennetts
Merge from bzr.dev, resolving the worst of the semantic conflicts, but there's
3631
2018.5.97 by Andrew Bennetts
Fix more tests.
3632
    def set_push_location(self, location):
3633
        self._ensure_real()
3634
        return self._real_branch.set_push_location(location)
3635
5741.1.11 by Jelmer Vernooij
Don't make heads_to_fetch() take a stop_revision.
3636
    def heads_to_fetch(self):
5672.1.7 by Andrew Bennetts
Use a more explicit method name.
3637
        if self._format._use_default_local_heads_to_fetch():
5672.1.5 by Andrew Bennetts
Add some tests for RemoteBranch.heads_to_fetch, and add release-note.
3638
            # We recognise this format, and its heads-to-fetch implementation
3639
            # is the default one (tip + tags).  In this case it's cheaper to
3640
            # just use the default implementation rather than a special RPC as
3641
            # the tip and tags data is cached.
5741.1.11 by Jelmer Vernooij
Don't make heads_to_fetch() take a stop_revision.
3642
            return branch.Branch.heads_to_fetch(self)
5672.1.4 by Andrew Bennetts
Fix final bzr-loom test by adding RemoteBranch.heads_to_fetch that can ask the remote branch for the heads to fetch (but uses the cheaper default logic if it knows the remote format has an identical heads_to_fetch as Branch.heads_to_fetch).
3643
        medium = self._client._medium
3644
        if medium._is_remote_before((2, 4)):
5741.1.11 by Jelmer Vernooij
Don't make heads_to_fetch() take a stop_revision.
3645
            return self._vfs_heads_to_fetch()
5672.1.4 by Andrew Bennetts
Fix final bzr-loom test by adding RemoteBranch.heads_to_fetch that can ask the remote branch for the heads to fetch (but uses the cheaper default logic if it knows the remote format has an identical heads_to_fetch as Branch.heads_to_fetch).
3646
        try:
5741.1.11 by Jelmer Vernooij
Don't make heads_to_fetch() take a stop_revision.
3647
            return self._rpc_heads_to_fetch()
5672.1.4 by Andrew Bennetts
Fix final bzr-loom test by adding RemoteBranch.heads_to_fetch that can ask the remote branch for the heads to fetch (but uses the cheaper default logic if it knows the remote format has an identical heads_to_fetch as Branch.heads_to_fetch).
3648
        except errors.UnknownSmartMethod:
3649
            medium._remember_remote_is_before((2, 4))
5741.1.11 by Jelmer Vernooij
Don't make heads_to_fetch() take a stop_revision.
3650
            return self._vfs_heads_to_fetch()
5672.1.4 by Andrew Bennetts
Fix final bzr-loom test by adding RemoteBranch.heads_to_fetch that can ask the remote branch for the heads to fetch (but uses the cheaper default logic if it knows the remote format has an identical heads_to_fetch as Branch.heads_to_fetch).
3651
5741.1.11 by Jelmer Vernooij
Don't make heads_to_fetch() take a stop_revision.
3652
    def _rpc_heads_to_fetch(self):
3653
        response = self._call('Branch.heads_to_fetch', self._remote_path())
5672.1.4 by Andrew Bennetts
Fix final bzr-loom test by adding RemoteBranch.heads_to_fetch that can ask the remote branch for the heads to fetch (but uses the cheaper default logic if it knows the remote format has an identical heads_to_fetch as Branch.heads_to_fetch).
3654
        if len(response) != 2:
3655
            raise errors.UnexpectedSmartServerResponse(response)
3656
        must_fetch, if_present_fetch = response
3657
        return set(must_fetch), set(if_present_fetch)
3658
5741.1.11 by Jelmer Vernooij
Don't make heads_to_fetch() take a stop_revision.
3659
    def _vfs_heads_to_fetch(self):
5672.1.4 by Andrew Bennetts
Fix final bzr-loom test by adding RemoteBranch.heads_to_fetch that can ask the remote branch for the heads to fetch (but uses the cheaper default logic if it knows the remote format has an identical heads_to_fetch as Branch.heads_to_fetch).
3660
        self._ensure_real()
5741.1.11 by Jelmer Vernooij
Don't make heads_to_fetch() take a stop_revision.
3661
        return self._real_branch.heads_to_fetch()
5672.1.4 by Andrew Bennetts
Fix final bzr-loom test by adding RemoteBranch.heads_to_fetch that can ask the remote branch for the heads to fetch (but uses the cheaper default logic if it knows the remote format has an identical heads_to_fetch as Branch.heads_to_fetch).
3662
2018.18.25 by Martin Pool
Repository.tarball fixes for python2.4
3663
4288.1.1 by Robert Collins
Add support for a RemoteBzrDirConfig to support optimising push operations which need to look for default stacking locations.
3664
class RemoteConfig(object):
3665
    """A Config that reads and writes from smart verbs.
4226.1.5 by Robert Collins
Reinstate the use of the Branch.get_config_file verb.
3666
3667
    It is a low-level object that considers config data to be name/value pairs
3668
    that may be associated with a section. Assigning meaning to the these
3669
    values is done at higher levels like bzrlib.config.TreeConfig.
3670
    """
3671
3672
    def get_option(self, name, section=None, default=None):
3673
        """Return the value associated with a named option.
3674
3675
        :param name: The name of the value
3676
        :param section: The section the option is in (if any)
3677
        :param default: The value to return if the value is not set
3678
        :return: The value or default value
3679
        """
4288.1.1 by Robert Collins
Add support for a RemoteBzrDirConfig to support optimising push operations which need to look for default stacking locations.
3680
        try:
3681
            configobj = self._get_configobj()
5743.8.17 by Vincent Ladeuil
Add config old_get hook for remote config.
3682
            section_obj = None
4288.1.1 by Robert Collins
Add support for a RemoteBzrDirConfig to support optimising push operations which need to look for default stacking locations.
3683
            if section is None:
3684
                section_obj = configobj
3685
            else:
3686
                try:
3687
                    section_obj = configobj[section]
3688
                except KeyError:
5743.8.17 by Vincent Ladeuil
Add config old_get hook for remote config.
3689
                    pass
3690
            if section_obj is None:
3691
                value = default
3692
            else:
3693
                value = section_obj.get(name, default)
4288.1.1 by Robert Collins
Add support for a RemoteBzrDirConfig to support optimising push operations which need to look for default stacking locations.
3694
        except errors.UnknownSmartMethod:
5743.8.17 by Vincent Ladeuil
Add config old_get hook for remote config.
3695
            value = self._vfs_get_option(name, section, default)
5743.8.24 by Vincent Ladeuil
Clearly seaparate both sets of hooks for the old and new config implementations.
3696
        for hook in config.OldConfigHooks['get']:
5743.8.17 by Vincent Ladeuil
Add config old_get hook for remote config.
3697
            hook(self, name, value)
3698
        return value
4226.1.5 by Robert Collins
Reinstate the use of the Branch.get_config_file verb.
3699
4288.1.1 by Robert Collins
Add support for a RemoteBzrDirConfig to support optimising push operations which need to look for default stacking locations.
3700
    def _response_to_configobj(self, response):
4288.1.2 by Robert Collins
Create a server verb for doing BzrDir.get_config()
3701
        if len(response[0]) and response[0][0] != 'ok':
4288.1.4 by Robert Collins
Remove the explicit set_parent method on RemoteBranch in favour of inheriting from Branch.
3702
            raise errors.UnexpectedSmartServerResponse(response)
4241.5.1 by Matt Nordhoff
Fix Branch.get_config_file smart verb on multi-line config files. (Bug #354075)
3703
        lines = response[1].read_body_bytes().splitlines()
5743.8.21 by Vincent Ladeuil
Add test for config load hook for remote configs.
3704
        conf = config.ConfigObj(lines, encoding='utf-8')
5743.8.24 by Vincent Ladeuil
Clearly seaparate both sets of hooks for the old and new config implementations.
3705
        for hook in config.OldConfigHooks['load']:
5743.8.21 by Vincent Ladeuil
Add test for config load hook for remote configs.
3706
            hook(self)
3707
        return conf
4226.1.5 by Robert Collins
Reinstate the use of the Branch.get_config_file verb.
3708
4288.1.1 by Robert Collins
Add support for a RemoteBzrDirConfig to support optimising push operations which need to look for default stacking locations.
3709
3710
class RemoteBranchConfig(RemoteConfig):
3711
    """A RemoteConfig for Branches."""
3712
3713
    def __init__(self, branch):
3714
        self._branch = branch
3715
3716
    def _get_configobj(self):
3717
        path = self._branch._remote_path()
3718
        response = self._branch._client.call_expecting_body(
3719
            'Branch.get_config_file', path)
3720
        return self._response_to_configobj(response)
3721
4226.1.5 by Robert Collins
Reinstate the use of the Branch.get_config_file verb.
3722
    def set_option(self, value, name, section=None):
3723
        """Set the value associated with a named option.
3724
3725
        :param value: The value to set
3726
        :param name: The name of the value to set
3727
        :param section: The section the option is in (if any)
3728
        """
4226.2.1 by Robert Collins
Set branch config options via a smart method.
3729
        medium = self._branch._client._medium
3730
        if medium._is_remote_before((1, 14)):
3731
            return self._vfs_set_option(value, name, section)
5227.1.2 by Andrew Bennetts
Add Branch.set_config_option_dict RPC (and VFS fallback), fixes #430382.
3732
        if isinstance(value, dict):
3733
            if medium._is_remote_before((2, 2)):
3734
                return self._vfs_set_option(value, name, section)
3735
            return self._set_config_option_dict(value, name, section)
3736
        else:
3737
            return self._set_config_option(value, name, section)
3738
3739
    def _set_config_option(self, value, name, section):
4226.2.1 by Robert Collins
Set branch config options via a smart method.
3740
        try:
3741
            path = self._branch._remote_path()
3742
            response = self._branch._client.call('Branch.set_config_option',
3743
                path, self._branch._lock_token, self._branch._repo_lock_token,
4226.2.2 by Robert Collins
Fix setting config options to support unicode values and don't attempt to reset repositories _fallback_repositories as the simple approach fails to work.
3744
                value.encode('utf8'), name, section or '')
4226.2.1 by Robert Collins
Set branch config options via a smart method.
3745
        except errors.UnknownSmartMethod:
5227.1.2 by Andrew Bennetts
Add Branch.set_config_option_dict RPC (and VFS fallback), fixes #430382.
3746
            medium = self._branch._client._medium
4226.2.1 by Robert Collins
Set branch config options via a smart method.
3747
            medium._remember_remote_is_before((1, 14))
3748
            return self._vfs_set_option(value, name, section)
3749
        if response != ():
3750
            raise errors.UnexpectedSmartServerResponse(response)
4226.1.5 by Robert Collins
Reinstate the use of the Branch.get_config_file verb.
3751
5227.1.2 by Andrew Bennetts
Add Branch.set_config_option_dict RPC (and VFS fallback), fixes #430382.
3752
    def _serialize_option_dict(self, option_dict):
3753
        utf8_dict = {}
3754
        for key, value in option_dict.items():
3755
            if isinstance(key, unicode):
3756
                key = key.encode('utf8')
3757
            if isinstance(value, unicode):
3758
                value = value.encode('utf8')
3759
            utf8_dict[key] = value
3760
        return bencode.bencode(utf8_dict)
3761
3762
    def _set_config_option_dict(self, value, name, section):
3763
        try:
3764
            path = self._branch._remote_path()
3765
            serialised_dict = self._serialize_option_dict(value)
3766
            response = self._branch._client.call(
3767
                'Branch.set_config_option_dict',
3768
                path, self._branch._lock_token, self._branch._repo_lock_token,
3769
                serialised_dict, name, section or '')
3770
        except errors.UnknownSmartMethod:
3771
            medium = self._branch._client._medium
3772
            medium._remember_remote_is_before((2, 2))
3773
            return self._vfs_set_option(value, name, section)
3774
        if response != ():
3775
            raise errors.UnexpectedSmartServerResponse(response)
3776
4288.1.1 by Robert Collins
Add support for a RemoteBzrDirConfig to support optimising push operations which need to look for default stacking locations.
3777
    def _real_object(self):
3778
        self._branch._ensure_real()
3779
        return self._branch._real_branch
3780
4226.1.5 by Robert Collins
Reinstate the use of the Branch.get_config_file verb.
3781
    def _vfs_set_option(self, value, name, section=None):
4288.1.1 by Robert Collins
Add support for a RemoteBzrDirConfig to support optimising push operations which need to look for default stacking locations.
3782
        return self._real_object()._get_config().set_option(
3783
            value, name, section)
3784
3785
3786
class RemoteBzrDirConfig(RemoteConfig):
3787
    """A RemoteConfig for BzrDirs."""
3788
3789
    def __init__(self, bzrdir):
3790
        self._bzrdir = bzrdir
3791
3792
    def _get_configobj(self):
4288.1.4 by Robert Collins
Remove the explicit set_parent method on RemoteBranch in favour of inheriting from Branch.
3793
        medium = self._bzrdir._client._medium
3794
        verb = 'BzrDir.get_config_file'
3795
        if medium._is_remote_before((1, 15)):
3796
            raise errors.UnknownSmartMethod(verb)
4288.1.1 by Robert Collins
Add support for a RemoteBzrDirConfig to support optimising push operations which need to look for default stacking locations.
3797
        path = self._bzrdir._path_for_remote_call(self._bzrdir._client)
3798
        response = self._bzrdir._call_expecting_body(
4288.1.4 by Robert Collins
Remove the explicit set_parent method on RemoteBranch in favour of inheriting from Branch.
3799
            verb, path)
4288.1.1 by Robert Collins
Add support for a RemoteBzrDirConfig to support optimising push operations which need to look for default stacking locations.
3800
        return self._response_to_configobj(response)
3801
3802
    def _vfs_get_option(self, name, section, default):
3803
        return self._real_object()._get_config().get_option(
3804
            name, section, default)
3805
3806
    def set_option(self, value, name, section=None):
3807
        """Set the value associated with a named option.
3808
3809
        :param value: The value to set
3810
        :param name: The name of the value to set
3811
        :param section: The section the option is in (if any)
3812
        """
3813
        return self._real_object()._get_config().set_option(
3814
            value, name, section)
3815
3816
    def _real_object(self):
3817
        self._bzrdir._ensure_real()
3818
        return self._bzrdir._real_bzrdir
3819
4226.1.5 by Robert Collins
Reinstate the use of the Branch.get_config_file verb.
3820
2018.18.25 by Martin Pool
Repository.tarball fixes for python2.4
3821
def _extract_tar(tar, to_dir):
3822
    """Extract all the contents of a tarfile object.
3823
3824
    A replacement for extractall, which is not present in python2.4
3825
    """
3826
    for tarinfo in tar:
3827
        tar.extract(tarinfo, to_dir)
3533.3.1 by Andrew Bennetts
Remove duplication of error translation in bzrlib/remote.py.
3828
3829
6284.1.1 by Jelmer Vernooij
Allow registering custom error handlers in the HPSS client.
3830
error_translators = registry.Registry()
3831
no_context_error_translators = registry.Registry()
3832
3833
3533.3.1 by Andrew Bennetts
Remove duplication of error translation in bzrlib/remote.py.
3834
def _translate_error(err, **context):
3835
    """Translate an ErrorFromSmartServer into a more useful error.
3836
3837
    Possible context keys:
3838
      - branch
3839
      - repository
3840
      - bzrdir
3841
      - token
3842
      - other_branch
3779.3.2 by Andrew Bennetts
Unify error translation done in bzrlib.remote and bzrlib.transport.remote.
3843
      - path
3690.1.1 by Andrew Bennetts
Unexpected error responses from a smart server no longer cause the client to traceback.
3844
3845
    If the error from the server doesn't match a known pattern, then
3690.1.2 by Andrew Bennetts
Rename UntranslateableErrorFromSmartServer -> UnknownErrorFromSmartServer.
3846
    UnknownErrorFromSmartServer is raised.
3533.3.1 by Andrew Bennetts
Remove duplication of error translation in bzrlib/remote.py.
3847
    """
3848
    def find(name):
3533.3.4 by Andrew Bennetts
Add tests for _translate_error's robustness.
3849
        try:
3850
            return context[name]
3779.3.2 by Andrew Bennetts
Unify error translation done in bzrlib.remote and bzrlib.transport.remote.
3851
        except KeyError, key_err:
3852
            mutter('Missing key %r in context %r', key_err.args[0], context)
3533.3.4 by Andrew Bennetts
Add tests for _translate_error's robustness.
3853
            raise err
3779.3.2 by Andrew Bennetts
Unify error translation done in bzrlib.remote and bzrlib.transport.remote.
3854
    def get_path():
3779.3.3 by Andrew Bennetts
Add a docstring.
3855
        """Get the path from the context if present, otherwise use first error
3856
        arg.
3857
        """
3779.3.2 by Andrew Bennetts
Unify error translation done in bzrlib.remote and bzrlib.transport.remote.
3858
        try:
3859
            return context['path']
3860
        except KeyError, key_err:
3861
            try:
3862
                return err.error_args[0]
3863
            except IndexError, idx_err:
3864
                mutter(
3865
                    'Missing key %r in context %r', key_err.args[0], context)
3866
                raise err
3867
6284.1.1 by Jelmer Vernooij
Allow registering custom error handlers in the HPSS client.
3868
    try:
3869
        translator = error_translators.get(err.error_verb)
3870
    except KeyError:
3871
        pass
3872
    else:
3873
        raise translator(err, find, get_path)
3874
    try:
3875
        translator = no_context_error_translators.get(err.error_verb)
3876
    except KeyError:
3877
        raise errors.UnknownErrorFromSmartServer(err)
3878
    else:
3879
        raise translator(err)
3880
3881
3882
error_translators.register('NoSuchRevision',
3883
    lambda err, find, get_path: NoSuchRevision(
3884
        find('branch'), err.error_args[0]))
3885
error_translators.register('nosuchrevision',
3886
    lambda err, find, get_path: NoSuchRevision(
3887
        find('repository'), err.error_args[0]))
3888
3889
def _translate_nobranch_error(err, find, get_path):
3890
    if len(err.error_args) >= 1:
3891
        extra = err.error_args[0]
3892
    else:
3893
        extra = None
3894
    return errors.NotBranchError(path=find('bzrdir').root_transport.base,
3895
        detail=extra)
3896
3897
error_translators.register('nobranch', _translate_nobranch_error)
3898
error_translators.register('norepository',
3899
    lambda err, find, get_path: errors.NoRepositoryPresent(
3900
        find('bzrdir')))
3901
error_translators.register('UnlockableTransport',
3902
    lambda err, find, get_path: errors.UnlockableTransport(
3903
        find('bzrdir').root_transport))
3904
error_translators.register('TokenMismatch',
3905
    lambda err, find, get_path: errors.TokenMismatch(
3906
        find('token'), '(remote token)'))
3907
error_translators.register('Diverged',
3908
    lambda err, find, get_path: errors.DivergedBranches(
3909
        find('branch'), find('other_branch')))
3910
error_translators.register('NotStacked',
3911
    lambda err, find, get_path: errors.NotStacked(branch=find('branch')))
3912
3913
def _translate_PermissionDenied(err, find, get_path):
3914
    path = get_path()
3915
    if len(err.error_args) >= 2:
3916
        extra = err.error_args[1]
3917
    else:
3918
        extra = None
3919
    return errors.PermissionDenied(path, extra=extra)
3920
3921
error_translators.register('PermissionDenied', _translate_PermissionDenied)
3922
error_translators.register('ReadError',
3923
    lambda err, find, get_path: errors.ReadError(get_path()))
3924
error_translators.register('NoSuchFile',
3925
    lambda err, find, get_path: errors.NoSuchFile(get_path()))
6280.10.31 by Jelmer Vernooij
Merge bzr.dev.
3926
error_translators.register('UnsuspendableWriteGroup',
3927
    lambda err, find, get_path: errors.UnsuspendableWriteGroup(
3928
        repository=find('repository')))
3929
error_translators.register('UnresumableWriteGroup',
3930
    lambda err, find, get_path: errors.UnresumableWriteGroup(
3931
        repository=find('repository'), write_groups=err.error_args[0],
3932
        reason=err.error_args[1]))
6284.1.1 by Jelmer Vernooij
Allow registering custom error handlers in the HPSS client.
3933
no_context_error_translators.register('IncompatibleRepositories',
3934
    lambda err: errors.IncompatibleRepositories(
3935
        err.error_args[0], err.error_args[1], err.error_args[2]))
3936
no_context_error_translators.register('LockContention',
3937
    lambda err: errors.LockContention('(remote lock)'))
3938
no_context_error_translators.register('LockFailed',
3939
    lambda err: errors.LockFailed(err.error_args[0], err.error_args[1]))
3940
no_context_error_translators.register('TipChangeRejected',
3941
    lambda err: errors.TipChangeRejected(err.error_args[0].decode('utf8')))
3942
no_context_error_translators.register('UnstackableBranchFormat',
3943
    lambda err: errors.UnstackableBranchFormat(*err.error_args))
3944
no_context_error_translators.register('UnstackableRepositoryFormat',
3945
    lambda err: errors.UnstackableRepositoryFormat(*err.error_args))
3946
no_context_error_translators.register('FileExists',
3947
    lambda err: errors.FileExists(err.error_args[0]))
3948
no_context_error_translators.register('DirectoryNotEmpty',
3949
    lambda err: errors.DirectoryNotEmpty(err.error_args[0]))
3950
3951
def _translate_short_readv_error(err):
3952
    args = err.error_args
3953
    return errors.ShortReadvError(args[0], int(args[1]), int(args[2]),
3954
        int(args[3]))
3955
3956
no_context_error_translators.register('ShortReadvError',
3957
    _translate_short_readv_error)
3958
3959
def _translate_unicode_error(err):
3779.3.2 by Andrew Bennetts
Unify error translation done in bzrlib.remote and bzrlib.transport.remote.
3960
        encoding = str(err.error_args[0]) # encoding must always be a string
3961
        val = err.error_args[1]
3962
        start = int(err.error_args[2])
3963
        end = int(err.error_args[3])
3964
        reason = str(err.error_args[4]) # reason must always be a string
3965
        if val.startswith('u:'):
3966
            val = val[2:].decode('utf-8')
3967
        elif val.startswith('s:'):
3968
            val = val[2:].decode('base64')
3786.2.3 by Andrew Bennetts
Remove duplicated 'call & translate errors' code in bzrlib.remote.
3969
        if err.error_verb == 'UnicodeDecodeError':
3779.3.2 by Andrew Bennetts
Unify error translation done in bzrlib.remote and bzrlib.transport.remote.
3970
            raise UnicodeDecodeError(encoding, val, start, end, reason)
3786.2.3 by Andrew Bennetts
Remove duplicated 'call & translate errors' code in bzrlib.remote.
3971
        elif err.error_verb == 'UnicodeEncodeError':
3779.3.2 by Andrew Bennetts
Unify error translation done in bzrlib.remote and bzrlib.transport.remote.
3972
            raise UnicodeEncodeError(encoding, val, start, end, reason)
6284.1.1 by Jelmer Vernooij
Allow registering custom error handlers in the HPSS client.
3973
3974
no_context_error_translators.register('UnicodeEncodeError',
3975
    _translate_unicode_error)
3976
no_context_error_translators.register('UnicodeDecodeError',
3977
    _translate_unicode_error)
3978
no_context_error_translators.register('ReadOnlyError',
3979
    lambda err: errors.TransportNotPossible('readonly transport'))
3980
no_context_error_translators.register('MemoryError',
3981
    lambda err: errors.BzrError("remote server out of memory\n"
3982
        "Retry non-remotely, or contact the server admin for details."))
6280.10.28 by Jelmer Vernooij
merge bzr.dev.
3983
no_context_error_translators.register('RevisionNotPresent',
3984
    lambda err: errors.RevisionNotPresent(err.error_args[0], err.error_args[1]))
3985
6280.7.13 by Jelmer Vernooij
Merge bzr.dev.
3986
no_context_error_translators.register('BzrCheckError',
3987
    lambda err: errors.BzrCheckError(msg=err.error_args[0]))
3988