~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/remote.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2010-09-20 16:15:26 UTC
  • mfrom: (5430.4.1 work)
  • Revision ID: pqm@pqm.ubuntu.com-20100920161526-3r87u084xg7d3pd6
(vila) Tweak tools/check-newsbug.py and do some light editing in
 doc/developers/ppa.txt. (Vincent Ladeuil)

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
    branch,
22
22
    bzrdir,
23
23
    config,
 
24
    controldir,
24
25
    debug,
25
26
    errors,
26
27
    graph,
33
34
    static_tuple,
34
35
    symbol_versioning,
35
36
)
36
 
from bzrlib.branch import BranchReferenceFormat
 
37
from bzrlib.branch import BranchReferenceFormat, BranchWriteLockResult
37
38
from bzrlib.bzrdir import BzrDir, RemoteBzrDirFormat
38
39
from bzrlib.decorators import needs_read_lock, needs_write_lock, only_raises
39
40
from bzrlib.errors import (
43
44
from bzrlib.lockable_files import LockableFiles
44
45
from bzrlib.smart import client, vfs, repository as smart_repo
45
46
from bzrlib.revision import ensure_null, NULL_REVISION
 
47
from bzrlib.repository import RepositoryWriteLockResult
46
48
from bzrlib.trace import mutter, note, warning
47
49
 
48
50
 
212
214
        if len(branch_info) != 2:
213
215
            raise errors.UnexpectedSmartServerResponse(response)
214
216
        branch_ref, branch_name = branch_info
215
 
        format = bzrdir.network_format_registry.get(control_name)
 
217
        format = controldir.network_format_registry.get(control_name)
216
218
        if repo_name:
217
219
            format.repository_format = repository.network_format_registry.get(
218
220
                repo_name)
272
274
    def create_workingtree(self, revision_id=None, from_branch=None):
273
275
        raise errors.NotLocalUrl(self.transport.base)
274
276
 
275
 
    def find_branch_format(self):
 
277
    def find_branch_format(self, name=None):
276
278
        """Find the branch 'format' for this bzrdir.
277
279
 
278
280
        This might be a synthetic object for e.g. RemoteBranch and SVN.
279
281
        """
280
 
        b = self.open_branch()
 
282
        b = self.open_branch(name=name)
281
283
        return b._format
282
284
 
283
 
    def get_branch_reference(self):
 
285
    def get_branch_reference(self, name=None):
284
286
        """See BzrDir.get_branch_reference()."""
 
287
        if name is not None:
 
288
            # XXX JRV20100304: Support opening colocated branches
 
289
            raise errors.NoColocatedBranchSupport(self)
285
290
        response = self._get_branch_reference()
286
291
        if response[0] == 'ref':
287
292
            return response[1]
318
323
            raise errors.UnexpectedSmartServerResponse(response)
319
324
        return response
320
325
 
321
 
    def _get_tree_branch(self):
 
326
    def _get_tree_branch(self, name=None):
322
327
        """See BzrDir._get_tree_branch()."""
323
 
        return None, self.open_branch()
 
328
        return None, self.open_branch(name=name)
324
329
 
325
330
    def open_branch(self, name=None, unsupported=False,
326
331
                    ignore_fallbacks=False):
644
649
 
645
650
 
646
651
class RemoteRepository(_RpcHelper, lock._RelockDebugMixin,
647
 
    bzrdir.ControlComponent):
 
652
    controldir.ControlComponent):
648
653
    """Repository accessed over rpc.
649
654
 
650
655
    For the moment most operations are performed using local transport-backed
895
900
    def _has_same_fallbacks(self, other_repo):
896
901
        """Returns true if the repositories have the same fallbacks."""
897
902
        # XXX: copied from Repository; it should be unified into a base class
898
 
        # <https://bugs.edge.launchpad.net/bzr/+bug/401622>
 
903
        # <https://bugs.launchpad.net/bzr/+bug/401622>
899
904
        my_fb = self._fallback_repositories
900
905
        other_fb = other_repo._fallback_repositories
901
906
        if len(my_fb) != len(other_fb):
997
1002
        pass
998
1003
 
999
1004
    def lock_read(self):
 
1005
        """Lock the repository for read operations.
 
1006
 
 
1007
        :return: A bzrlib.lock.LogicalLockResult.
 
1008
        """
1000
1009
        # wrong eventually - want a local lock cache context
1001
1010
        if not self._lock_mode:
1002
1011
            self._note_lock('r')
1009
1018
                repo.lock_read()
1010
1019
        else:
1011
1020
            self._lock_count += 1
 
1021
        return lock.LogicalLockResult(self.unlock)
1012
1022
 
1013
1023
    def _remote_lock_write(self, token):
1014
1024
        path = self.bzrdir._path_for_remote_call(self._client)
1054
1064
            raise errors.ReadOnlyError(self)
1055
1065
        else:
1056
1066
            self._lock_count += 1
1057
 
        return self._lock_token or None
 
1067
        return RepositoryWriteLockResult(self.unlock, self._lock_token or None)
1058
1068
 
1059
1069
    def leave_lock_in_place(self):
1060
1070
        if not self._lock_token:
1306
1316
        return self._real_repository.make_working_trees()
1307
1317
 
1308
1318
    def refresh_data(self):
1309
 
        """Re-read any data needed to to synchronise with disk.
 
1319
        """Re-read any data needed to synchronise with disk.
1310
1320
 
1311
1321
        This method is intended to be called after another repository instance
1312
1322
        (such as one used by a smart server) has inserted data into the
1313
 
        repository. It may not be called during a write group, but may be
1314
 
        called at any other time.
 
1323
        repository. On all repositories this will work outside of write groups.
 
1324
        Some repository formats (pack and newer for bzrlib native formats)
 
1325
        support refresh_data inside write groups. If called inside a write
 
1326
        group on a repository that does not support refreshing in a write group
 
1327
        IsInWriteGroupError will be raised.
1315
1328
        """
1316
 
        if self.is_in_write_group():
1317
 
            raise errors.InternalBzrError(
1318
 
                "May not refresh_data while in a write group.")
1319
1329
        if self._real_repository is not None:
1320
1330
            self._real_repository.refresh_data()
1321
1331
 
1971
1981
        if response_tuple[0] != 'ok':
1972
1982
            raise errors.UnexpectedSmartServerResponse(response_tuple)
1973
1983
        byte_stream = response_handler.read_streamed_body()
1974
 
        src_format, stream = smart_repo._byte_stream_to_stream(byte_stream)
 
1984
        src_format, stream = smart_repo._byte_stream_to_stream(byte_stream,
 
1985
            self._record_counter)
1975
1986
        if src_format.network_name() != repo._format.network_name():
1976
1987
            raise AssertionError(
1977
1988
                "Mismatched RemoteRepository and stream src %r, %r" % (
2387
2398
            self._vfs_set_tags_bytes(bytes)
2388
2399
 
2389
2400
    def lock_read(self):
 
2401
        """Lock the branch for read operations.
 
2402
 
 
2403
        :return: A bzrlib.lock.LogicalLockResult.
 
2404
        """
2390
2405
        self.repository.lock_read()
2391
2406
        if not self._lock_mode:
2392
2407
            self._note_lock('r')
2396
2411
                self._real_branch.lock_read()
2397
2412
        else:
2398
2413
            self._lock_count += 1
 
2414
        return lock.LogicalLockResult(self.unlock)
2399
2415
 
2400
2416
    def _remote_lock_write(self, token):
2401
2417
        if token is None:
2402
2418
            branch_token = repo_token = ''
2403
2419
        else:
2404
2420
            branch_token = token
2405
 
            repo_token = self.repository.lock_write()
 
2421
            repo_token = self.repository.lock_write().repository_token
2406
2422
            self.repository.unlock()
2407
2423
        err_context = {'token': token}
2408
 
        response = self._call(
2409
 
            'Branch.lock_write', self._remote_path(), branch_token,
2410
 
            repo_token or '', **err_context)
 
2424
        try:
 
2425
            response = self._call(
 
2426
                'Branch.lock_write', self._remote_path(), branch_token,
 
2427
                repo_token or '', **err_context)
 
2428
        except errors.LockContention, e:
 
2429
            # The LockContention from the server doesn't have any
 
2430
            # information about the lock_url. We re-raise LockContention
 
2431
            # with valid lock_url.
 
2432
            raise errors.LockContention('(remote lock)',
 
2433
                self.repository.base.split('.bzr/')[0])
2411
2434
        if response[0] != 'ok':
2412
2435
            raise errors.UnexpectedSmartServerResponse(response)
2413
2436
        ok, branch_token, repo_token = response
2434
2457
            self._lock_mode = 'w'
2435
2458
            self._lock_count = 1
2436
2459
        elif self._lock_mode == 'r':
2437
 
            raise errors.ReadOnlyTransaction
 
2460
            raise errors.ReadOnlyError(self)
2438
2461
        else:
2439
2462
            if token is not None:
2440
2463
                # A token was given to lock_write, and we're relocking, so
2445
2468
            self._lock_count += 1
2446
2469
            # Re-lock the repository too.
2447
2470
            self.repository.lock_write(self._repo_lock_token)
2448
 
        return self._lock_token or None
 
2471
        return BranchWriteLockResult(self.unlock, self._lock_token or None)
2449
2472
 
2450
2473
    def _unlock(self, branch_token, repo_token):
2451
2474
        err_context = {'token': str((branch_token, repo_token))}
2774
2797
        medium = self._branch._client._medium
2775
2798
        if medium._is_remote_before((1, 14)):
2776
2799
            return self._vfs_set_option(value, name, section)
 
2800
        if isinstance(value, dict):
 
2801
            if medium._is_remote_before((2, 2)):
 
2802
                return self._vfs_set_option(value, name, section)
 
2803
            return self._set_config_option_dict(value, name, section)
 
2804
        else:
 
2805
            return self._set_config_option(value, name, section)
 
2806
 
 
2807
    def _set_config_option(self, value, name, section):
2777
2808
        try:
2778
2809
            path = self._branch._remote_path()
2779
2810
            response = self._branch._client.call('Branch.set_config_option',
2780
2811
                path, self._branch._lock_token, self._branch._repo_lock_token,
2781
2812
                value.encode('utf8'), name, section or '')
2782
2813
        except errors.UnknownSmartMethod:
 
2814
            medium = self._branch._client._medium
2783
2815
            medium._remember_remote_is_before((1, 14))
2784
2816
            return self._vfs_set_option(value, name, section)
2785
2817
        if response != ():
2786
2818
            raise errors.UnexpectedSmartServerResponse(response)
2787
2819
 
 
2820
    def _serialize_option_dict(self, option_dict):
 
2821
        utf8_dict = {}
 
2822
        for key, value in option_dict.items():
 
2823
            if isinstance(key, unicode):
 
2824
                key = key.encode('utf8')
 
2825
            if isinstance(value, unicode):
 
2826
                value = value.encode('utf8')
 
2827
            utf8_dict[key] = value
 
2828
        return bencode.bencode(utf8_dict)
 
2829
 
 
2830
    def _set_config_option_dict(self, value, name, section):
 
2831
        try:
 
2832
            path = self._branch._remote_path()
 
2833
            serialised_dict = self._serialize_option_dict(value)
 
2834
            response = self._branch._client.call(
 
2835
                'Branch.set_config_option_dict',
 
2836
                path, self._branch._lock_token, self._branch._repo_lock_token,
 
2837
                serialised_dict, name, section or '')
 
2838
        except errors.UnknownSmartMethod:
 
2839
            medium = self._branch._client._medium
 
2840
            medium._remember_remote_is_before((2, 2))
 
2841
            return self._vfs_set_option(value, name, section)
 
2842
        if response != ():
 
2843
            raise errors.UnexpectedSmartServerResponse(response)
 
2844
 
2788
2845
    def _real_object(self):
2789
2846
        self._branch._ensure_real()
2790
2847
        return self._branch._real_branch