~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/remote.py

  • Committer: Neil Santos
  • Date: 2010-03-04 02:43:41 UTC
  • mto: (5080.1.1 integration)
  • mto: This revision was merged to the branch mainline in revision 5081.
  • Revision ID: neil_santos@users.sourceforge.net-20100304024341-ra7njxj4lzjb46rl
Removed separate lstat() and reverted LocalTransport and SFTPTransport's stat() methods to using lstat() internally.
Reworked how SFTPTransport's symlink() handles success and signals failure.
Removed lstat() declaration on the Transport base class.

Show diffs side-by-side

added added

removed removed

Lines of Context:
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
244
242
        self._ensure_real()
245
243
        self._real_bzrdir.destroy_repository()
246
244
 
247
 
    def create_branch(self, name=None):
 
245
    def create_branch(self):
248
246
        # as per meta1 formats - just delegate to the format object which may
249
247
        # be parameterised.
250
 
        real_branch = self._format.get_branch_format().initialize(self,
251
 
            name=name)
 
248
        real_branch = self._format.get_branch_format().initialize(self)
252
249
        if not isinstance(real_branch, RemoteBranch):
253
 
            result = RemoteBranch(self, self.find_repository(), real_branch,
254
 
                                  name=name)
 
250
            result = RemoteBranch(self, self.find_repository(), real_branch)
255
251
        else:
256
252
            result = real_branch
257
253
        # BzrDir.clone_on_transport() uses the result of create_branch but does
263
259
        self._next_open_branch_result = result
264
260
        return result
265
261
 
266
 
    def destroy_branch(self, name=None):
 
262
    def destroy_branch(self):
267
263
        """See BzrDir.destroy_branch"""
268
264
        self._ensure_real()
269
 
        self._real_bzrdir.destroy_branch(name=name)
 
265
        self._real_bzrdir.destroy_branch()
270
266
        self._next_open_branch_result = None
271
267
 
272
268
    def create_workingtree(self, revision_id=None, from_branch=None):
322
318
        """See BzrDir._get_tree_branch()."""
323
319
        return None, self.open_branch()
324
320
 
325
 
    def open_branch(self, name=None, unsupported=False,
326
 
                    ignore_fallbacks=False):
327
 
        if unsupported:
 
321
    def open_branch(self, _unsupported=False, ignore_fallbacks=False):
 
322
        if _unsupported:
328
323
            raise NotImplementedError('unsupported flag support not implemented yet.')
329
324
        if self._next_open_branch_result is not None:
330
325
            # See create_branch for details.
335
330
        if response[0] == 'ref':
336
331
            # a branch reference, use the existing BranchReference logic.
337
332
            format = BranchReferenceFormat()
338
 
            return format.open(self, name=name, _found=True,
339
 
                location=response[1], ignore_fallbacks=ignore_fallbacks)
 
333
            return format.open(self, _found=True, location=response[1],
 
334
                ignore_fallbacks=ignore_fallbacks)
340
335
        branch_format_name = response[1]
341
336
        if not branch_format_name:
342
337
            branch_format_name = None
343
338
        format = RemoteBranchFormat(network_name=branch_format_name)
344
339
        return RemoteBranch(self, self.find_repository(), format=format,
345
 
            setup_stacking=not ignore_fallbacks, name=name)
 
340
            setup_stacking=not ignore_fallbacks)
346
341
 
347
342
    def _open_repo_v1(self, path):
348
343
        verb = 'BzrDir.find_repository'
425
420
        """Return the path to be used for this bzrdir in a remote call."""
426
421
        return client.remote_path_from_transport(self.root_transport)
427
422
 
428
 
    def get_branch_transport(self, branch_format, name=None):
 
423
    def get_branch_transport(self, branch_format):
429
424
        self._ensure_real()
430
 
        return self._real_bzrdir.get_branch_transport(branch_format, name=name)
 
425
        return self._real_bzrdir.get_branch_transport(branch_format)
431
426
 
432
427
    def get_repository_transport(self, repository_format):
433
428
        self._ensure_real()
643
638
        return self._custom_format._serializer
644
639
 
645
640
 
646
 
class RemoteRepository(_RpcHelper, lock._RelockDebugMixin,
647
 
    bzrdir.ControlComponent):
 
641
class RemoteRepository(_RpcHelper, lock._RelockDebugMixin):
648
642
    """Repository accessed over rpc.
649
643
 
650
644
    For the moment most operations are performed using local transport-backed
693
687
        # Additional places to query for data.
694
688
        self._fallback_repositories = []
695
689
 
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
690
    def __str__(self):
708
691
        return "%s(%s)" % (self.__class__.__name__, self.base)
709
692
 
917
900
        parents_provider = self._make_parents_provider(other_repository)
918
901
        return graph.Graph(parents_provider)
919
902
 
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
903
    def gather_stats(self, revid=None, committers=None):
930
904
        """See Repository.gather_stats()."""
931
905
        path = self.bzrdir._path_for_remote_call(self._client)
1240
1214
            # state, so always add a lock here. If a caller passes us a locked
1241
1215
            # repository, they are responsible for unlocking it later.
1242
1216
            repository.lock_read()
1243
 
        self._check_fallback_repository(repository)
1244
1217
        self._fallback_repositories.append(repository)
1245
1218
        # If self._real_repository was parameterised already (e.g. because a
1246
1219
        # _real_branch had its get_stacked_on_url method called), then the
1247
1220
        # repository to be added may already be in the _real_repositories list.
1248
1221
        if self._real_repository is not None:
1249
 
            fallback_locations = [repo.user_url for repo in
 
1222
            fallback_locations = [repo.bzrdir.root_transport.base for repo in
1250
1223
                self._real_repository._fallback_repositories]
1251
 
            if repository.user_url not in fallback_locations:
 
1224
            if repository.bzrdir.root_transport.base not in fallback_locations:
1252
1225
                self._real_repository.add_fallback_repository(repository)
1253
1226
 
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
1227
    def add_inventory(self, revid, inv, parents):
1265
1228
        self._ensure_real()
1266
1229
        return self._real_repository.add_inventory(revid, inv, parents)
1267
1230
 
1268
1231
    def add_inventory_by_delta(self, basis_revision_id, delta, new_revision_id,
1269
 
            parents, basis_inv=None, propagate_caches=False):
 
1232
                               parents):
1270
1233
        self._ensure_real()
1271
1234
        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)
 
1235
            delta, new_revision_id, parents)
1274
1236
 
1275
1237
    def add_revision(self, rev_id, rev, inv=None, config=None):
1276
1238
        self._ensure_real()
1619
1581
        return self._real_repository.inventories
1620
1582
 
1621
1583
    @needs_write_lock
1622
 
    def pack(self, hint=None, clean_obsolete_packs=False):
 
1584
    def pack(self, hint=None):
1623
1585
        """Compress the data within the repository.
1624
1586
 
1625
1587
        This is not currently implemented within the smart server.
1626
1588
        """
1627
1589
        self._ensure_real()
1628
 
        return self._real_repository.pack(hint=hint, clean_obsolete_packs=clean_obsolete_packs)
 
1590
        return self._real_repository.pack(hint=hint)
1629
1591
 
1630
1592
    @property
1631
1593
    def revisions(self):
2059
2021
    def network_name(self):
2060
2022
        return self._network_name
2061
2023
 
2062
 
    def open(self, a_bzrdir, name=None, ignore_fallbacks=False):
2063
 
        return a_bzrdir.open_branch(name=name, 
2064
 
            ignore_fallbacks=ignore_fallbacks)
 
2024
    def open(self, a_bzrdir, ignore_fallbacks=False):
 
2025
        return a_bzrdir.open_branch(ignore_fallbacks=ignore_fallbacks)
2065
2026
 
2066
 
    def _vfs_initialize(self, a_bzrdir, name):
 
2027
    def _vfs_initialize(self, a_bzrdir):
2067
2028
        # Initialisation when using a local bzrdir object, or a non-vfs init
2068
2029
        # method is not available on the server.
2069
2030
        # self._custom_format is always set - the start of initialize ensures
2070
2031
        # that.
2071
2032
        if isinstance(a_bzrdir, RemoteBzrDir):
2072
2033
            a_bzrdir._ensure_real()
2073
 
            result = self._custom_format.initialize(a_bzrdir._real_bzrdir,
2074
 
                name)
 
2034
            result = self._custom_format.initialize(a_bzrdir._real_bzrdir)
2075
2035
        else:
2076
2036
            # We assume the bzrdir is parameterised; it may not be.
2077
 
            result = self._custom_format.initialize(a_bzrdir, name)
 
2037
            result = self._custom_format.initialize(a_bzrdir)
2078
2038
        if (isinstance(a_bzrdir, RemoteBzrDir) and
2079
2039
            not isinstance(result, RemoteBranch)):
2080
 
            result = RemoteBranch(a_bzrdir, a_bzrdir.find_repository(), result,
2081
 
                                  name=name)
 
2040
            result = RemoteBranch(a_bzrdir, a_bzrdir.find_repository(), result)
2082
2041
        return result
2083
2042
 
2084
 
    def initialize(self, a_bzrdir, name=None):
 
2043
    def initialize(self, a_bzrdir):
2085
2044
        # 1) get the network name to use.
2086
2045
        if self._custom_format:
2087
2046
            network_name = self._custom_format.network_name()
2093
2052
            network_name = reference_format.network_name()
2094
2053
        # Being asked to create on a non RemoteBzrDir:
2095
2054
        if not isinstance(a_bzrdir, RemoteBzrDir):
2096
 
            return self._vfs_initialize(a_bzrdir, name=name)
 
2055
            return self._vfs_initialize(a_bzrdir)
2097
2056
        medium = a_bzrdir._client._medium
2098
2057
        if medium._is_remote_before((1, 13)):
2099
 
            return self._vfs_initialize(a_bzrdir, name=name)
 
2058
            return self._vfs_initialize(a_bzrdir)
2100
2059
        # Creating on a remote bzr dir.
2101
2060
        # 2) try direct creation via RPC
2102
2061
        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
2062
        verb = 'BzrDir.create_branch'
2107
2063
        try:
2108
2064
            response = a_bzrdir._call(verb, path, network_name)
2109
2065
        except errors.UnknownSmartMethod:
2110
2066
            # Fallback - use vfs methods
2111
2067
            medium._remember_remote_is_before((1, 13))
2112
 
            return self._vfs_initialize(a_bzrdir, name=name)
 
2068
            return self._vfs_initialize(a_bzrdir)
2113
2069
        if response[0] != 'ok':
2114
2070
            raise errors.UnexpectedSmartServerResponse(response)
2115
2071
        # Turn the response into a RemoteRepository object.
2123
2079
                a_bzrdir._client)
2124
2080
        remote_repo = RemoteRepository(repo_bzrdir, repo_format)
2125
2081
        remote_branch = RemoteBranch(a_bzrdir, remote_repo,
2126
 
            format=format, setup_stacking=False, name=name)
 
2082
            format=format, setup_stacking=False)
2127
2083
        # XXX: We know this is a new branch, so it must have revno 0, revid
2128
2084
        # NULL_REVISION. Creating the branch locked would make this be unable
2129
2085
        # to be wrong; here its simply very unlikely to be wrong. RBC 20090225
2156
2112
    """
2157
2113
 
2158
2114
    def __init__(self, remote_bzrdir, remote_repository, real_branch=None,
2159
 
        _client=None, format=None, setup_stacking=True, name=None):
 
2115
        _client=None, format=None, setup_stacking=True):
2160
2116
        """Create a RemoteBranch instance.
2161
2117
 
2162
2118
        :param real_branch: An optional local implementation of the branch
2168
2124
        :param setup_stacking: If True make an RPC call to determine the
2169
2125
            stacked (or not) status of the branch. If False assume the branch
2170
2126
            is not stacked.
2171
 
        :param name: Colocated branch name
2172
2127
        """
2173
2128
        # We intentionally don't call the parent class's __init__, because it
2174
2129
        # will try to assign to self.tags, which is a property in this subclass.
2193
2148
            self._real_branch = None
2194
2149
        # Fill out expected attributes of branch for bzrlib API users.
2195
2150
        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
 
2151
        self.base = self.bzrdir.root_transport.base
2199
2152
        self._control_files = None
2200
2153
        self._lock_mode = None
2201
2154
        self._lock_token = None
2266
2219
                    'to use vfs implementation')
2267
2220
            self.bzrdir._ensure_real()
2268
2221
            self._real_branch = self.bzrdir._real_bzrdir.open_branch(
2269
 
                ignore_fallbacks=self._real_ignore_fallbacks, name=self._name)
 
2222
                ignore_fallbacks=self._real_ignore_fallbacks)
2270
2223
            if self.repository._real_repository is None:
2271
2224
                # Give the remote repository the matching real repo.
2272
2225
                real_repo = self._real_branch.repository