/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: Vincent Ladeuil
  • Date: 2010-03-05 08:55:12 UTC
  • mfrom: (4797.2.27 2.1-integration)
  • mto: This revision was merged to the branch mainline in revision 5075.
  • Revision ID: v.ladeuil+lp@free.fr-20100305085512-rsguvvb02fbyx7zj
Merge 2.1 into bzr.dev including fixes for #524560 and #449776

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
 
from bzrlib.branch import BranchReferenceFormat, BranchWriteLockResult
 
34
from bzrlib.branch import BranchReferenceFormat
37
35
from bzrlib.bzrdir import BzrDir, RemoteBzrDirFormat
38
36
from bzrlib.decorators import needs_read_lock, needs_write_lock, only_raises
39
37
from bzrlib.errors import (
43
41
from bzrlib.lockable_files import LockableFiles
44
42
from bzrlib.smart import client, vfs, repository as smart_repo
45
43
from bzrlib.revision import ensure_null, NULL_REVISION
46
 
from bzrlib.repository import RepositoryWriteLockResult
47
44
from bzrlib.trace import mutter, note, warning
48
45
 
49
46
 
246
243
        self._real_bzrdir.destroy_repository()
247
244
 
248
245
    def create_branch(self, name=None):
 
246
        if name is not None:
 
247
            raise errors.NoColocatedBranchSupport(self)
249
248
        # as per meta1 formats - just delegate to the format object which may
250
249
        # be parameterised.
251
 
        real_branch = self._format.get_branch_format().initialize(self,
252
 
            name=name)
 
250
        real_branch = self._format.get_branch_format().initialize(self)
253
251
        if not isinstance(real_branch, RemoteBranch):
254
 
            result = RemoteBranch(self, self.find_repository(), real_branch,
255
 
                                  name=name)
 
252
            result = RemoteBranch(self, self.find_repository(), real_branch)
256
253
        else:
257
254
            result = real_branch
258
255
        # BzrDir.clone_on_transport() uses the result of create_branch but does
273
270
    def create_workingtree(self, revision_id=None, from_branch=None):
274
271
        raise errors.NotLocalUrl(self.transport.base)
275
272
 
276
 
    def find_branch_format(self, name=None):
 
273
    def find_branch_format(self):
277
274
        """Find the branch 'format' for this bzrdir.
278
275
 
279
276
        This might be a synthetic object for e.g. RemoteBranch and SVN.
280
277
        """
281
 
        b = self.open_branch(name=name)
 
278
        b = self.open_branch()
282
279
        return b._format
283
280
 
284
 
    def get_branch_reference(self, name=None):
 
281
    def get_branch_reference(self):
285
282
        """See BzrDir.get_branch_reference()."""
286
 
        if name is not None:
287
 
            # XXX JRV20100304: Support opening colocated branches
288
 
            raise errors.NoColocatedBranchSupport(self)
289
283
        response = self._get_branch_reference()
290
284
        if response[0] == 'ref':
291
285
            return response[1]
322
316
            raise errors.UnexpectedSmartServerResponse(response)
323
317
        return response
324
318
 
325
 
    def _get_tree_branch(self, name=None):
 
319
    def _get_tree_branch(self):
326
320
        """See BzrDir._get_tree_branch()."""
327
 
        return None, self.open_branch(name=name)
 
321
        return None, self.open_branch()
328
322
 
329
323
    def open_branch(self, name=None, unsupported=False,
330
324
                    ignore_fallbacks=False):
331
325
        if unsupported:
332
326
            raise NotImplementedError('unsupported flag support not implemented yet.')
 
327
        if name is not None:
 
328
            raise errors.NoColocatedBranchSupport(self)
333
329
        if self._next_open_branch_result is not None:
334
330
            # See create_branch for details.
335
331
            result = self._next_open_branch_result
339
335
        if response[0] == 'ref':
340
336
            # a branch reference, use the existing BranchReference logic.
341
337
            format = BranchReferenceFormat()
342
 
            return format.open(self, name=name, _found=True,
343
 
                location=response[1], ignore_fallbacks=ignore_fallbacks)
 
338
            return format.open(self, _found=True, location=response[1],
 
339
                ignore_fallbacks=ignore_fallbacks)
344
340
        branch_format_name = response[1]
345
341
        if not branch_format_name:
346
342
            branch_format_name = None
347
343
        format = RemoteBranchFormat(network_name=branch_format_name)
348
344
        return RemoteBranch(self, self.find_repository(), format=format,
349
 
            setup_stacking=not ignore_fallbacks, name=name)
 
345
            setup_stacking=not ignore_fallbacks)
350
346
 
351
347
    def _open_repo_v1(self, path):
352
348
        verb = 'BzrDir.find_repository'
429
425
        """Return the path to be used for this bzrdir in a remote call."""
430
426
        return client.remote_path_from_transport(self.root_transport)
431
427
 
432
 
    def get_branch_transport(self, branch_format, name=None):
 
428
    def get_branch_transport(self, branch_format):
433
429
        self._ensure_real()
434
 
        return self._real_bzrdir.get_branch_transport(branch_format, name=name)
 
430
        return self._real_bzrdir.get_branch_transport(branch_format)
435
431
 
436
432
    def get_repository_transport(self, repository_format):
437
433
        self._ensure_real()
647
643
        return self._custom_format._serializer
648
644
 
649
645
 
650
 
class RemoteRepository(_RpcHelper, lock._RelockDebugMixin,
651
 
    bzrdir.ControlComponent):
 
646
class RemoteRepository(_RpcHelper, lock._RelockDebugMixin):
652
647
    """Repository accessed over rpc.
653
648
 
654
649
    For the moment most operations are performed using local transport-backed
697
692
        # Additional places to query for data.
698
693
        self._fallback_repositories = []
699
694
 
700
 
    @property
701
 
    def user_transport(self):
702
 
        return self.bzrdir.user_transport
703
 
 
704
 
    @property
705
 
    def control_transport(self):
706
 
        # XXX: Normally you shouldn't directly get at the remote repository
707
 
        # transport, but I'm not sure it's worth making this method
708
 
        # optional -- mbp 2010-04-21
709
 
        return self.bzrdir.get_repository_transport(None)
710
 
        
711
695
    def __str__(self):
712
696
        return "%s(%s)" % (self.__class__.__name__, self.base)
713
697
 
921
905
        parents_provider = self._make_parents_provider(other_repository)
922
906
        return graph.Graph(parents_provider)
923
907
 
924
 
    @needs_read_lock
925
 
    def get_known_graph_ancestry(self, revision_ids):
926
 
        """Return the known graph for a set of revision ids and their ancestors.
927
 
        """
928
 
        st = static_tuple.StaticTuple
929
 
        revision_keys = [st(r_id).intern() for r_id in revision_ids]
930
 
        known_graph = self.revisions.get_known_graph_ancestry(revision_keys)
931
 
        return graph.GraphThunkIdsToKeys(known_graph)
932
 
 
933
908
    def gather_stats(self, revid=None, committers=None):
934
909
        """See Repository.gather_stats()."""
935
910
        path = self.bzrdir._path_for_remote_call(self._client)
1001
976
        pass
1002
977
 
1003
978
    def lock_read(self):
1004
 
        """Lock the repository for read operations.
1005
 
 
1006
 
        :return: A bzrlib.lock.LogicalLockResult.
1007
 
        """
1008
979
        # wrong eventually - want a local lock cache context
1009
980
        if not self._lock_mode:
1010
981
            self._note_lock('r')
1017
988
                repo.lock_read()
1018
989
        else:
1019
990
            self._lock_count += 1
1020
 
        return lock.LogicalLockResult(self.unlock)
1021
991
 
1022
992
    def _remote_lock_write(self, token):
1023
993
        path = self.bzrdir._path_for_remote_call(self._client)
1063
1033
            raise errors.ReadOnlyError(self)
1064
1034
        else:
1065
1035
            self._lock_count += 1
1066
 
        return RepositoryWriteLockResult(self.unlock, self._lock_token or None)
 
1036
        return self._lock_token or None
1067
1037
 
1068
1038
    def leave_lock_in_place(self):
1069
1039
        if not self._lock_token:
1249
1219
            # state, so always add a lock here. If a caller passes us a locked
1250
1220
            # repository, they are responsible for unlocking it later.
1251
1221
            repository.lock_read()
1252
 
        self._check_fallback_repository(repository)
1253
1222
        self._fallback_repositories.append(repository)
1254
1223
        # If self._real_repository was parameterised already (e.g. because a
1255
1224
        # _real_branch had its get_stacked_on_url method called), then the
1256
1225
        # repository to be added may already be in the _real_repositories list.
1257
1226
        if self._real_repository is not None:
1258
 
            fallback_locations = [repo.user_url for repo in
 
1227
            fallback_locations = [repo.bzrdir.root_transport.base for repo in
1259
1228
                self._real_repository._fallback_repositories]
1260
 
            if repository.user_url not in fallback_locations:
 
1229
            if repository.bzrdir.root_transport.base not in fallback_locations:
1261
1230
                self._real_repository.add_fallback_repository(repository)
1262
1231
 
1263
 
    def _check_fallback_repository(self, repository):
1264
 
        """Check that this repository can fallback to repository safely.
1265
 
 
1266
 
        Raise an error if not.
1267
 
 
1268
 
        :param repository: A repository to fallback to.
1269
 
        """
1270
 
        return _mod_repository.InterRepository._assert_same_model(
1271
 
            self, repository)
1272
 
 
1273
1232
    def add_inventory(self, revid, inv, parents):
1274
1233
        self._ensure_real()
1275
1234
        return self._real_repository.add_inventory(revid, inv, parents)
1276
1235
 
1277
1236
    def add_inventory_by_delta(self, basis_revision_id, delta, new_revision_id,
1278
 
            parents, basis_inv=None, propagate_caches=False):
 
1237
                               parents):
1279
1238
        self._ensure_real()
1280
1239
        return self._real_repository.add_inventory_by_delta(basis_revision_id,
1281
 
            delta, new_revision_id, parents, basis_inv=basis_inv,
1282
 
            propagate_caches=propagate_caches)
 
1240
            delta, new_revision_id, parents)
1283
1241
 
1284
1242
    def add_revision(self, rev_id, rev, inv=None, config=None):
1285
1243
        self._ensure_real()
1315
1273
        return self._real_repository.make_working_trees()
1316
1274
 
1317
1275
    def refresh_data(self):
1318
 
        """Re-read any data needed to synchronise with disk.
 
1276
        """Re-read any data needed to to synchronise with disk.
1319
1277
 
1320
1278
        This method is intended to be called after another repository instance
1321
1279
        (such as one used by a smart server) has inserted data into the
1322
 
        repository. On all repositories this will work outside of write groups.
1323
 
        Some repository formats (pack and newer for bzrlib native formats)
1324
 
        support refresh_data inside write groups. If called inside a write
1325
 
        group on a repository that does not support refreshing in a write group
1326
 
        IsInWriteGroupError will be raised.
 
1280
        repository. It may not be called during a write group, but may be
 
1281
        called at any other time.
1327
1282
        """
 
1283
        if self.is_in_write_group():
 
1284
            raise errors.InternalBzrError(
 
1285
                "May not refresh_data while in a write group.")
1328
1286
        if self._real_repository is not None:
1329
1287
            self._real_repository.refresh_data()
1330
1288
 
1628
1586
        return self._real_repository.inventories
1629
1587
 
1630
1588
    @needs_write_lock
1631
 
    def pack(self, hint=None, clean_obsolete_packs=False):
 
1589
    def pack(self, hint=None):
1632
1590
        """Compress the data within the repository.
1633
1591
 
1634
1592
        This is not currently implemented within the smart server.
1635
1593
        """
1636
1594
        self._ensure_real()
1637
 
        return self._real_repository.pack(hint=hint, clean_obsolete_packs=clean_obsolete_packs)
 
1595
        return self._real_repository.pack(hint=hint)
1638
1596
 
1639
1597
    @property
1640
1598
    def revisions(self):
2068
2026
    def network_name(self):
2069
2027
        return self._network_name
2070
2028
 
2071
 
    def open(self, a_bzrdir, name=None, ignore_fallbacks=False):
2072
 
        return a_bzrdir.open_branch(name=name, 
2073
 
            ignore_fallbacks=ignore_fallbacks)
 
2029
    def open(self, a_bzrdir, ignore_fallbacks=False):
 
2030
        return a_bzrdir.open_branch(ignore_fallbacks=ignore_fallbacks)
2074
2031
 
2075
 
    def _vfs_initialize(self, a_bzrdir, name):
 
2032
    def _vfs_initialize(self, a_bzrdir):
2076
2033
        # Initialisation when using a local bzrdir object, or a non-vfs init
2077
2034
        # method is not available on the server.
2078
2035
        # self._custom_format is always set - the start of initialize ensures
2079
2036
        # that.
2080
2037
        if isinstance(a_bzrdir, RemoteBzrDir):
2081
2038
            a_bzrdir._ensure_real()
2082
 
            result = self._custom_format.initialize(a_bzrdir._real_bzrdir,
2083
 
                name)
 
2039
            result = self._custom_format.initialize(a_bzrdir._real_bzrdir)
2084
2040
        else:
2085
2041
            # We assume the bzrdir is parameterised; it may not be.
2086
 
            result = self._custom_format.initialize(a_bzrdir, name)
 
2042
            result = self._custom_format.initialize(a_bzrdir)
2087
2043
        if (isinstance(a_bzrdir, RemoteBzrDir) and
2088
2044
            not isinstance(result, RemoteBranch)):
2089
 
            result = RemoteBranch(a_bzrdir, a_bzrdir.find_repository(), result,
2090
 
                                  name=name)
 
2045
            result = RemoteBranch(a_bzrdir, a_bzrdir.find_repository(), result)
2091
2046
        return result
2092
2047
 
2093
 
    def initialize(self, a_bzrdir, name=None):
 
2048
    def initialize(self, a_bzrdir):
2094
2049
        # 1) get the network name to use.
2095
2050
        if self._custom_format:
2096
2051
            network_name = self._custom_format.network_name()
2102
2057
            network_name = reference_format.network_name()
2103
2058
        # Being asked to create on a non RemoteBzrDir:
2104
2059
        if not isinstance(a_bzrdir, RemoteBzrDir):
2105
 
            return self._vfs_initialize(a_bzrdir, name=name)
 
2060
            return self._vfs_initialize(a_bzrdir)
2106
2061
        medium = a_bzrdir._client._medium
2107
2062
        if medium._is_remote_before((1, 13)):
2108
 
            return self._vfs_initialize(a_bzrdir, name=name)
 
2063
            return self._vfs_initialize(a_bzrdir)
2109
2064
        # Creating on a remote bzr dir.
2110
2065
        # 2) try direct creation via RPC
2111
2066
        path = a_bzrdir._path_for_remote_call(a_bzrdir._client)
2112
 
        if name is not None:
2113
 
            # XXX JRV20100304: Support creating colocated branches
2114
 
            raise errors.NoColocatedBranchSupport(self)
2115
2067
        verb = 'BzrDir.create_branch'
2116
2068
        try:
2117
2069
            response = a_bzrdir._call(verb, path, network_name)
2118
2070
        except errors.UnknownSmartMethod:
2119
2071
            # Fallback - use vfs methods
2120
2072
            medium._remember_remote_is_before((1, 13))
2121
 
            return self._vfs_initialize(a_bzrdir, name=name)
 
2073
            return self._vfs_initialize(a_bzrdir)
2122
2074
        if response[0] != 'ok':
2123
2075
            raise errors.UnexpectedSmartServerResponse(response)
2124
2076
        # Turn the response into a RemoteRepository object.
2132
2084
                a_bzrdir._client)
2133
2085
        remote_repo = RemoteRepository(repo_bzrdir, repo_format)
2134
2086
        remote_branch = RemoteBranch(a_bzrdir, remote_repo,
2135
 
            format=format, setup_stacking=False, name=name)
 
2087
            format=format, setup_stacking=False)
2136
2088
        # XXX: We know this is a new branch, so it must have revno 0, revid
2137
2089
        # NULL_REVISION. Creating the branch locked would make this be unable
2138
2090
        # to be wrong; here its simply very unlikely to be wrong. RBC 20090225
2165
2117
    """
2166
2118
 
2167
2119
    def __init__(self, remote_bzrdir, remote_repository, real_branch=None,
2168
 
        _client=None, format=None, setup_stacking=True, name=None):
 
2120
        _client=None, format=None, setup_stacking=True):
2169
2121
        """Create a RemoteBranch instance.
2170
2122
 
2171
2123
        :param real_branch: An optional local implementation of the branch
2177
2129
        :param setup_stacking: If True make an RPC call to determine the
2178
2130
            stacked (or not) status of the branch. If False assume the branch
2179
2131
            is not stacked.
2180
 
        :param name: Colocated branch name
2181
2132
        """
2182
2133
        # We intentionally don't call the parent class's __init__, because it
2183
2134
        # will try to assign to self.tags, which is a property in this subclass.
2202
2153
            self._real_branch = None
2203
2154
        # Fill out expected attributes of branch for bzrlib API users.
2204
2155
        self._clear_cached_state()
2205
 
        # TODO: deprecate self.base in favor of user_url
2206
 
        self.base = self.bzrdir.user_url
2207
 
        self._name = name
 
2156
        self.base = self.bzrdir.root_transport.base
2208
2157
        self._control_files = None
2209
2158
        self._lock_mode = None
2210
2159
        self._lock_token = None
2275
2224
                    'to use vfs implementation')
2276
2225
            self.bzrdir._ensure_real()
2277
2226
            self._real_branch = self.bzrdir._real_bzrdir.open_branch(
2278
 
                ignore_fallbacks=self._real_ignore_fallbacks, name=self._name)
 
2227
                ignore_fallbacks=self._real_ignore_fallbacks)
2279
2228
            if self.repository._real_repository is None:
2280
2229
                # Give the remote repository the matching real repo.
2281
2230
                real_repo = self._real_branch.repository
2396
2345
            self._vfs_set_tags_bytes(bytes)
2397
2346
 
2398
2347
    def lock_read(self):
2399
 
        """Lock the branch for read operations.
2400
 
 
2401
 
        :return: A bzrlib.lock.LogicalLockResult.
2402
 
        """
2403
2348
        self.repository.lock_read()
2404
2349
        if not self._lock_mode:
2405
2350
            self._note_lock('r')
2409
2354
                self._real_branch.lock_read()
2410
2355
        else:
2411
2356
            self._lock_count += 1
2412
 
        return lock.LogicalLockResult(self.unlock)
2413
2357
 
2414
2358
    def _remote_lock_write(self, token):
2415
2359
        if token is None:
2416
2360
            branch_token = repo_token = ''
2417
2361
        else:
2418
2362
            branch_token = token
2419
 
            repo_token = self.repository.lock_write().repository_token
 
2363
            repo_token = self.repository.lock_write()
2420
2364
            self.repository.unlock()
2421
2365
        err_context = {'token': token}
2422
2366
        response = self._call(
2459
2403
            self._lock_count += 1
2460
2404
            # Re-lock the repository too.
2461
2405
            self.repository.lock_write(self._repo_lock_token)
2462
 
        return BranchWriteLockResult(self.unlock, self._lock_token or None)
 
2406
        return self._lock_token or None
2463
2407
 
2464
2408
    def _unlock(self, branch_token, repo_token):
2465
2409
        err_context = {'token': str((branch_token, repo_token))}