/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/bzrdir.py

1st cut merge of bzr.dev r3907

Show diffs side-by-side

added added

removed removed

Lines of Context:
27
27
 
28
28
# TODO: Move old formats into a plugin to make this file smaller.
29
29
 
30
 
from cStringIO import StringIO
31
30
import os
32
31
import sys
33
32
 
35
34
lazy_import(globals(), """
36
35
from stat import S_ISDIR
37
36
import textwrap
38
 
from warnings import warn
39
37
 
40
38
import bzrlib
41
39
from bzrlib import (
45
43
    lockable_files,
46
44
    lockdir,
47
45
    osutils,
48
 
    registry,
49
46
    remote,
50
47
    revision as _mod_revision,
51
 
    symbol_versioning,
52
48
    ui,
53
49
    urlutils,
54
50
    versionedfile,
59
55
    xml5,
60
56
    )
61
57
from bzrlib.osutils import (
62
 
    sha_strings,
63
58
    sha_string,
64
59
    )
65
 
from bzrlib.repository import Repository
66
60
from bzrlib.smart.client import _SmartClient
67
 
from bzrlib.smart import protocol
68
61
from bzrlib.store.versioned import WeaveStore
69
62
from bzrlib.transactions import WriteTransaction
70
63
from bzrlib.transport import (
71
64
    do_catching_redirections,
72
65
    get_transport,
 
66
    local,
73
67
    )
74
68
from bzrlib.weave import Weave
75
69
""")
78
72
    mutter,
79
73
    note,
80
74
    )
81
 
from bzrlib.transport.local import LocalTransport
82
 
from bzrlib.symbol_versioning import (
83
 
    deprecated_function,
84
 
    deprecated_method,
 
75
 
 
76
from bzrlib import (
 
77
    registry,
 
78
    symbol_versioning,
85
79
    )
86
80
 
87
81
 
177
171
                                       preserve_stacking=preserve_stacking)
178
172
 
179
173
    def clone_on_transport(self, transport, revision_id=None,
180
 
                           force_new_repo=False, preserve_stacking=False):
 
174
                           force_new_repo=False, preserve_stacking=False,
 
175
                           stacked_on=None):
181
176
        """Clone this bzrdir and its contents to transport verbatim.
182
177
 
183
178
        :param transport: The transport for the location to produce the clone
191
186
            new branch on top of the other branch's stacked-on branch.
192
187
        """
193
188
        transport.ensure_base()
194
 
        result = self.cloning_metadir().initialize_on_transport(transport)
 
189
        require_stacking = (stacked_on is not None)
 
190
        metadir = self.cloning_metadir(require_stacking)
 
191
        result = metadir.initialize_on_transport(transport)
195
192
        repository_policy = None
196
 
        stack_on = None
197
193
        try:
198
194
            local_repo = self.find_repository()
199
195
        except errors.NoRepositoryPresent:
208
204
                local_repo = local_branch.repository
209
205
            if preserve_stacking:
210
206
                try:
211
 
                    stack_on = local_branch.get_stacked_on_url()
 
207
                    stacked_on = local_branch.get_stacked_on_url()
212
208
                except (errors.UnstackableBranchFormat,
213
209
                        errors.UnstackableRepositoryFormat,
214
210
                        errors.NotStacked):
217
213
        if local_repo:
218
214
            # may need to copy content in
219
215
            repository_policy = result.determine_repository_policy(
220
 
                force_new_repo, stack_on, self.root_transport.base)
 
216
                force_new_repo, stacked_on, self.root_transport.base,
 
217
                require_stacking=require_stacking)
221
218
            make_working_trees = local_repo.make_working_trees()
222
219
            result_repo = repository_policy.acquire_repository(
223
220
                make_working_trees, local_repo.is_shared())
471
468
        if force_new_tree:
472
469
            # check for non local urls
473
470
            t = get_transport(base, possible_transports)
474
 
            if not isinstance(t, LocalTransport):
 
471
            if not isinstance(t, local.LocalTransport):
475
472
                raise errors.NotLocalUrl(base)
476
473
        bzrdir = BzrDir.create(base, format, possible_transports)
477
474
        repo = bzrdir._find_or_create_repository(force_new_repo)
499
496
        :return: The WorkingTree object.
500
497
        """
501
498
        t = get_transport(base)
502
 
        if not isinstance(t, LocalTransport):
 
499
        if not isinstance(t, local.LocalTransport):
503
500
            raise errors.NotLocalUrl(base)
504
501
        bzrdir = BzrDir.create_branch_and_repo(base,
505
502
                                               force_new_repo=True,
519
516
        """
520
517
        raise NotImplementedError(self.create_workingtree)
521
518
 
 
519
    def backup_bzrdir(self):
 
520
        """Backup this bzr control directory.
 
521
        
 
522
        :return: Tuple with old path name and new path name
 
523
        """
 
524
        self.root_transport.copy_tree('.bzr', 'backup.bzr')
 
525
        return (self.root_transport.abspath('.bzr'),
 
526
                self.root_transport.abspath('backup.bzr'))
 
527
 
522
528
    def retire_bzrdir(self, limit=10000):
523
529
        """Permanently disable the bzrdir.
524
530
 
637
643
 
638
644
    def _find_creation_modes(self):
639
645
        """Determine the appropriate modes for files and directories.
640
 
        
 
646
 
641
647
        They're always set to be consistent with the base directory,
642
648
        assuming that this transport allows setting modes.
643
649
        """
656
662
            # directories and files are read-write for this user. This is
657
663
            # mostly a workaround for filesystems which lie about being able to
658
664
            # write to a directory (cygwin & win32)
659
 
            self._dir_mode = (st.st_mode & 07777) | 00700
660
 
            # Remove the sticky and execute bits for files
661
 
            self._file_mode = self._dir_mode & ~07111
 
665
            if (st.st_mode & 07777 == 00000):
 
666
                # FTP allows stat but does not return dir/file modes
 
667
                self._dir_mode = None
 
668
                self._file_mode = None
 
669
            else:
 
670
                self._dir_mode = (st.st_mode & 07777) | 00700
 
671
                # Remove the sticky and execute bits for files
 
672
                self._file_mode = self._dir_mode & ~07111
662
673
 
663
674
    def _get_file_mode(self):
664
675
        """Return Unix mode for newly created files, or None.
771
782
        :param transport: Transport containing the bzrdir.
772
783
        :param _unsupported: private.
773
784
        """
 
785
        # Keep initial base since 'transport' may be modified while following
 
786
        # the redirections.
774
787
        base = transport.base
775
 
 
776
788
        def find_format(transport):
777
789
            return transport, BzrDirFormat.find_format(
778
790
                transport, _server_formats=_server_formats)
779
791
 
780
792
        def redirected(transport, e, redirection_notice):
781
 
            qualified_source = e.get_source_url()
782
 
            relpath = transport.relpath(qualified_source)
783
 
            if not e.target.endswith(relpath):
784
 
                # Not redirected to a branch-format, not a branch
785
 
                raise errors.NotBranchError(path=e.target)
786
 
            target = e.target[:-len(relpath)]
 
793
            redirected_transport = transport._redirected_to(e.source, e.target)
 
794
            if redirected_transport is None:
 
795
                raise errors.NotBranchError(base)
787
796
            note('%s is%s redirected to %s',
788
 
                 transport.base, e.permanently, target)
789
 
            # Let's try with a new transport
790
 
            # FIXME: If 'transport' has a qualifier, this should
791
 
            # be applied again to the new transport *iff* the
792
 
            # schemes used are the same. Uncomment this code
793
 
            # once the function (and tests) exist.
794
 
            # -- vila20070212
795
 
            #target = urlutils.copy_url_qualifiers(original, target)
796
 
            return get_transport(target)
 
797
                 transport.base, e.permanently, redirected_transport.base)
 
798
            return redirected_transport
797
799
 
798
800
        try:
799
801
            transport, format = do_catching_redirections(find_format,
988
990
            try:
989
991
                branch = self.open_branch()
990
992
                source_repository = branch.repository
 
993
                result_format._branch_format = branch._format
991
994
            except errors.NotBranchError:
992
995
                source_branch = None
993
996
                source_repository = self.open_repository()
998
1001
            # the fix recommended in bug # 103195 - to delegate this choice the
999
1002
            # repository itself.
1000
1003
            repo_format = source_repository._format
1001
 
            if not isinstance(repo_format, remote.RemoteRepositoryFormat):
1002
 
                result_format.repository_format = repo_format
 
1004
            if isinstance(repo_format, remote.RemoteRepositoryFormat):
 
1005
                source_repository._ensure_real()
 
1006
                repo_format = source_repository._real_repository._format
 
1007
            result_format.repository_format = repo_format
1003
1008
        try:
1004
1009
            # TODO: Couldn't we just probe for the format in these cases,
1005
1010
            # rather than opening the whole tree?  It would be a little
1011
1016
            result_format.workingtree_format = tree._format.__class__()
1012
1017
        return result_format, source_repository
1013
1018
 
1014
 
    def cloning_metadir(self):
 
1019
    def cloning_metadir(self, require_stacking=False):
1015
1020
        """Produce a metadir suitable for cloning or sprouting with.
1016
1021
 
1017
1022
        These operations may produce workingtrees (yes, even though they're
1018
1023
        "cloning" something that doesn't have a tree), so a viable workingtree
1019
1024
        format must be selected.
1020
1025
 
 
1026
        :require_stacking: If True, non-stackable formats will be upgraded
 
1027
            to similar stackable formats.
1021
1028
        :returns: a BzrDirFormat with all component formats either set
1022
 
            appropriately or set to None if that component should not be 
 
1029
            appropriately or set to None if that component should not be
1023
1030
            created.
1024
1031
        """
1025
1032
        format, repository = self._cloning_metadir()
1028
1035
                return format
1029
1036
            tree_format = repository._format._matchingbzrdir.workingtree_format
1030
1037
            format.workingtree_format = tree_format.__class__()
 
1038
        if (require_stacking and not
 
1039
            format.get_branch_format().supports_stacking()):
 
1040
            # We need to make a stacked branch, but the default format for the
 
1041
            # target doesn't support stacking.  So force a branch that *can*
 
1042
            # support stacking.
 
1043
            from bzrlib.branch import BzrBranchFormat7
 
1044
            format._branch_format = BzrBranchFormat7()
 
1045
            mutter("using %r for stacking" % (format._branch_format,))
 
1046
            from bzrlib.repofmt import pack_repo
 
1047
            if format.repository_format.rich_root_data:
 
1048
                bzrdir_format_name = '1.6.1-rich-root'
 
1049
                repo_format = pack_repo.RepositoryFormatKnitPack5RichRoot()
 
1050
            else:
 
1051
                bzrdir_format_name = '1.6'
 
1052
                repo_format = pack_repo.RepositoryFormatKnitPack5()
 
1053
            note('Source format does not support stacking, using format:'
 
1054
                 ' \'%s\'\n  %s\n',
 
1055
                 bzrdir_format_name, repo_format.get_format_description())
 
1056
            format.repository_format = repo_format
1031
1057
        return format
1032
1058
 
1033
1059
    def checkout_metadir(self):
1035
1061
 
1036
1062
    def sprout(self, url, revision_id=None, force_new_repo=False,
1037
1063
               recurse='down', possible_transports=None,
1038
 
               accelerator_tree=None, hardlink=False, stacked=False):
 
1064
               accelerator_tree=None, hardlink=False, stacked=False,
 
1065
               source_branch=None):
1039
1066
        """Create a copy of this bzrdir prepared for use as a new line of
1040
1067
        development.
1041
1068
 
1059
1086
        """
1060
1087
        target_transport = get_transport(url, possible_transports)
1061
1088
        target_transport.ensure_base()
1062
 
        cloning_format = self.cloning_metadir()
 
1089
        cloning_format = self.cloning_metadir(stacked)
 
1090
        # Create/update the result branch
1063
1091
        result = cloning_format.initialize_on_transport(target_transport)
1064
 
        try:
1065
 
            source_branch = self.open_branch()
1066
 
            source_repository = source_branch.repository
 
1092
        # if a stacked branch wasn't requested, we don't create one
 
1093
        # even if the origin was stacked
 
1094
        stacked_branch_url = None
 
1095
        if source_branch is not None:
1067
1096
            if stacked:
1068
1097
                stacked_branch_url = self.root_transport.base
1069
 
            else:
1070
 
                # if a stacked branch wasn't requested, we don't create one
1071
 
                # even if the origin was stacked
1072
 
                stacked_branch_url = None
1073
 
        except errors.NotBranchError:
1074
 
            source_branch = None
 
1098
            source_repository = source_branch.repository
 
1099
        else:
1075
1100
            try:
1076
 
                source_repository = self.open_repository()
1077
 
            except errors.NoRepositoryPresent:
1078
 
                source_repository = None
1079
 
            stacked_branch_url = None
 
1101
                source_branch = self.open_branch()
 
1102
                source_repository = source_branch.repository
 
1103
                if stacked:
 
1104
                    stacked_branch_url = self.root_transport.base
 
1105
            except errors.NotBranchError:
 
1106
                source_branch = None
 
1107
                try:
 
1108
                    source_repository = self.open_repository()
 
1109
                except errors.NoRepositoryPresent:
 
1110
                    source_repository = None
1080
1111
        repository_policy = result.determine_repository_policy(
1081
1112
            force_new_repo, stacked_branch_url, require_stacking=stacked)
1082
1113
        result_repo = repository_policy.acquire_repository()
1083
1114
        if source_repository is not None:
1084
 
            # XXX: Isn't this redundant with the copy_content_into used below
1085
 
            # after creating the branch? -- mbp 20080724
 
1115
            # Fetch while stacked to prevent unstacked fetch from
 
1116
            # Branch.sprout.
1086
1117
            result_repo.fetch(source_repository, revision_id=revision_id)
1087
1118
 
1088
 
        # Create/update the result branch
1089
 
        format_forced = False
1090
 
        if ((stacked 
1091
 
             or repository_policy._require_stacking 
1092
 
             or repository_policy._stack_on)
1093
 
            and not result._format.get_branch_format().supports_stacking()):
1094
 
            # We need to make a stacked branch, but the default format for the
1095
 
            # target doesn't support stacking.  So force a branch that *can*
1096
 
            # support stacking. 
1097
 
            from bzrlib.branch import BzrBranchFormat7
1098
 
            format = BzrBranchFormat7()
1099
 
            result_branch = format.initialize(result)
1100
 
            mutter("using %r for stacking" % (format,))
1101
 
            format_forced = True
1102
 
        elif source_branch is None:
 
1119
        if source_branch is None:
1103
1120
            # this is for sprouting a bzrdir without a branch; is that
1104
1121
            # actually useful?
 
1122
            # Not especially, but it's part of the contract.
1105
1123
            result_branch = result.create_branch()
1106
1124
        else:
 
1125
            # Force NULL revision to avoid using repository before stacking
 
1126
            # is configured.
1107
1127
            result_branch = source_branch.sprout(
1108
 
                result, revision_id=revision_id)
 
1128
                result, revision_id=_mod_revision.NULL_REVISION)
 
1129
            parent_location = result_branch.get_parent()
1109
1130
        mutter("created new branch %r" % (result_branch,))
1110
1131
        repository_policy.configure_branch(result_branch)
1111
 
        if source_branch is not None and format_forced:
1112
 
            # XXX: this duplicates Branch.sprout(); it probably belongs on an
1113
 
            # InterBranch method? -- mbp 20080724
1114
 
            source_branch.copy_content_into(result_branch,
1115
 
                 revision_id=revision_id)
1116
 
            result_branch.set_parent(self.root_transport.base)
 
1132
        if source_branch is not None:
 
1133
            source_branch.copy_content_into(result_branch, revision_id)
 
1134
            # Override copy_content_into
 
1135
            result_branch.set_parent(parent_location)
1117
1136
 
1118
1137
        # Create/update the result working tree
1119
 
        if isinstance(target_transport, LocalTransport) and (
 
1138
        if isinstance(target_transport, local.LocalTransport) and (
1120
1139
            result_repo is None or result_repo.make_working_trees()):
1121
1140
            wt = result.create_workingtree(accelerator_tree=accelerator_tree,
1122
1141
                hardlink=hardlink)
1136
1155
                basis = wt.basis_tree()
1137
1156
                basis.lock_read()
1138
1157
                subtrees = basis.iter_references()
 
1158
            elif result_branch is not None:
 
1159
                basis = result_branch.basis_tree()
 
1160
                basis.lock_read()
 
1161
                subtrees = basis.iter_references()
1139
1162
            elif source_branch is not None:
1140
1163
                basis = source_branch.basis_tree()
1141
1164
                basis.lock_read()
1172
1195
        """Pre-splitout bzrdirs do not suffer from stale locks."""
1173
1196
        raise NotImplementedError(self.break_lock)
1174
1197
 
1175
 
    def cloning_metadir(self):
 
1198
    def cloning_metadir(self, require_stacking=False):
1176
1199
        """Produce a metadir suitable for cloning with."""
 
1200
        if require_stacking:
 
1201
            return format_registry.make_bzrdir('1.6')
1177
1202
        return self._format.__class__()
1178
1203
 
1179
1204
    def clone(self, url, revision_id=None, force_new_repo=False,
1185
1210
        preserve_stacking has no effect, since no source branch using this
1186
1211
        family of formats can be stacked, so there is no stacking to preserve.
1187
1212
        """
1188
 
        from bzrlib.workingtree import WorkingTreeFormat2
1189
1213
        self._make_tail(url)
1190
1214
        result = self._format._initialize_for_clone(url)
1191
1215
        self.open_repository().clone(result, revision_id=revision_id)
1192
1216
        from_branch = self.open_branch()
1193
1217
        from_branch.clone(result, revision_id=revision_id)
1194
1218
        try:
1195
 
            self.open_workingtree().clone(result)
 
1219
            tree = self.open_workingtree()
1196
1220
        except errors.NotLocalUrl:
1197
1221
            # make a new one, this format always has to have one.
1198
 
            try:
1199
 
                WorkingTreeFormat2().initialize(result)
1200
 
            except errors.NotLocalUrl:
1201
 
                # but we cannot do it for remote trees.
1202
 
                to_branch = result.open_branch()
1203
 
                WorkingTreeFormat2()._stub_initialize_remote(to_branch)
 
1222
            result._init_workingtree()
 
1223
        else:
 
1224
            tree.clone(result)
1204
1225
        return result
1205
1226
 
1206
1227
    def create_branch(self):
1207
1228
        """See BzrDir.create_branch."""
1208
 
        return self.open_branch()
 
1229
        return self._format.get_branch_format().initialize(self)
1209
1230
 
1210
1231
    def destroy_branch(self):
1211
1232
        """See BzrDir.destroy_branch."""
1224
1245
    def create_workingtree(self, revision_id=None, from_branch=None,
1225
1246
                           accelerator_tree=None, hardlink=False):
1226
1247
        """See BzrDir.create_workingtree."""
 
1248
        # The workingtree is sometimes created when the bzrdir is created,
 
1249
        # but not when cloning.
 
1250
 
1227
1251
        # this looks buggy but is not -really-
1228
1252
        # because this format creates the workingtree when the bzrdir is
1229
1253
        # created
1233
1257
        # that can do wonky stuff here, and that only
1234
1258
        # happens for creating checkouts, which cannot be 
1235
1259
        # done on this format anyway. So - acceptable wart.
1236
 
        result = self.open_workingtree(recommend_upgrade=False)
 
1260
        try:
 
1261
            result = self.open_workingtree(recommend_upgrade=False)
 
1262
        except errors.NoSuchFile:
 
1263
            result = self._init_workingtree()
1237
1264
        if revision_id is not None:
1238
1265
            if revision_id == _mod_revision.NULL_REVISION:
1239
1266
                result.set_parent_ids([])
1241
1268
                result.set_parent_ids([revision_id])
1242
1269
        return result
1243
1270
 
 
1271
    def _init_workingtree(self):
 
1272
        from bzrlib.workingtree import WorkingTreeFormat2
 
1273
        try:
 
1274
            return WorkingTreeFormat2().initialize(self)
 
1275
        except errors.NotLocalUrl:
 
1276
            # Even though we can't access the working tree, we need to
 
1277
            # create its control files.
 
1278
            return WorkingTreeFormat2()._stub_initialize_on_transport(
 
1279
                self.transport, self._control_files._file_mode)
 
1280
 
1244
1281
    def destroy_workingtree(self):
1245
1282
        """See BzrDir.destroy_workingtree."""
1246
1283
        raise errors.UnsupportedOperation(self.destroy_workingtree, self)
1663
1700
                                      # FIXME: RBC 20060121 don't peek under
1664
1701
                                      # the covers
1665
1702
                                      mode=temp_control._dir_mode)
1666
 
        if sys.platform == 'win32' and isinstance(transport, LocalTransport):
 
1703
        if sys.platform == 'win32' and isinstance(transport, local.LocalTransport):
1667
1704
            win32utils.set_file_attr_hidden(transport._abspath('.bzr'))
1668
1705
        file_mode = temp_control._file_mode
1669
1706
        del temp_control
1853
1890
        """See BzrDirFormat.get_format_string()."""
1854
1891
        return "Bazaar-NG branch, format 5\n"
1855
1892
 
 
1893
    def get_branch_format(self):
 
1894
        from bzrlib import branch
 
1895
        return branch.BzrBranchFormat4()
 
1896
 
1856
1897
    def get_format_description(self):
1857
1898
        """See BzrDirFormat.get_format_description()."""
1858
1899
        return "All-in-one format 5"
1872
1913
        """
1873
1914
        from bzrlib.branch import BzrBranchFormat4
1874
1915
        from bzrlib.repofmt.weaverepo import RepositoryFormat5
1875
 
        from bzrlib.workingtree import WorkingTreeFormat2
1876
1916
        result = (super(BzrDirFormat5, self).initialize_on_transport(transport))
1877
1917
        RepositoryFormat5().initialize(result, _internal=True)
1878
1918
        if not _cloning:
1879
1919
            branch = BzrBranchFormat4().initialize(result)
1880
 
            try:
1881
 
                WorkingTreeFormat2().initialize(result)
1882
 
            except errors.NotLocalUrl:
1883
 
                # Even though we can't access the working tree, we need to
1884
 
                # create its control files.
1885
 
                WorkingTreeFormat2()._stub_initialize_remote(branch)
 
1920
            result._init_workingtree()
1886
1921
        return result
1887
1922
 
1888
1923
    def _open(self, transport):
1916
1951
        """See BzrDirFormat.get_format_description()."""
1917
1952
        return "All-in-one format 6"
1918
1953
 
 
1954
    def get_branch_format(self):
 
1955
        from bzrlib import branch
 
1956
        return branch.BzrBranchFormat4()
 
1957
 
1919
1958
    def get_converter(self, format=None):
1920
1959
        """See BzrDirFormat.get_converter()."""
1921
1960
        # there is one and only one upgrade path here.
1931
1970
        """
1932
1971
        from bzrlib.branch import BzrBranchFormat4
1933
1972
        from bzrlib.repofmt.weaverepo import RepositoryFormat6
1934
 
        from bzrlib.workingtree import WorkingTreeFormat2
1935
1973
        result = super(BzrDirFormat6, self).initialize_on_transport(transport)
1936
1974
        RepositoryFormat6().initialize(result, _internal=True)
1937
1975
        if not _cloning:
1938
1976
            branch = BzrBranchFormat4().initialize(result)
1939
 
            try:
1940
 
                WorkingTreeFormat2().initialize(result)
1941
 
            except errors.NotLocalUrl:
1942
 
                # Even though we can't access the working tree, we need to
1943
 
                # create its control files.
1944
 
                WorkingTreeFormat2()._stub_initialize_remote(branch)
 
1977
            result._init_workingtree()
1945
1978
        return result
1946
1979
 
1947
1980
    def _open(self, transport):
2083
2116
        self.bzrdir = to_convert
2084
2117
        self.pb = pb
2085
2118
        self.pb.note('starting upgrade from format 4 to 5')
2086
 
        if isinstance(self.bzrdir.transport, LocalTransport):
 
2119
        if isinstance(self.bzrdir.transport, local.LocalTransport):
2087
2120
            self.bzrdir.get_workingtree_transport(None).delete('stat-cache')
2088
2121
        self._convert_to_weaves()
2089
2122
        return BzrDir.open(self.bzrdir.root_transport.base)
2617
2650
            return False
2618
2651
        return self.get_format_description() == other.get_format_description()
2619
2652
 
 
2653
    @property
 
2654
    def repository_format(self):
 
2655
        # Using a property to avoid early loading of remote
 
2656
        return remote.RemoteRepositoryFormat()
 
2657
 
2620
2658
 
2621
2659
BzrDirFormat.register_control_server_format(RemoteBzrDirFormat)
2622
2660
 
2640
2678
    def __init__(self):
2641
2679
        """Create a BzrDirFormatRegistry."""
2642
2680
        self._aliases = set()
 
2681
        self._registration_order = list()
2643
2682
        super(BzrDirFormatRegistry, self).__init__()
2644
2683
 
2645
2684
    def aliases(self):
2707
2746
            BzrDirFormatInfo(native, deprecated, hidden, experimental))
2708
2747
        if alias:
2709
2748
            self._aliases.add(key)
 
2749
        self._registration_order.append(key)
2710
2750
 
2711
2751
    def register_lazy(self, key, module_name, member_name, help, native=True,
2712
2752
        deprecated=False, hidden=False, experimental=False, alias=False):
2714
2754
            help, BzrDirFormatInfo(native, deprecated, hidden, experimental))
2715
2755
        if alias:
2716
2756
            self._aliases.add(key)
 
2757
        self._registration_order.append(key)
2717
2758
 
2718
2759
    def set_default(self, key):
2719
2760
        """Set the 'default' key to be a clone of the supplied key.
2739
2780
        return self.get(key)()
2740
2781
 
2741
2782
    def help_topic(self, topic):
2742
 
        output = textwrap.dedent("""\
2743
 
            These formats can be used for creating branches, working trees, and
2744
 
            repositories.
2745
 
 
2746
 
            """)
 
2783
        output = ""
2747
2784
        default_realkey = None
2748
2785
        default_help = self.get_help('default')
2749
2786
        help_pairs = []
2750
 
        for key in self.keys():
 
2787
        for key in self._registration_order:
2751
2788
            if key == 'default':
2752
2789
                continue
2753
2790
            help = self.get_help(key)
2777
2814
                experimental_pairs.append((key, help))
2778
2815
            else:
2779
2816
                output += wrapped(key, help, info)
 
2817
        output += "\nSee ``bzr help formats`` for more about storage formats."
 
2818
        other_output = ""
2780
2819
        if len(experimental_pairs) > 0:
2781
 
            output += "Experimental formats are shown below.\n\n"
 
2820
            other_output += "Experimental formats are shown below.\n\n"
2782
2821
            for key, help in experimental_pairs:
2783
2822
                info = self.get_info(key)
2784
 
                output += wrapped(key, help, info)
 
2823
                other_output += wrapped(key, help, info)
 
2824
        else:
 
2825
            other_output += \
 
2826
                "No experimental formats are available.\n\n"
2785
2827
        if len(deprecated_pairs) > 0:
2786
 
            output += "Deprecated formats are shown below.\n\n"
 
2828
            other_output += "\nDeprecated formats are shown below.\n\n"
2787
2829
            for key, help in deprecated_pairs:
2788
2830
                info = self.get_info(key)
2789
 
                output += wrapped(key, help, info)
 
2831
                other_output += wrapped(key, help, info)
 
2832
        else:
 
2833
            other_output += \
 
2834
                "\nNo deprecated formats are available.\n\n"
 
2835
        other_output += \
 
2836
            "\nSee ``bzr help formats`` for more about storage formats."
2790
2837
 
2791
 
        return output
 
2838
        if topic == 'other-formats':
 
2839
            return other_output
 
2840
        else:
 
2841
            return output
2792
2842
 
2793
2843
 
2794
2844
class RepositoryAcquisitionPolicy(object):
2891
2941
 
2892
2942
        Creates the desired repository in the bzrdir we already have.
2893
2943
        """
2894
 
        if self._stack_on or self._require_stacking:
2895
 
            # we may be coming from a format that doesn't support stacking,
2896
 
            # but we require it in the destination, so force creation of a new
2897
 
            # one here.
2898
 
            #
2899
 
            # TODO: perhaps this should be treated as a distinct repository
2900
 
            # acquisition policy?
2901
 
            repository_format = self._bzrdir._format.repository_format
2902
 
            if not repository_format.supports_external_lookups:
2903
 
                # should possibly be controlled by the registry rather than
2904
 
                # hardcoded here.
2905
 
                from bzrlib.repofmt import pack_repo
2906
 
                if repository_format.rich_root_data:
2907
 
                    repository_format = \
2908
 
                        pack_repo.RepositoryFormatKnitPack5RichRoot()
2909
 
                else:
2910
 
                    repository_format = pack_repo.RepositoryFormatKnitPack5()
2911
 
                note("using %r for stacking" % (repository_format,))
2912
 
            repository = repository_format.initialize(self._bzrdir,
2913
 
                shared=shared)
2914
 
        else:
2915
 
            # let bzrdir choose
2916
 
            repository = self._bzrdir.create_repository(shared=shared)
 
2944
        repository = self._bzrdir.create_repository(shared=shared)
2917
2945
        self._add_fallback(repository)
2918
2946
        if make_working_trees is not None:
2919
2947
            repository.set_make_working_trees(make_working_trees)
2945
2973
        return self._repository
2946
2974
 
2947
2975
 
 
2976
# Please register new formats after old formats so that formats
 
2977
# appear in chronological order and format descriptions can build
 
2978
# on previous ones.
2948
2979
format_registry = BzrDirFormatRegistry()
2949
2980
format_registry.register('weave', BzrDirFormat6,
2950
2981
    'Pre-0.8 format.  Slower than knit and does not'
2951
2982
    ' support checkouts or shared repositories.',
2952
2983
    deprecated=True)
2953
 
format_registry.register_metadir('knit',
2954
 
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2955
 
    'Format using knits.  Recommended for interoperation with bzr <= 0.14.',
2956
 
    branch_format='bzrlib.branch.BzrBranchFormat5',
2957
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat3')
2958
2984
format_registry.register_metadir('metaweave',
2959
2985
    'bzrlib.repofmt.weaverepo.RepositoryFormat7',
2960
2986
    'Transitional format in 0.8.  Slower than knit.',
2961
2987
    branch_format='bzrlib.branch.BzrBranchFormat5',
2962
2988
    tree_format='bzrlib.workingtree.WorkingTreeFormat3',
2963
2989
    deprecated=True)
 
2990
format_registry.register_metadir('knit',
 
2991
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
 
2992
    'Format using knits.  Recommended for interoperation with bzr <= 0.14.',
 
2993
    branch_format='bzrlib.branch.BzrBranchFormat5',
 
2994
    tree_format='bzrlib.workingtree.WorkingTreeFormat3',
 
2995
    deprecated=True)
2964
2996
format_registry.register_metadir('dirstate',
2965
2997
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2966
2998
    help='New in 0.15: Fast local operations. Compatible with bzr 0.8 and '
2969
3001
    # this uses bzrlib.workingtree.WorkingTreeFormat4 because importing
2970
3002
    # directly from workingtree_4 triggers a circular import.
2971
3003
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2972
 
    )
 
3004
    deprecated=True)
2973
3005
format_registry.register_metadir('dirstate-tags',
2974
3006
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
2975
3007
    help='New in 0.15: Fast local operations and improved scaling for '
2977
3009
        ' Incompatible with bzr < 0.15.',
2978
3010
    branch_format='bzrlib.branch.BzrBranchFormat6',
2979
3011
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2980
 
    )
 
3012
    deprecated=True)
2981
3013
format_registry.register_metadir('rich-root',
2982
3014
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit4',
2983
3015
    help='New in 1.0.  Better handling of tree roots.  Incompatible with'
2984
 
        ' bzr < 1.0',
 
3016
        ' bzr < 1.0.',
2985
3017
    branch_format='bzrlib.branch.BzrBranchFormat6',
2986
3018
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
2987
 
    )
 
3019
    deprecated=True)
2988
3020
format_registry.register_metadir('dirstate-with-subtree',
2989
3021
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
2990
3022
    help='New in 0.15: Fast local operations and improved scaling for '
3021
3053
    )
3022
3054
format_registry.register_metadir('rich-root-pack',
3023
3055
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
3024
 
    help='New in 1.0: Pack-based format with data compatible with '
3025
 
        'rich-root format repositories. Incompatible with'
3026
 
        ' bzr < 1.0',
 
3056
    help='New in 1.0: A variant of pack-0.92 that supports rich-root data '
 
3057
         '(needed for bzr-svn).',
3027
3058
    branch_format='bzrlib.branch.BzrBranchFormat6',
3028
3059
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3029
3060
    )
3030
3061
format_registry.register_metadir('1.6',
3031
3062
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5',
3032
 
    help='A branch and pack based repository that supports stacking. ',
 
3063
    help='A format that allows a branch to indicate that there is another '
 
3064
         '(stacked) repository that should be used to access data that is '
 
3065
         'not present locally.',
3033
3066
    branch_format='bzrlib.branch.BzrBranchFormat7',
3034
3067
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3035
3068
    )
3036
 
format_registry.register_metadir('1.6-rich-root',
 
3069
format_registry.register_metadir('1.6.1-rich-root',
3037
3070
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5RichRoot',
3038
 
    help='A branch and pack based repository that supports stacking '
3039
 
         'and rich root data (needed for bzr-svn). ',
 
3071
    help='A variant of 1.6 that supports rich-root data '
 
3072
         '(needed for bzr-svn).',
 
3073
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
3074
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
3075
    )
 
3076
format_registry.register_metadir('1.9',
 
3077
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
 
3078
    help='A repository format using B+tree indexes. These indexes '
 
3079
         'are smaller in size, have smarter caching and provide faster '
 
3080
         'performance for most operations.',
 
3081
    branch_format='bzrlib.branch.BzrBranchFormat7',
 
3082
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
 
3083
    )
 
3084
format_registry.register_metadir('1.9-rich-root',
 
3085
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
 
3086
    help='A variant of 1.9 that supports rich-root data '
 
3087
         '(needed for bzr-svn).',
3040
3088
    branch_format='bzrlib.branch.BzrBranchFormat7',
3041
3089
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3042
3090
    )
3043
3091
# The following two formats should always just be aliases.
3044
3092
format_registry.register_metadir('development',
3045
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment1',
 
3093
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2',
3046
3094
    help='Current development format. Can convert data to and from pack-0.92 '
3047
3095
        '(and anything compatible with pack-0.92) format repositories. '
3048
3096
        'Repositories and branches in this format can only be read by bzr.dev. '
3055
3103
    alias=True,
3056
3104
    )
3057
3105
format_registry.register_metadir('development-subtree',
3058
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment1Subtree',
 
3106
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2Subtree',
3059
3107
    help='Current development format, subtree variant. Can convert data to and '
3060
3108
        'from pack-0.92-subtree (and anything compatible with '
3061
3109
        'pack-0.92-subtree) format repositories. Repositories and branches in '
3067
3115
    experimental=True,
3068
3116
    alias=True,
3069
3117
    )
3070
 
# And the development formats which the will have aliased one of follow:
3071
 
format_registry.register_metadir('development0',
3072
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment0',
3073
 
    help='Trivial rename of pack-0.92 to provide a development format. '
3074
 
        'Please read '
3075
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3076
 
        'before use.',
3077
 
    branch_format='bzrlib.branch.BzrBranchFormat6',
3078
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3079
 
    hidden=True,
3080
 
    experimental=True,
3081
 
    )
3082
 
format_registry.register_metadir('development0-subtree',
3083
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment0Subtree',
3084
 
    help='Trivial rename of pack-0.92-subtree to provide a development format. '
3085
 
        'Please read '
3086
 
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3087
 
        'before use.',
3088
 
    branch_format='bzrlib.branch.BzrBranchFormat6',
3089
 
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3090
 
    hidden=True,
3091
 
    experimental=True,
3092
 
    )
3093
 
format_registry.register_metadir('development1',
3094
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment1',
3095
 
    help='A branch and pack based repository that supports stacking. '
 
3118
# And the development formats above will have aliased one of the following:
 
3119
format_registry.register_metadir('development2',
 
3120
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2',
 
3121
    help='1.6.1 with B+Tree based index. '
3096
3122
        'Please read '
3097
3123
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3098
3124
        'before use.',
3101
3127
    hidden=True,
3102
3128
    experimental=True,
3103
3129
    )
3104
 
format_registry.register_metadir('development1-subtree',
3105
 
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment1Subtree',
3106
 
    help='A branch and pack based repository that supports stacking. '
 
3130
format_registry.register_metadir('development2-subtree',
 
3131
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2Subtree',
 
3132
    help='1.6.1-subtree with B+Tree based index. '
3107
3133
        'Please read '
3108
3134
        'http://doc.bazaar-vcs.org/latest/developers/development-repo.html '
3109
3135
        'before use.',