/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: John Arbash Meinel
  • Date: 2010-01-12 22:51:31 UTC
  • mto: This revision was merged to the branch mainline in revision 4955.
  • Revision ID: john@arbash-meinel.com-20100112225131-he8h411p6aeeb947
Delay grabbing an output stream until we actually go to show a diff.

This makes the test suite happy, but it also seems to be reasonable.
If we aren't going to write anything, we don't need to hold an
output stream open.

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
 
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
 
117
114
 
118
115
        self._probe_bzrdir()
119
116
 
120
 
    def __repr__(self):
121
 
        return '%s(%r)' % (self.__class__.__name__, self._client)
122
 
 
123
117
    def _probe_bzrdir(self):
124
118
        medium = self._client._medium
125
119
        path = self._path_for_remote_call(self._client)
245
239
        self._ensure_real()
246
240
        self._real_bzrdir.destroy_repository()
247
241
 
248
 
    def create_branch(self, name=None):
 
242
    def create_branch(self):
249
243
        # as per meta1 formats - just delegate to the format object which may
250
244
        # be parameterised.
251
 
        real_branch = self._format.get_branch_format().initialize(self,
252
 
            name=name)
 
245
        real_branch = self._format.get_branch_format().initialize(self)
253
246
        if not isinstance(real_branch, RemoteBranch):
254
 
            result = RemoteBranch(self, self.find_repository(), real_branch,
255
 
                                  name=name)
 
247
            result = RemoteBranch(self, self.find_repository(), real_branch)
256
248
        else:
257
249
            result = real_branch
258
250
        # BzrDir.clone_on_transport() uses the result of create_branch but does
264
256
        self._next_open_branch_result = result
265
257
        return result
266
258
 
267
 
    def destroy_branch(self, name=None):
 
259
    def destroy_branch(self):
268
260
        """See BzrDir.destroy_branch"""
269
261
        self._ensure_real()
270
 
        self._real_bzrdir.destroy_branch(name=name)
 
262
        self._real_bzrdir.destroy_branch()
271
263
        self._next_open_branch_result = None
272
264
 
273
265
    def create_workingtree(self, revision_id=None, from_branch=None):
292
284
    def _get_branch_reference(self):
293
285
        path = self._path_for_remote_call(self._client)
294
286
        medium = self._client._medium
295
 
        candidate_calls = [
296
 
            ('BzrDir.open_branchV3', (2, 1)),
297
 
            ('BzrDir.open_branchV2', (1, 13)),
298
 
            ('BzrDir.open_branch', None),
299
 
            ]
300
 
        for verb, required_version in candidate_calls:
301
 
            if required_version and medium._is_remote_before(required_version):
302
 
                continue
 
287
        if not medium._is_remote_before((1, 13)):
303
288
            try:
304
 
                response = self._call(verb, path)
 
289
                response = self._call('BzrDir.open_branchV2', path)
 
290
                if response[0] not in ('ref', 'branch'):
 
291
                    raise errors.UnexpectedSmartServerResponse(response)
 
292
                return response
305
293
            except errors.UnknownSmartMethod:
306
 
                if required_version is None:
307
 
                    raise
308
 
                medium._remember_remote_is_before(required_version)
309
 
            else:
310
 
                break
311
 
        if verb == 'BzrDir.open_branch':
312
 
            if response[0] != 'ok':
313
 
                raise errors.UnexpectedSmartServerResponse(response)
314
 
            if response[1] != '':
315
 
                return ('ref', response[1])
316
 
            else:
317
 
                return ('branch', '')
318
 
        if response[0] not in ('ref', 'branch'):
 
294
                medium._remember_remote_is_before((1, 13))
 
295
        response = self._call('BzrDir.open_branch', path)
 
296
        if response[0] != 'ok':
319
297
            raise errors.UnexpectedSmartServerResponse(response)
320
 
        return response
 
298
        if response[1] != '':
 
299
            return ('ref', response[1])
 
300
        else:
 
301
            return ('branch', '')
321
302
 
322
303
    def _get_tree_branch(self):
323
304
        """See BzrDir._get_tree_branch()."""
324
305
        return None, self.open_branch()
325
306
 
326
 
    def open_branch(self, name=None, unsupported=False,
327
 
                    ignore_fallbacks=False):
328
 
        if unsupported:
 
307
    def open_branch(self, _unsupported=False, ignore_fallbacks=False):
 
308
        if _unsupported:
329
309
            raise NotImplementedError('unsupported flag support not implemented yet.')
330
310
        if self._next_open_branch_result is not None:
331
311
            # See create_branch for details.
336
316
        if response[0] == 'ref':
337
317
            # a branch reference, use the existing BranchReference logic.
338
318
            format = BranchReferenceFormat()
339
 
            return format.open(self, name=name, _found=True,
340
 
                location=response[1], ignore_fallbacks=ignore_fallbacks)
 
319
            return format.open(self, _found=True, location=response[1],
 
320
                ignore_fallbacks=ignore_fallbacks)
341
321
        branch_format_name = response[1]
342
322
        if not branch_format_name:
343
323
            branch_format_name = None
344
324
        format = RemoteBranchFormat(network_name=branch_format_name)
345
325
        return RemoteBranch(self, self.find_repository(), format=format,
346
 
            setup_stacking=not ignore_fallbacks, name=name)
 
326
            setup_stacking=not ignore_fallbacks)
347
327
 
348
328
    def _open_repo_v1(self, path):
349
329
        verb = 'BzrDir.find_repository'
426
406
        """Return the path to be used for this bzrdir in a remote call."""
427
407
        return client.remote_path_from_transport(self.root_transport)
428
408
 
429
 
    def get_branch_transport(self, branch_format, name=None):
 
409
    def get_branch_transport(self, branch_format):
430
410
        self._ensure_real()
431
 
        return self._real_bzrdir.get_branch_transport(branch_format, name=name)
 
411
        return self._real_bzrdir.get_branch_transport(branch_format)
432
412
 
433
413
    def get_repository_transport(self, repository_format):
434
414
        self._ensure_real()
644
624
        return self._custom_format._serializer
645
625
 
646
626
 
647
 
class RemoteRepository(_RpcHelper, lock._RelockDebugMixin,
648
 
    bzrdir.ControlComponent):
 
627
class RemoteRepository(_RpcHelper, lock._RelockDebugMixin):
649
628
    """Repository accessed over rpc.
650
629
 
651
630
    For the moment most operations are performed using local transport-backed
694
673
        # Additional places to query for data.
695
674
        self._fallback_repositories = []
696
675
 
697
 
    @property
698
 
    def user_transport(self):
699
 
        return self.bzrdir.user_transport
700
 
 
701
 
    @property
702
 
    def control_transport(self):
703
 
        # XXX: Normally you shouldn't directly get at the remote repository
704
 
        # transport, but I'm not sure it's worth making this method
705
 
        # optional -- mbp 2010-04-21
706
 
        return self.bzrdir.get_repository_transport(None)
707
 
        
708
676
    def __str__(self):
709
677
        return "%s(%s)" % (self.__class__.__name__, self.base)
710
678
 
918
886
        parents_provider = self._make_parents_provider(other_repository)
919
887
        return graph.Graph(parents_provider)
920
888
 
921
 
    @needs_read_lock
922
 
    def get_known_graph_ancestry(self, revision_ids):
923
 
        """Return the known graph for a set of revision ids and their ancestors.
924
 
        """
925
 
        st = static_tuple.StaticTuple
926
 
        revision_keys = [st(r_id).intern() for r_id in revision_ids]
927
 
        known_graph = self.revisions.get_known_graph_ancestry(revision_keys)
928
 
        return graph.GraphThunkIdsToKeys(known_graph)
929
 
 
930
889
    def gather_stats(self, revid=None, committers=None):
931
890
        """See Repository.gather_stats()."""
932
891
        path = self.bzrdir._path_for_remote_call(self._client)
998
957
        pass
999
958
 
1000
959
    def lock_read(self):
1001
 
        """Lock the repository for read operations.
1002
 
 
1003
 
        :return: An object with an unlock method which will release the lock
1004
 
            obtained.
1005
 
        """
1006
960
        # wrong eventually - want a local lock cache context
1007
961
        if not self._lock_mode:
1008
962
            self._note_lock('r')
1015
969
                repo.lock_read()
1016
970
        else:
1017
971
            self._lock_count += 1
1018
 
        return self
1019
972
 
1020
973
    def _remote_lock_write(self, token):
1021
974
        path = self.bzrdir._path_for_remote_call(self._client)
1061
1014
            raise errors.ReadOnlyError(self)
1062
1015
        else:
1063
1016
            self._lock_count += 1
1064
 
        return RepositoryWriteLockResult(self.unlock, self._lock_token or None)
 
1017
        return self._lock_token or None
1065
1018
 
1066
1019
    def leave_lock_in_place(self):
1067
1020
        if not self._lock_token:
1247
1200
            # state, so always add a lock here. If a caller passes us a locked
1248
1201
            # repository, they are responsible for unlocking it later.
1249
1202
            repository.lock_read()
1250
 
        self._check_fallback_repository(repository)
1251
1203
        self._fallback_repositories.append(repository)
1252
1204
        # If self._real_repository was parameterised already (e.g. because a
1253
1205
        # _real_branch had its get_stacked_on_url method called), then the
1254
1206
        # repository to be added may already be in the _real_repositories list.
1255
1207
        if self._real_repository is not None:
1256
 
            fallback_locations = [repo.user_url for repo in
 
1208
            fallback_locations = [repo.bzrdir.root_transport.base for repo in
1257
1209
                self._real_repository._fallback_repositories]
1258
 
            if repository.user_url not in fallback_locations:
 
1210
            if repository.bzrdir.root_transport.base not in fallback_locations:
1259
1211
                self._real_repository.add_fallback_repository(repository)
1260
1212
 
1261
 
    def _check_fallback_repository(self, repository):
1262
 
        """Check that this repository can fallback to repository safely.
1263
 
 
1264
 
        Raise an error if not.
1265
 
 
1266
 
        :param repository: A repository to fallback to.
1267
 
        """
1268
 
        return _mod_repository.InterRepository._assert_same_model(
1269
 
            self, repository)
1270
 
 
1271
1213
    def add_inventory(self, revid, inv, parents):
1272
1214
        self._ensure_real()
1273
1215
        return self._real_repository.add_inventory(revid, inv, parents)
1274
1216
 
1275
1217
    def add_inventory_by_delta(self, basis_revision_id, delta, new_revision_id,
1276
 
            parents, basis_inv=None, propagate_caches=False):
 
1218
                               parents):
1277
1219
        self._ensure_real()
1278
1220
        return self._real_repository.add_inventory_by_delta(basis_revision_id,
1279
 
            delta, new_revision_id, parents, basis_inv=basis_inv,
1280
 
            propagate_caches=propagate_caches)
 
1221
            delta, new_revision_id, parents)
1281
1222
 
1282
1223
    def add_revision(self, rev_id, rev, inv=None, config=None):
1283
1224
        self._ensure_real()
1542
1483
        return self._real_repository.get_signature_text(revision_id)
1543
1484
 
1544
1485
    @needs_read_lock
1545
 
    def _get_inventory_xml(self, revision_id):
1546
 
        self._ensure_real()
1547
 
        return self._real_repository._get_inventory_xml(revision_id)
 
1486
    def get_inventory_xml(self, revision_id):
 
1487
        self._ensure_real()
 
1488
        return self._real_repository.get_inventory_xml(revision_id)
 
1489
 
 
1490
    def deserialise_inventory(self, revision_id, xml):
 
1491
        self._ensure_real()
 
1492
        return self._real_repository.deserialise_inventory(revision_id, xml)
1548
1493
 
1549
1494
    def reconcile(self, other=None, thorough=False):
1550
1495
        self._ensure_real()
1626
1571
        return self._real_repository.inventories
1627
1572
 
1628
1573
    @needs_write_lock
1629
 
    def pack(self, hint=None, clean_obsolete_packs=False):
 
1574
    def pack(self, hint=None):
1630
1575
        """Compress the data within the repository.
1631
1576
 
1632
1577
        This is not currently implemented within the smart server.
1633
1578
        """
1634
1579
        self._ensure_real()
1635
 
        return self._real_repository.pack(hint=hint, clean_obsolete_packs=clean_obsolete_packs)
 
1580
        return self._real_repository.pack(hint=hint)
1636
1581
 
1637
1582
    @property
1638
1583
    def revisions(self):
2066
2011
    def network_name(self):
2067
2012
        return self._network_name
2068
2013
 
2069
 
    def open(self, a_bzrdir, name=None, ignore_fallbacks=False):
2070
 
        return a_bzrdir.open_branch(name=name, 
2071
 
            ignore_fallbacks=ignore_fallbacks)
 
2014
    def open(self, a_bzrdir, ignore_fallbacks=False):
 
2015
        return a_bzrdir.open_branch(ignore_fallbacks=ignore_fallbacks)
2072
2016
 
2073
 
    def _vfs_initialize(self, a_bzrdir, name):
 
2017
    def _vfs_initialize(self, a_bzrdir):
2074
2018
        # Initialisation when using a local bzrdir object, or a non-vfs init
2075
2019
        # method is not available on the server.
2076
2020
        # self._custom_format is always set - the start of initialize ensures
2077
2021
        # that.
2078
2022
        if isinstance(a_bzrdir, RemoteBzrDir):
2079
2023
            a_bzrdir._ensure_real()
2080
 
            result = self._custom_format.initialize(a_bzrdir._real_bzrdir,
2081
 
                name)
 
2024
            result = self._custom_format.initialize(a_bzrdir._real_bzrdir)
2082
2025
        else:
2083
2026
            # We assume the bzrdir is parameterised; it may not be.
2084
 
            result = self._custom_format.initialize(a_bzrdir, name)
 
2027
            result = self._custom_format.initialize(a_bzrdir)
2085
2028
        if (isinstance(a_bzrdir, RemoteBzrDir) and
2086
2029
            not isinstance(result, RemoteBranch)):
2087
 
            result = RemoteBranch(a_bzrdir, a_bzrdir.find_repository(), result,
2088
 
                                  name=name)
 
2030
            result = RemoteBranch(a_bzrdir, a_bzrdir.find_repository(), result)
2089
2031
        return result
2090
2032
 
2091
 
    def initialize(self, a_bzrdir, name=None):
 
2033
    def initialize(self, a_bzrdir):
2092
2034
        # 1) get the network name to use.
2093
2035
        if self._custom_format:
2094
2036
            network_name = self._custom_format.network_name()
2100
2042
            network_name = reference_format.network_name()
2101
2043
        # Being asked to create on a non RemoteBzrDir:
2102
2044
        if not isinstance(a_bzrdir, RemoteBzrDir):
2103
 
            return self._vfs_initialize(a_bzrdir, name=name)
 
2045
            return self._vfs_initialize(a_bzrdir)
2104
2046
        medium = a_bzrdir._client._medium
2105
2047
        if medium._is_remote_before((1, 13)):
2106
 
            return self._vfs_initialize(a_bzrdir, name=name)
 
2048
            return self._vfs_initialize(a_bzrdir)
2107
2049
        # Creating on a remote bzr dir.
2108
2050
        # 2) try direct creation via RPC
2109
2051
        path = a_bzrdir._path_for_remote_call(a_bzrdir._client)
2110
 
        if name is not None:
2111
 
            # XXX JRV20100304: Support creating colocated branches
2112
 
            raise errors.NoColocatedBranchSupport(self)
2113
2052
        verb = 'BzrDir.create_branch'
2114
2053
        try:
2115
2054
            response = a_bzrdir._call(verb, path, network_name)
2116
2055
        except errors.UnknownSmartMethod:
2117
2056
            # Fallback - use vfs methods
2118
2057
            medium._remember_remote_is_before((1, 13))
2119
 
            return self._vfs_initialize(a_bzrdir, name=name)
 
2058
            return self._vfs_initialize(a_bzrdir)
2120
2059
        if response[0] != 'ok':
2121
2060
            raise errors.UnexpectedSmartServerResponse(response)
2122
2061
        # Turn the response into a RemoteRepository object.
2130
2069
                a_bzrdir._client)
2131
2070
        remote_repo = RemoteRepository(repo_bzrdir, repo_format)
2132
2071
        remote_branch = RemoteBranch(a_bzrdir, remote_repo,
2133
 
            format=format, setup_stacking=False, name=name)
 
2072
            format=format, setup_stacking=False)
2134
2073
        # XXX: We know this is a new branch, so it must have revno 0, revid
2135
2074
        # NULL_REVISION. Creating the branch locked would make this be unable
2136
2075
        # to be wrong; here its simply very unlikely to be wrong. RBC 20090225
2163
2102
    """
2164
2103
 
2165
2104
    def __init__(self, remote_bzrdir, remote_repository, real_branch=None,
2166
 
        _client=None, format=None, setup_stacking=True, name=None):
 
2105
        _client=None, format=None, setup_stacking=True):
2167
2106
        """Create a RemoteBranch instance.
2168
2107
 
2169
2108
        :param real_branch: An optional local implementation of the branch
2175
2114
        :param setup_stacking: If True make an RPC call to determine the
2176
2115
            stacked (or not) status of the branch. If False assume the branch
2177
2116
            is not stacked.
2178
 
        :param name: Colocated branch name
2179
2117
        """
2180
2118
        # We intentionally don't call the parent class's __init__, because it
2181
2119
        # will try to assign to self.tags, which is a property in this subclass.
2200
2138
            self._real_branch = None
2201
2139
        # Fill out expected attributes of branch for bzrlib API users.
2202
2140
        self._clear_cached_state()
2203
 
        # TODO: deprecate self.base in favor of user_url
2204
 
        self.base = self.bzrdir.user_url
2205
 
        self._name = name
 
2141
        self.base = self.bzrdir.root_transport.base
2206
2142
        self._control_files = None
2207
2143
        self._lock_mode = None
2208
2144
        self._lock_token = None
2273
2209
                    'to use vfs implementation')
2274
2210
            self.bzrdir._ensure_real()
2275
2211
            self._real_branch = self.bzrdir._real_bzrdir.open_branch(
2276
 
                ignore_fallbacks=self._real_ignore_fallbacks, name=self._name)
 
2212
                ignore_fallbacks=self._real_ignore_fallbacks)
2277
2213
            if self.repository._real_repository is None:
2278
2214
                # Give the remote repository the matching real repo.
2279
2215
                real_repo = self._real_branch.repository
2394
2330
            self._vfs_set_tags_bytes(bytes)
2395
2331
 
2396
2332
    def lock_read(self):
2397
 
        """Lock the branch for read operations.
2398
 
 
2399
 
        :return: An object with an unlock method which will release the lock
2400
 
            obtained.
2401
 
        """
2402
2333
        self.repository.lock_read()
2403
2334
        if not self._lock_mode:
2404
2335
            self._note_lock('r')
2408
2339
                self._real_branch.lock_read()
2409
2340
        else:
2410
2341
            self._lock_count += 1
2411
 
        return self
2412
2342
 
2413
2343
    def _remote_lock_write(self, token):
2414
2344
        if token is None:
2415
2345
            branch_token = repo_token = ''
2416
2346
        else:
2417
2347
            branch_token = token
2418
 
            repo_token = self.repository.lock_write().repository_token
 
2348
            repo_token = self.repository.lock_write()
2419
2349
            self.repository.unlock()
2420
2350
        err_context = {'token': token}
2421
2351
        response = self._call(
2458
2388
            self._lock_count += 1
2459
2389
            # Re-lock the repository too.
2460
2390
            self.repository.lock_write(self._repo_lock_token)
2461
 
        return BranchWriteLockResult(self.unlock, self._lock_token or None)
 
2391
        return self._lock_token or None
2462
2392
 
2463
2393
    def _unlock(self, branch_token, repo_token):
2464
2394
        err_context = {'token': str((branch_token, repo_token))}
2893
2823
        raise NoSuchRevision(find('branch'), err.error_args[0])
2894
2824
    elif err.error_verb == 'nosuchrevision':
2895
2825
        raise NoSuchRevision(find('repository'), err.error_args[0])
2896
 
    elif err.error_verb == 'nobranch':
2897
 
        if len(err.error_args) >= 1:
2898
 
            extra = err.error_args[0]
2899
 
        else:
2900
 
            extra = None
2901
 
        raise errors.NotBranchError(path=find('bzrdir').root_transport.base,
2902
 
            detail=extra)
 
2826
    elif err.error_tuple == ('nobranch',):
 
2827
        raise errors.NotBranchError(path=find('bzrdir').root_transport.base)
2903
2828
    elif err.error_verb == 'norepository':
2904
2829
        raise errors.NoRepositoryPresent(find('bzrdir'))
2905
2830
    elif err.error_verb == 'LockContention':