~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/bzrdir.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2007-04-20 08:33:47 UTC
  • mfrom: (2018.5.174 hpss)
  • Revision ID: pqm@pqm.ubuntu.com-20070420083347-m00rr4y00xjnv7or
(Andrew Bennetts, and many others) High performance smart server: add smart (non-vfs) commands to the client and server.

Show diffs side-by-side

added added

removed removed

Lines of Context:
22
22
 
23
23
# TODO: remove unittest dependency; put that stuff inside the test suite
24
24
 
25
 
# TODO: The Format probe_transport seems a bit redundant with just trying to
26
 
# open the bzrdir. -- mbp
27
 
#
28
25
# TODO: Can we move specific formats into separate modules to make this file
29
26
# smaller?
30
27
 
44
41
    lockable_files,
45
42
    lockdir,
46
43
    registry,
 
44
    remote,
47
45
    revision as _mod_revision,
48
46
    symbol_versioning,
49
47
    ui,
58
56
    sha_strings,
59
57
    sha_string,
60
58
    )
 
59
from bzrlib.smart.client import _SmartClient
61
60
from bzrlib.store.revision.text import TextRevisionStore
62
61
from bzrlib.store.text import TextStore
63
62
from bzrlib.store.versioned import WeaveStore
94
93
        If there is a tree, the tree is opened and break_lock() called.
95
94
        Otherwise, branch is tried, and finally repository.
96
95
        """
 
96
        # XXX: This seems more like a UI function than something that really
 
97
        # belongs in this class.
97
98
        try:
98
99
            thing_to_unlock = self.open_workingtree()
99
100
        except (errors.NotLocalUrl, errors.NoWorkingTree):
413
414
                    break
414
415
                else:
415
416
                    continue
416
 
            if ((found_bzrdir.root_transport.base == 
 
417
            if ((found_bzrdir.root_transport.base ==
417
418
                 self.root_transport.base) or repository.is_shared()):
418
419
                return repository
419
420
            else:
420
421
                raise errors.NoRepositoryPresent(self)
421
422
        raise errors.NoRepositoryPresent(self)
422
423
 
 
424
    def get_branch_reference(self):
 
425
        """Return the referenced URL for the branch in this bzrdir.
 
426
 
 
427
        :raises NotBranchError: If there is no Branch.
 
428
        :return: The URL the branch in this bzrdir references if it is a
 
429
            reference branch, or None for regular branches.
 
430
        """
 
431
        return None
 
432
 
423
433
    def get_branch_transport(self, branch_format):
424
434
        """Get the transport for use by branch format in this BzrDir.
425
435
 
517
527
        return BzrDir.open_from_transport(t, _unsupported=_unsupported)
518
528
 
519
529
    @staticmethod
520
 
    def open_from_transport(transport, _unsupported=False):
 
530
    def open_from_transport(transport, _unsupported=False,
 
531
                            _server_formats=True):
521
532
        """Open a bzrdir within a particular directory.
522
533
 
523
534
        :param transport: Transport containing the bzrdir.
526
537
        base = transport.base
527
538
 
528
539
        def find_format(transport):
529
 
            return transport, BzrDirFormat.find_format(transport)
 
540
            return transport, BzrDirFormat.find_format(
 
541
                transport, _server_formats=_server_formats)
530
542
 
531
543
        def redirected(transport, e, redirection_notice):
532
544
            qualified_source = e.get_source_url()
598
610
                return result, urlutils.unescape(a_transport.relpath(url))
599
611
            except errors.NotBranchError, e:
600
612
                pass
601
 
            new_t = a_transport.clone('..')
 
613
            try:
 
614
                new_t = a_transport.clone('..')
 
615
            except errors.InvalidURLJoin:
 
616
                # reached the root, whatever that may be
 
617
                raise errors.NotBranchError(path=url)
602
618
            if new_t.base == a_transport.base:
603
619
                # reached the root, whatever that may be
604
620
                raise errors.NotBranchError(path=url)
677
693
            return False
678
694
 
679
695
    def _cloning_metadir(self):
 
696
        """Produce a metadir suitable for cloning with"""
680
697
        result_format = self._format.__class__()
681
698
        try:
682
699
            try:
685
702
            except errors.NotBranchError:
686
703
                source_branch = None
687
704
                source_repository = self.open_repository()
688
 
            result_format.repository_format = source_repository._format
689
705
        except errors.NoRepositoryPresent:
690
706
            source_repository = None
 
707
        else:
 
708
            # XXX TODO: This isinstance is here because we have not implemented
 
709
            # the fix recommended in bug # 103195 - to delegate this choice the
 
710
            # repository itself.
 
711
            repo_format = source_repository._format
 
712
            if not isinstance(repo_format, remote.RemoteRepositoryFormat):
 
713
                result_format.repository_format = repo_format
691
714
        try:
692
715
            # TODO: Couldn't we just probe for the format in these cases,
693
716
            # rather than opening the whole tree?  It would be a little
1048
1071
    def destroy_workingtree_metadata(self):
1049
1072
        self.transport.delete_tree('checkout')
1050
1073
 
 
1074
    def find_branch_format(self):
 
1075
        """Find the branch 'format' for this bzrdir.
 
1076
 
 
1077
        This might be a synthetic object for e.g. RemoteBranch and SVN.
 
1078
        """
 
1079
        from bzrlib.branch import BranchFormat
 
1080
        return BranchFormat.find_format(self)
 
1081
 
1051
1082
    def _get_mkdir_mode(self):
1052
1083
        """Figure out the mode to use when creating a bzrdir subdir."""
1053
1084
        temp_control = lockable_files.LockableFiles(self.transport, '',
1054
1085
                                     lockable_files.TransportLock)
1055
1086
        return temp_control._dir_mode
1056
1087
 
 
1088
    def get_branch_reference(self):
 
1089
        """See BzrDir.get_branch_reference()."""
 
1090
        from bzrlib.branch import BranchFormat
 
1091
        format = BranchFormat.find_format(self)
 
1092
        return format.get_reference(self)
 
1093
 
1057
1094
    def get_branch_transport(self, branch_format):
1058
1095
        """See BzrDir.get_branch_transport()."""
1059
1096
        if branch_format is None:
1130
1167
 
1131
1168
    def open_branch(self, unsupported=False):
1132
1169
        """See BzrDir.open_branch."""
1133
 
        from bzrlib.branch import BranchFormat
1134
 
        format = BranchFormat.find_format(self)
 
1170
        format = self.find_branch_format()
1135
1171
        self._check_supported(format, unsupported)
1136
1172
        return format.open(self, _found=True)
1137
1173
 
1182
1218
    This is a list of BzrDirFormat objects.
1183
1219
    """
1184
1220
 
 
1221
    _control_server_formats = []
 
1222
    """The registered control server formats, e.g. RemoteBzrDirs.
 
1223
 
 
1224
    This is a list of BzrDirFormat objects.
 
1225
    """
 
1226
 
1185
1227
    _lock_file_name = 'branch-lock'
1186
1228
 
1187
1229
    # _lock_class must be set in subclasses to the lock type, typ.
1188
1230
    # TransportLock or LockDir
1189
1231
 
1190
1232
    @classmethod
1191
 
    def find_format(klass, transport):
 
1233
    def find_format(klass, transport, _server_formats=True):
1192
1234
        """Return the format present at transport."""
1193
 
        for format in klass._control_formats:
 
1235
        if _server_formats:
 
1236
            formats = klass._control_server_formats + klass._control_formats
 
1237
        else:
 
1238
            formats = klass._control_formats
 
1239
        for format in formats:
1194
1240
            try:
1195
1241
                return format.probe_transport(transport)
1196
1242
            except errors.NotBranchError:
1200
1246
 
1201
1247
    @classmethod
1202
1248
    def probe_transport(klass, transport):
1203
 
        """Return the .bzrdir style transport present at URL."""
 
1249
        """Return the .bzrdir style format present in a directory."""
1204
1250
        try:
1205
1251
            format_string = transport.get(".bzr/branch-format").read()
1206
1252
        except errors.NoSuchFile:
1346
1392
        klass._control_formats.append(format)
1347
1393
 
1348
1394
    @classmethod
 
1395
    def register_control_server_format(klass, format):
 
1396
        """Register a control format for client-server environments.
 
1397
 
 
1398
        These formats will be tried before ones registered with
 
1399
        register_control_format.  This gives implementations that decide to the
 
1400
        chance to grab it before anything looks at the contents of the format
 
1401
        file.
 
1402
        """
 
1403
        klass._control_server_formats.append(format)
 
1404
 
 
1405
    @classmethod
1349
1406
    @symbol_versioning.deprecated_method(symbol_versioning.zero_fourteen)
1350
1407
    def set_default_format(klass, format):
1351
1408
        klass._set_default_format(format)
1645
1702
    easy to identify.
1646
1703
    """
1647
1704
 
1648
 
    def __init__(self, transport_server, transport_readonly_server, formats):
 
1705
    def __init__(self, vfs_factory, transport_server, transport_readonly_server,
 
1706
        formats):
 
1707
        """Create an object to adapt tests.
 
1708
 
 
1709
        :param vfs_server: A factory to create a Transport Server which has
 
1710
            all the VFS methods working, and is writable.
 
1711
        """
 
1712
        self._vfs_factory = vfs_factory
1649
1713
        self._transport_server = transport_server
1650
1714
        self._transport_readonly_server = transport_readonly_server
1651
1715
        self._formats = formats
1654
1718
        result = unittest.TestSuite()
1655
1719
        for format in self._formats:
1656
1720
            new_test = deepcopy(test)
 
1721
            new_test.vfs_transport_factory = self._vfs_factory
1657
1722
            new_test.transport_server = self._transport_server
1658
1723
            new_test.transport_readonly_server = self._transport_readonly_server
1659
1724
            new_test.bzrdir_format = format
2153
2218
        return to_convert
2154
2219
 
2155
2220
 
 
2221
# This is not in remote.py because it's small, and needs to be registered.
 
2222
# Putting it in remote.py creates a circular import problem.
 
2223
# we can make it a lazy object if the control formats is turned into something
 
2224
# like a registry.
 
2225
class RemoteBzrDirFormat(BzrDirMetaFormat1):
 
2226
    """Format representing bzrdirs accessed via a smart server"""
 
2227
 
 
2228
    def get_format_description(self):
 
2229
        return 'bzr remote bzrdir'
 
2230
    
 
2231
    @classmethod
 
2232
    def probe_transport(klass, transport):
 
2233
        """Return a RemoteBzrDirFormat object if it looks possible."""
 
2234
        try:
 
2235
            transport.get_smart_client()
 
2236
        except (NotImplementedError, AttributeError,
 
2237
                errors.TransportNotPossible):
 
2238
            # no smart server, so not a branch for this format type.
 
2239
            raise errors.NotBranchError(path=transport.base)
 
2240
        else:
 
2241
            return klass()
 
2242
 
 
2243
    def initialize_on_transport(self, transport):
 
2244
        try:
 
2245
            # hand off the request to the smart server
 
2246
            medium = transport.get_smart_medium()
 
2247
        except errors.NoSmartMedium:
 
2248
            # TODO: lookup the local format from a server hint.
 
2249
            local_dir_format = BzrDirMetaFormat1()
 
2250
            return local_dir_format.initialize_on_transport(transport)
 
2251
        client = _SmartClient(medium)
 
2252
        path = client.remote_path_from_transport(transport)
 
2253
        response = _SmartClient(medium).call('BzrDirFormat.initialize', path)
 
2254
        assert response[0] in ('ok', ), 'unexpected response code %s' % (response,)
 
2255
        return remote.RemoteBzrDir(transport)
 
2256
 
 
2257
    def _open(self, transport):
 
2258
        return remote.RemoteBzrDir(transport)
 
2259
 
 
2260
    def __eq__(self, other):
 
2261
        if not isinstance(other, RemoteBzrDirFormat):
 
2262
            return False
 
2263
        return self.get_format_description() == other.get_format_description()
 
2264
 
 
2265
 
 
2266
BzrDirFormat.register_control_server_format(RemoteBzrDirFormat)
 
2267
 
 
2268
 
2156
2269
class BzrDirFormatInfo(object):
2157
2270
 
2158
2271
    def __init__(self, native, deprecated, hidden):