/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/remote.py

  • Committer: Andrew Bennetts
  • Date: 2009-10-21 11:13:40 UTC
  • mto: This revision was merged to the branch mainline in revision 4762.
  • Revision ID: andrew.bennetts@canonical.com-20091021111340-w7x4d5yf83qwjncc
Add test that WSGI glue allows request handlers to access paths above that request's. backing transport, so long as it is within the WSGI app's backing transport.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
# Copyright (C) 2006-2010 Canonical Ltd
 
1
# Copyright (C) 2006, 2007, 2008, 2009 Canonical Ltd
2
2
#
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
27
27
    lock,
28
28
    lockdir,
29
29
    repository,
30
 
    repository as _mod_repository,
31
30
    revision,
32
31
    revision as _mod_revision,
33
 
    static_tuple,
34
32
    symbol_versioning,
35
33
)
36
34
from bzrlib.branch import BranchReferenceFormat
116
114
 
117
115
        self._probe_bzrdir()
118
116
 
119
 
    def __repr__(self):
120
 
        return '%s(%r)' % (self.__class__.__name__, self._client)
121
 
 
122
117
    def _probe_bzrdir(self):
123
118
        medium = self._client._medium
124
119
        path = self._path_for_remote_call(self._client)
159
154
        Used before calls to self._real_bzrdir.
160
155
        """
161
156
        if not self._real_bzrdir:
162
 
            if 'hpssvfs' in debug.debug_flags:
163
 
                import traceback
164
 
                warning('VFS BzrDir access triggered\n%s',
165
 
                    ''.join(traceback.format_stack()))
166
157
            self._real_bzrdir = BzrDir.open_from_transport(
167
158
                self.root_transport, _server_formats=False)
168
159
            self._format._network_name = \
244
235
        self._ensure_real()
245
236
        self._real_bzrdir.destroy_repository()
246
237
 
247
 
    def create_branch(self, name=None):
 
238
    def create_branch(self):
248
239
        # as per meta1 formats - just delegate to the format object which may
249
240
        # be parameterised.
250
 
        real_branch = self._format.get_branch_format().initialize(self,
251
 
            name=name)
 
241
        real_branch = self._format.get_branch_format().initialize(self)
252
242
        if not isinstance(real_branch, RemoteBranch):
253
 
            result = RemoteBranch(self, self.find_repository(), real_branch,
254
 
                                  name=name)
 
243
            result = RemoteBranch(self, self.find_repository(), real_branch)
255
244
        else:
256
245
            result = real_branch
257
246
        # BzrDir.clone_on_transport() uses the result of create_branch but does
263
252
        self._next_open_branch_result = result
264
253
        return result
265
254
 
266
 
    def destroy_branch(self, name=None):
 
255
    def destroy_branch(self):
267
256
        """See BzrDir.destroy_branch"""
268
257
        self._ensure_real()
269
 
        self._real_bzrdir.destroy_branch(name=name)
 
258
        self._real_bzrdir.destroy_branch()
270
259
        self._next_open_branch_result = None
271
260
 
272
261
    def create_workingtree(self, revision_id=None, from_branch=None):
291
280
    def _get_branch_reference(self):
292
281
        path = self._path_for_remote_call(self._client)
293
282
        medium = self._client._medium
294
 
        candidate_calls = [
295
 
            ('BzrDir.open_branchV3', (2, 1)),
296
 
            ('BzrDir.open_branchV2', (1, 13)),
297
 
            ('BzrDir.open_branch', None),
298
 
            ]
299
 
        for verb, required_version in candidate_calls:
300
 
            if required_version and medium._is_remote_before(required_version):
301
 
                continue
 
283
        if not medium._is_remote_before((1, 13)):
302
284
            try:
303
 
                response = self._call(verb, path)
 
285
                response = self._call('BzrDir.open_branchV2', path)
 
286
                if response[0] not in ('ref', 'branch'):
 
287
                    raise errors.UnexpectedSmartServerResponse(response)
 
288
                return response
304
289
            except errors.UnknownSmartMethod:
305
 
                if required_version is None:
306
 
                    raise
307
 
                medium._remember_remote_is_before(required_version)
308
 
            else:
309
 
                break
310
 
        if verb == 'BzrDir.open_branch':
311
 
            if response[0] != 'ok':
312
 
                raise errors.UnexpectedSmartServerResponse(response)
313
 
            if response[1] != '':
314
 
                return ('ref', response[1])
315
 
            else:
316
 
                return ('branch', '')
317
 
        if response[0] not in ('ref', 'branch'):
 
290
                medium._remember_remote_is_before((1, 13))
 
291
        response = self._call('BzrDir.open_branch', path)
 
292
        if response[0] != 'ok':
318
293
            raise errors.UnexpectedSmartServerResponse(response)
319
 
        return response
 
294
        if response[1] != '':
 
295
            return ('ref', response[1])
 
296
        else:
 
297
            return ('branch', '')
320
298
 
321
299
    def _get_tree_branch(self):
322
300
        """See BzrDir._get_tree_branch()."""
323
301
        return None, self.open_branch()
324
302
 
325
 
    def open_branch(self, name=None, unsupported=False,
326
 
                    ignore_fallbacks=False):
327
 
        if unsupported:
 
303
    def open_branch(self, _unsupported=False, ignore_fallbacks=False):
 
304
        if _unsupported:
328
305
            raise NotImplementedError('unsupported flag support not implemented yet.')
329
306
        if self._next_open_branch_result is not None:
330
307
            # See create_branch for details.
335
312
        if response[0] == 'ref':
336
313
            # a branch reference, use the existing BranchReference logic.
337
314
            format = BranchReferenceFormat()
338
 
            return format.open(self, name=name, _found=True,
339
 
                location=response[1], ignore_fallbacks=ignore_fallbacks)
 
315
            return format.open(self, _found=True, location=response[1],
 
316
                ignore_fallbacks=ignore_fallbacks)
340
317
        branch_format_name = response[1]
341
318
        if not branch_format_name:
342
319
            branch_format_name = None
343
320
        format = RemoteBranchFormat(network_name=branch_format_name)
344
321
        return RemoteBranch(self, self.find_repository(), format=format,
345
 
            setup_stacking=not ignore_fallbacks, name=name)
 
322
            setup_stacking=not ignore_fallbacks)
346
323
 
347
324
    def _open_repo_v1(self, path):
348
325
        verb = 'BzrDir.find_repository'
425
402
        """Return the path to be used for this bzrdir in a remote call."""
426
403
        return client.remote_path_from_transport(self.root_transport)
427
404
 
428
 
    def get_branch_transport(self, branch_format, name=None):
 
405
    def get_branch_transport(self, branch_format):
429
406
        self._ensure_real()
430
 
        return self._real_bzrdir.get_branch_transport(branch_format, name=name)
 
407
        return self._real_bzrdir.get_branch_transport(branch_format)
431
408
 
432
409
    def get_repository_transport(self, repository_format):
433
410
        self._ensure_real()
620
597
        return self._custom_format._fetch_reconcile
621
598
 
622
599
    def get_format_description(self):
623
 
        self._ensure_real()
624
 
        return 'Remote: ' + self._custom_format.get_format_description()
 
600
        return 'bzr remote repository'
625
601
 
626
602
    def __eq__(self, other):
627
603
        return self.__class__ is other.__class__
643
619
        return self._custom_format._serializer
644
620
 
645
621
 
646
 
class RemoteRepository(_RpcHelper, lock._RelockDebugMixin,
647
 
    bzrdir.ControlComponent):
 
622
class RemoteRepository(_RpcHelper, lock._RelockDebugMixin):
648
623
    """Repository accessed over rpc.
649
624
 
650
625
    For the moment most operations are performed using local transport-backed
693
668
        # Additional places to query for data.
694
669
        self._fallback_repositories = []
695
670
 
696
 
    @property
697
 
    def user_transport(self):
698
 
        return self.bzrdir.user_transport
699
 
 
700
 
    @property
701
 
    def control_transport(self):
702
 
        # XXX: Normally you shouldn't directly get at the remote repository
703
 
        # transport, but I'm not sure it's worth making this method
704
 
        # optional -- mbp 2010-04-21
705
 
        return self.bzrdir.get_repository_transport(None)
706
 
        
707
671
    def __str__(self):
708
672
        return "%s(%s)" % (self.__class__.__name__, self.base)
709
673
 
917
881
        parents_provider = self._make_parents_provider(other_repository)
918
882
        return graph.Graph(parents_provider)
919
883
 
920
 
    @needs_read_lock
921
 
    def get_known_graph_ancestry(self, revision_ids):
922
 
        """Return the known graph for a set of revision ids and their ancestors.
923
 
        """
924
 
        st = static_tuple.StaticTuple
925
 
        revision_keys = [st(r_id).intern() for r_id in revision_ids]
926
 
        known_graph = self.revisions.get_known_graph_ancestry(revision_keys)
927
 
        return graph.GraphThunkIdsToKeys(known_graph)
928
 
 
929
884
    def gather_stats(self, revid=None, committers=None):
930
885
        """See Repository.gather_stats()."""
931
886
        path = self.bzrdir._path_for_remote_call(self._client)
991
946
    def is_write_locked(self):
992
947
        return self._lock_mode == 'w'
993
948
 
994
 
    def _warn_if_deprecated(self, branch=None):
995
 
        # If we have a real repository, the check will be done there, if we
996
 
        # don't the check will be done remotely.
997
 
        pass
998
 
 
999
949
    def lock_read(self):
1000
950
        # wrong eventually - want a local lock cache context
1001
951
        if not self._lock_mode:
1240
1190
            # state, so always add a lock here. If a caller passes us a locked
1241
1191
            # repository, they are responsible for unlocking it later.
1242
1192
            repository.lock_read()
1243
 
        self._check_fallback_repository(repository)
1244
1193
        self._fallback_repositories.append(repository)
1245
1194
        # If self._real_repository was parameterised already (e.g. because a
1246
1195
        # _real_branch had its get_stacked_on_url method called), then the
1247
1196
        # repository to be added may already be in the _real_repositories list.
1248
1197
        if self._real_repository is not None:
1249
 
            fallback_locations = [repo.user_url for repo in
 
1198
            fallback_locations = [repo.bzrdir.root_transport.base for repo in
1250
1199
                self._real_repository._fallback_repositories]
1251
 
            if repository.user_url not in fallback_locations:
 
1200
            if repository.bzrdir.root_transport.base not in fallback_locations:
1252
1201
                self._real_repository.add_fallback_repository(repository)
1253
1202
 
1254
 
    def _check_fallback_repository(self, repository):
1255
 
        """Check that this repository can fallback to repository safely.
1256
 
 
1257
 
        Raise an error if not.
1258
 
 
1259
 
        :param repository: A repository to fallback to.
1260
 
        """
1261
 
        return _mod_repository.InterRepository._assert_same_model(
1262
 
            self, repository)
1263
 
 
1264
1203
    def add_inventory(self, revid, inv, parents):
1265
1204
        self._ensure_real()
1266
1205
        return self._real_repository.add_inventory(revid, inv, parents)
1267
1206
 
1268
1207
    def add_inventory_by_delta(self, basis_revision_id, delta, new_revision_id,
1269
 
            parents, basis_inv=None, propagate_caches=False):
 
1208
                               parents):
1270
1209
        self._ensure_real()
1271
1210
        return self._real_repository.add_inventory_by_delta(basis_revision_id,
1272
 
            delta, new_revision_id, parents, basis_inv=basis_inv,
1273
 
            propagate_caches=propagate_caches)
 
1211
            delta, new_revision_id, parents)
1274
1212
 
1275
1213
    def add_revision(self, rev_id, rev, inv=None, config=None):
1276
1214
        self._ensure_real()
1535
1473
        return self._real_repository.get_signature_text(revision_id)
1536
1474
 
1537
1475
    @needs_read_lock
1538
 
    def _get_inventory_xml(self, revision_id):
1539
 
        self._ensure_real()
1540
 
        return self._real_repository._get_inventory_xml(revision_id)
 
1476
    def get_inventory_xml(self, revision_id):
 
1477
        self._ensure_real()
 
1478
        return self._real_repository.get_inventory_xml(revision_id)
 
1479
 
 
1480
    def deserialise_inventory(self, revision_id, xml):
 
1481
        self._ensure_real()
 
1482
        return self._real_repository.deserialise_inventory(revision_id, xml)
1541
1483
 
1542
1484
    def reconcile(self, other=None, thorough=False):
1543
1485
        self._ensure_real()
1619
1561
        return self._real_repository.inventories
1620
1562
 
1621
1563
    @needs_write_lock
1622
 
    def pack(self, hint=None, clean_obsolete_packs=False):
 
1564
    def pack(self, hint=None):
1623
1565
        """Compress the data within the repository.
1624
1566
 
1625
1567
        This is not currently implemented within the smart server.
1626
1568
        """
1627
1569
        self._ensure_real()
1628
 
        return self._real_repository.pack(hint=hint, clean_obsolete_packs=clean_obsolete_packs)
 
1570
        return self._real_repository.pack(hint=hint)
1629
1571
 
1630
1572
    @property
1631
1573
    def revisions(self):
2053
1995
                self._network_name)
2054
1996
 
2055
1997
    def get_format_description(self):
2056
 
        self._ensure_real()
2057
 
        return 'Remote: ' + self._custom_format.get_format_description()
 
1998
        return 'Remote BZR Branch'
2058
1999
 
2059
2000
    def network_name(self):
2060
2001
        return self._network_name
2061
2002
 
2062
 
    def open(self, a_bzrdir, name=None, ignore_fallbacks=False):
2063
 
        return a_bzrdir.open_branch(name=name, 
2064
 
            ignore_fallbacks=ignore_fallbacks)
 
2003
    def open(self, a_bzrdir, ignore_fallbacks=False):
 
2004
        return a_bzrdir.open_branch(ignore_fallbacks=ignore_fallbacks)
2065
2005
 
2066
 
    def _vfs_initialize(self, a_bzrdir, name):
 
2006
    def _vfs_initialize(self, a_bzrdir):
2067
2007
        # Initialisation when using a local bzrdir object, or a non-vfs init
2068
2008
        # method is not available on the server.
2069
2009
        # self._custom_format is always set - the start of initialize ensures
2070
2010
        # that.
2071
2011
        if isinstance(a_bzrdir, RemoteBzrDir):
2072
2012
            a_bzrdir._ensure_real()
2073
 
            result = self._custom_format.initialize(a_bzrdir._real_bzrdir,
2074
 
                name)
 
2013
            result = self._custom_format.initialize(a_bzrdir._real_bzrdir)
2075
2014
        else:
2076
2015
            # We assume the bzrdir is parameterised; it may not be.
2077
 
            result = self._custom_format.initialize(a_bzrdir, name)
 
2016
            result = self._custom_format.initialize(a_bzrdir)
2078
2017
        if (isinstance(a_bzrdir, RemoteBzrDir) and
2079
2018
            not isinstance(result, RemoteBranch)):
2080
 
            result = RemoteBranch(a_bzrdir, a_bzrdir.find_repository(), result,
2081
 
                                  name=name)
 
2019
            result = RemoteBranch(a_bzrdir, a_bzrdir.find_repository(), result)
2082
2020
        return result
2083
2021
 
2084
 
    def initialize(self, a_bzrdir, name=None):
 
2022
    def initialize(self, a_bzrdir):
2085
2023
        # 1) get the network name to use.
2086
2024
        if self._custom_format:
2087
2025
            network_name = self._custom_format.network_name()
2093
2031
            network_name = reference_format.network_name()
2094
2032
        # Being asked to create on a non RemoteBzrDir:
2095
2033
        if not isinstance(a_bzrdir, RemoteBzrDir):
2096
 
            return self._vfs_initialize(a_bzrdir, name=name)
 
2034
            return self._vfs_initialize(a_bzrdir)
2097
2035
        medium = a_bzrdir._client._medium
2098
2036
        if medium._is_remote_before((1, 13)):
2099
 
            return self._vfs_initialize(a_bzrdir, name=name)
 
2037
            return self._vfs_initialize(a_bzrdir)
2100
2038
        # Creating on a remote bzr dir.
2101
2039
        # 2) try direct creation via RPC
2102
2040
        path = a_bzrdir._path_for_remote_call(a_bzrdir._client)
2103
 
        if name is not None:
2104
 
            # XXX JRV20100304: Support creating colocated branches
2105
 
            raise errors.NoColocatedBranchSupport(self)
2106
2041
        verb = 'BzrDir.create_branch'
2107
2042
        try:
2108
2043
            response = a_bzrdir._call(verb, path, network_name)
2109
2044
        except errors.UnknownSmartMethod:
2110
2045
            # Fallback - use vfs methods
2111
2046
            medium._remember_remote_is_before((1, 13))
2112
 
            return self._vfs_initialize(a_bzrdir, name=name)
 
2047
            return self._vfs_initialize(a_bzrdir)
2113
2048
        if response[0] != 'ok':
2114
2049
            raise errors.UnexpectedSmartServerResponse(response)
2115
2050
        # Turn the response into a RemoteRepository object.
2123
2058
                a_bzrdir._client)
2124
2059
        remote_repo = RemoteRepository(repo_bzrdir, repo_format)
2125
2060
        remote_branch = RemoteBranch(a_bzrdir, remote_repo,
2126
 
            format=format, setup_stacking=False, name=name)
 
2061
            format=format, setup_stacking=False)
2127
2062
        # XXX: We know this is a new branch, so it must have revno 0, revid
2128
2063
        # NULL_REVISION. Creating the branch locked would make this be unable
2129
2064
        # to be wrong; here its simply very unlikely to be wrong. RBC 20090225
2156
2091
    """
2157
2092
 
2158
2093
    def __init__(self, remote_bzrdir, remote_repository, real_branch=None,
2159
 
        _client=None, format=None, setup_stacking=True, name=None):
 
2094
        _client=None, format=None, setup_stacking=True):
2160
2095
        """Create a RemoteBranch instance.
2161
2096
 
2162
2097
        :param real_branch: An optional local implementation of the branch
2168
2103
        :param setup_stacking: If True make an RPC call to determine the
2169
2104
            stacked (or not) status of the branch. If False assume the branch
2170
2105
            is not stacked.
2171
 
        :param name: Colocated branch name
2172
2106
        """
2173
2107
        # We intentionally don't call the parent class's __init__, because it
2174
2108
        # will try to assign to self.tags, which is a property in this subclass.
2193
2127
            self._real_branch = None
2194
2128
        # Fill out expected attributes of branch for bzrlib API users.
2195
2129
        self._clear_cached_state()
2196
 
        # TODO: deprecate self.base in favor of user_url
2197
 
        self.base = self.bzrdir.user_url
2198
 
        self._name = name
 
2130
        self.base = self.bzrdir.root_transport.base
2199
2131
        self._control_files = None
2200
2132
        self._lock_mode = None
2201
2133
        self._lock_token = None
2266
2198
                    'to use vfs implementation')
2267
2199
            self.bzrdir._ensure_real()
2268
2200
            self._real_branch = self.bzrdir._real_bzrdir.open_branch(
2269
 
                ignore_fallbacks=self._real_ignore_fallbacks, name=self._name)
 
2201
                ignore_fallbacks=self._real_ignore_fallbacks)
2270
2202
            if self.repository._real_repository is None:
2271
2203
                # Give the remote repository the matching real repo.
2272
2204
                real_repo = self._real_branch.repository
2880
2812
        raise NoSuchRevision(find('branch'), err.error_args[0])
2881
2813
    elif err.error_verb == 'nosuchrevision':
2882
2814
        raise NoSuchRevision(find('repository'), err.error_args[0])
2883
 
    elif err.error_verb == 'nobranch':
2884
 
        if len(err.error_args) >= 1:
2885
 
            extra = err.error_args[0]
2886
 
        else:
2887
 
            extra = None
2888
 
        raise errors.NotBranchError(path=find('bzrdir').root_transport.base,
2889
 
            detail=extra)
 
2815
    elif err.error_tuple == ('nobranch',):
 
2816
        raise errors.NotBranchError(path=find('bzrdir').root_transport.base)
2890
2817
    elif err.error_verb == 'norepository':
2891
2818
        raise errors.NoRepositoryPresent(find('bzrdir'))
2892
2819
    elif err.error_verb == 'LockContention':