~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/remote.py

  • Committer: Martin Pool
  • Date: 2011-06-13 17:03:20 UTC
  • mto: This revision was merged to the branch mainline in revision 5996.
  • Revision ID: mbp@canonical.com-20110613170320-btdsj7fp63y3jb24
Further shrink export code

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
    static_tuple,
33
33
    symbol_versioning,
34
34
    urlutils,
 
35
    versionedfile,
35
36
    vf_repository,
36
37
    )
37
38
from bzrlib.branch import BranchReferenceFormat, BranchWriteLockResult
40
41
    NoSuchRevision,
41
42
    SmartProtocolError,
42
43
    )
43
 
from bzrlib.i18n import gettext
44
44
from bzrlib.lockable_files import LockableFiles
45
45
from bzrlib.smart import client, vfs, repository as smart_repo
46
46
from bzrlib.smart.client import _SmartClient
49
49
from bzrlib.trace import mutter, note, warning
50
50
 
51
51
 
52
 
_DEFAULT_SEARCH_DEPTH = 100
53
 
 
54
 
 
55
52
class _RpcHelper(object):
56
53
    """Mixin class that helps with issuing RPCs."""
57
54
 
487
484
        self._ensure_real()
488
485
        self._real_bzrdir.destroy_repository()
489
486
 
490
 
    def create_branch(self, name=None, repository=None,
491
 
                      append_revisions_only=None):
 
487
    def create_branch(self, name=None, repository=None):
492
488
        # as per meta1 formats - just delegate to the format object which may
493
489
        # be parameterised.
494
490
        real_branch = self._format.get_branch_format().initialize(self,
495
 
            name=name, repository=repository,
496
 
            append_revisions_only=append_revisions_only)
 
491
            name=name, repository=repository)
497
492
        if not isinstance(real_branch, RemoteBranch):
498
493
            if not isinstance(repository, RemoteRepository):
499
494
                raise AssertionError(
675
670
 
676
671
    def _path_for_remote_call(self, client):
677
672
        """Return the path to be used for this bzrdir in a remote call."""
678
 
        return urlutils.split_segment_parameters_raw(
679
 
            client.remote_path_from_transport(self.root_transport))[0]
 
673
        return client.remote_path_from_transport(self.root_transport)
680
674
 
681
675
    def get_branch_transport(self, branch_format, name=None):
682
676
        self._ensure_real()
742
736
        self._supports_external_lookups = None
743
737
        self._supports_tree_reference = None
744
738
        self._supports_funky_characters = None
745
 
        self._supports_nesting_repositories = None
746
739
        self._rich_root_data = None
747
740
 
748
741
    def __repr__(self):
785
778
        return self._supports_funky_characters
786
779
 
787
780
    @property
788
 
    def supports_nesting_repositories(self):
789
 
        if self._supports_nesting_repositories is None:
790
 
            self._ensure_real()
791
 
            self._supports_nesting_repositories = \
792
 
                self._custom_format.supports_nesting_repositories
793
 
        return self._supports_nesting_repositories
794
 
 
795
 
    @property
796
781
    def supports_tree_reference(self):
797
782
        if self._supports_tree_reference is None:
798
783
            self._ensure_real()
1521
1506
        # We need to accumulate additional repositories here, to pass them in
1522
1507
        # on various RPC's.
1523
1508
        #
1524
 
        # Make the check before we lock: this raises an exception.
1525
 
        self._check_fallback_repository(repository)
1526
1509
        if self.is_locked():
1527
1510
            # We will call fallback.unlock() when we transition to the unlocked
1528
1511
            # state, so always add a lock here. If a caller passes us a locked
1529
1512
            # repository, they are responsible for unlocking it later.
1530
1513
            repository.lock_read()
 
1514
        self._check_fallback_repository(repository)
1531
1515
        self._fallback_repositories.append(repository)
1532
1516
        # If self._real_repository was parameterised already (e.g. because a
1533
1517
        # _real_branch had its get_stacked_on_url method called), then the
1677
1661
        self._real_repository.create_bundle(target, base, fileobj, format)
1678
1662
 
1679
1663
    @needs_read_lock
1680
 
    @symbol_versioning.deprecated_method(
1681
 
        symbol_versioning.deprecated_in((2, 4, 0)))
1682
1664
    def get_ancestry(self, revision_id, topo_sorted=True):
1683
1665
        self._ensure_real()
1684
1666
        return self._real_repository.get_ancestry(revision_id, topo_sorted)
1698
1680
        self._ensure_real()
1699
1681
        return self._real_repository.iter_files_bytes(desired_files)
1700
1682
 
1701
 
    def get_cached_parent_map(self, revision_ids):
1702
 
        """See bzrlib.CachingParentsProvider.get_cached_parent_map"""
1703
 
        return self._unstacked_provider.get_cached_parent_map(revision_ids)
1704
 
 
1705
1683
    def get_parent_map(self, revision_ids):
1706
1684
        """See bzrlib.Graph.get_parent_map()."""
1707
1685
        return self._make_parents_provider().get_parent_map(revision_ids)
1765
1743
        if parents_map is None:
1766
1744
            # Repository is not locked, so there's no cache.
1767
1745
            parents_map = {}
1768
 
        if _DEFAULT_SEARCH_DEPTH <= 0:
1769
 
            (start_set, stop_keys,
1770
 
             key_count) = graph.search_result_from_parent_map(
1771
 
                parents_map, self._unstacked_provider.missing_keys)
1772
 
        else:
1773
 
            (start_set, stop_keys,
1774
 
             key_count) = graph.limited_search_result_from_parent_map(
1775
 
                parents_map, self._unstacked_provider.missing_keys,
1776
 
                keys, depth=_DEFAULT_SEARCH_DEPTH)
 
1746
        # start_set is all the keys in the cache
 
1747
        start_set = set(parents_map)
 
1748
        # result set is all the references to keys in the cache
 
1749
        result_parents = set()
 
1750
        for parents in parents_map.itervalues():
 
1751
            result_parents.update(parents)
 
1752
        stop_keys = result_parents.difference(start_set)
 
1753
        # We don't need to send ghosts back to the server as a position to
 
1754
        # stop either.
 
1755
        stop_keys.difference_update(self._unstacked_provider.missing_keys)
 
1756
        key_count = len(parents_map)
 
1757
        if (NULL_REVISION in result_parents
 
1758
            and NULL_REVISION in self._unstacked_provider.missing_keys):
 
1759
            # If we pruned NULL_REVISION from the stop_keys because it's also
 
1760
            # in our cache of "missing" keys we need to increment our key count
 
1761
            # by 1, because the reconsitituted SearchResult on the server will
 
1762
            # still consider NULL_REVISION to be an included key.
 
1763
            key_count += 1
 
1764
        included_keys = start_set.intersection(result_parents)
 
1765
        start_set.difference_update(included_keys)
1777
1766
        recipe = ('manual', start_set, stop_keys, key_count)
1778
1767
        body = self._serialise_search_recipe(recipe)
1779
1768
        path = self.bzrdir._path_for_remote_call(self._client)
1883
1872
        from bzrlib import osutils
1884
1873
        import tarfile
1885
1874
        # TODO: Maybe a progress bar while streaming the tarball?
1886
 
        note(gettext("Copying repository content as tarball..."))
 
1875
        note("Copying repository content as tarball...")
1887
1876
        tar_file = self._get_tarball('bz2')
1888
1877
        if tar_file is None:
1889
1878
            return None
1985
1974
    def supports_rich_root(self):
1986
1975
        return self._format.rich_root_data
1987
1976
 
1988
 
    @symbol_versioning.deprecated_method(symbol_versioning.deprecated_in((2, 4, 0)))
1989
1977
    def iter_reverse_revision_history(self, revision_id):
1990
1978
        self._ensure_real()
1991
1979
        return self._real_repository.iter_reverse_revision_history(revision_id)
2363
2351
        return a_bzrdir.open_branch(name=name, 
2364
2352
            ignore_fallbacks=ignore_fallbacks)
2365
2353
 
2366
 
    def _vfs_initialize(self, a_bzrdir, name, append_revisions_only):
 
2354
    def _vfs_initialize(self, a_bzrdir, name):
2367
2355
        # Initialisation when using a local bzrdir object, or a non-vfs init
2368
2356
        # method is not available on the server.
2369
2357
        # self._custom_format is always set - the start of initialize ensures
2371
2359
        if isinstance(a_bzrdir, RemoteBzrDir):
2372
2360
            a_bzrdir._ensure_real()
2373
2361
            result = self._custom_format.initialize(a_bzrdir._real_bzrdir,
2374
 
                name, append_revisions_only=append_revisions_only)
 
2362
                name)
2375
2363
        else:
2376
2364
            # We assume the bzrdir is parameterised; it may not be.
2377
 
            result = self._custom_format.initialize(a_bzrdir, name,
2378
 
                append_revisions_only=append_revisions_only)
 
2365
            result = self._custom_format.initialize(a_bzrdir, name)
2379
2366
        if (isinstance(a_bzrdir, RemoteBzrDir) and
2380
2367
            not isinstance(result, RemoteBranch)):
2381
2368
            result = RemoteBranch(a_bzrdir, a_bzrdir.find_repository(), result,
2382
2369
                                  name=name)
2383
2370
        return result
2384
2371
 
2385
 
    def initialize(self, a_bzrdir, name=None, repository=None,
2386
 
                   append_revisions_only=None):
 
2372
    def initialize(self, a_bzrdir, name=None, repository=None):
2387
2373
        # 1) get the network name to use.
2388
2374
        if self._custom_format:
2389
2375
            network_name = self._custom_format.network_name()
2395
2381
            network_name = reference_format.network_name()
2396
2382
        # Being asked to create on a non RemoteBzrDir:
2397
2383
        if not isinstance(a_bzrdir, RemoteBzrDir):
2398
 
            return self._vfs_initialize(a_bzrdir, name=name,
2399
 
                append_revisions_only=append_revisions_only)
 
2384
            return self._vfs_initialize(a_bzrdir, name=name)
2400
2385
        medium = a_bzrdir._client._medium
2401
2386
        if medium._is_remote_before((1, 13)):
2402
 
            return self._vfs_initialize(a_bzrdir, name=name,
2403
 
                append_revisions_only=append_revisions_only)
 
2387
            return self._vfs_initialize(a_bzrdir, name=name)
2404
2388
        # Creating on a remote bzr dir.
2405
2389
        # 2) try direct creation via RPC
2406
2390
        path = a_bzrdir._path_for_remote_call(a_bzrdir._client)
2413
2397
        except errors.UnknownSmartMethod:
2414
2398
            # Fallback - use vfs methods
2415
2399
            medium._remember_remote_is_before((1, 13))
2416
 
            return self._vfs_initialize(a_bzrdir, name=name,
2417
 
                    append_revisions_only=append_revisions_only)
 
2400
            return self._vfs_initialize(a_bzrdir, name=name)
2418
2401
        if response[0] != 'ok':
2419
2402
            raise errors.UnexpectedSmartServerResponse(response)
2420
2403
        # Turn the response into a RemoteRepository object.
2441
2424
            remote_repo = RemoteRepository(repo_bzrdir, repo_format)
2442
2425
        remote_branch = RemoteBranch(a_bzrdir, remote_repo,
2443
2426
            format=format, setup_stacking=False, name=name)
2444
 
        if append_revisions_only:
2445
 
            remote_branch.set_append_revisions_only(append_revisions_only)
2446
2427
        # XXX: We know this is a new branch, so it must have revno 0, revid
2447
2428
        # NULL_REVISION. Creating the branch locked would make this be unable
2448
2429
        # to be wrong; here its simply very unlikely to be wrong. RBC 20090225
2643
2624
                self.bzrdir, self._client)
2644
2625
        return self._control_files
2645
2626
 
2646
 
    def _get_checkout_format(self, lightweight=False):
 
2627
    def _get_checkout_format(self):
2647
2628
        self._ensure_real()
2648
 
        if lightweight:
2649
 
            format = RemoteBzrDirFormat()
2650
 
            self.bzrdir._format._supply_sub_formats_to(format)
2651
 
            format.workingtree_format = self._real_branch._get_checkout_format(
2652
 
                lightweight=lightweight).workingtree_format
2653
 
            return format
2654
 
        else:
2655
 
            return self._real_branch._get_checkout_format(lightweight=False)
 
2629
        return self._real_branch._get_checkout_format()
2656
2630
 
2657
2631
    def get_physical_lock_status(self):
2658
2632
        """See Branch.get_physical_lock_status()."""
3127
3101
        """
3128
3102
        try:
3129
3103
            configobj = self._get_configobj()
3130
 
            section_obj = None
3131
3104
            if section is None:
3132
3105
                section_obj = configobj
3133
3106
            else:
3134
3107
                try:
3135
3108
                    section_obj = configobj[section]
3136
3109
                except KeyError:
3137
 
                    pass
3138
 
            if section_obj is None:
3139
 
                value = default
3140
 
            else:
3141
 
                value = section_obj.get(name, default)
 
3110
                    return default
 
3111
            return section_obj.get(name, default)
3142
3112
        except errors.UnknownSmartMethod:
3143
 
            value = self._vfs_get_option(name, section, default)
3144
 
        for hook in config.OldConfigHooks['get']:
3145
 
            hook(self, name, value)
3146
 
        return value
 
3113
            return self._vfs_get_option(name, section, default)
3147
3114
 
3148
3115
    def _response_to_configobj(self, response):
3149
3116
        if len(response[0]) and response[0][0] != 'ok':
3150
3117
            raise errors.UnexpectedSmartServerResponse(response)
3151
3118
        lines = response[1].read_body_bytes().splitlines()
3152
 
        conf = config.ConfigObj(lines, encoding='utf-8')
3153
 
        for hook in config.OldConfigHooks['load']:
3154
 
            hook(self)
3155
 
        return conf
 
3119
        return config.ConfigObj(lines, encoding='utf-8')
3156
3120
 
3157
3121
 
3158
3122
class RemoteBranchConfig(RemoteConfig):