~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/bzrdir.py

[merge] bzr.dev 2255, resolve conflicts, update copyrights

Show diffs side-by-side

added added

removed removed

Lines of Context:
28
28
# TODO: Can we move specific formats into separate modules to make this file
29
29
# smaller?
30
30
 
31
 
from copy import deepcopy
32
31
from cStringIO import StringIO
33
32
import os
 
33
import textwrap
 
34
 
 
35
from bzrlib.lazy_import import lazy_import
 
36
lazy_import(globals(), """
 
37
from copy import deepcopy
34
38
from stat import S_ISDIR
35
 
from unittest import TestSuite
 
39
import unittest
36
40
 
37
41
import bzrlib
38
 
import bzrlib.errors as errors
39
 
from bzrlib.lockable_files import LockableFiles, TransportLock
40
 
from bzrlib.lockdir import LockDir
 
42
from bzrlib import (
 
43
    errors,
 
44
    lockable_files,
 
45
    lockdir,
 
46
    registry,
 
47
    revision as _mod_revision,
 
48
    repository as _mod_repository,
 
49
    symbol_versioning,
 
50
    urlutils,
 
51
    xml4,
 
52
    xml5,
 
53
    )
41
54
from bzrlib.osutils import (
42
 
                            abspath,
43
 
                            pathjoin,
44
 
                            safe_unicode,
45
 
                            sha_strings,
46
 
                            sha_string,
47
 
                            )
48
 
import bzrlib.revision
 
55
    safe_unicode,
 
56
    sha_strings,
 
57
    sha_string,
 
58
    )
49
59
from bzrlib.store.revision.text import TextRevisionStore
50
60
from bzrlib.store.text import TextStore
51
61
from bzrlib.store.versioned import WeaveStore
52
 
from bzrlib.trace import mutter
53
62
from bzrlib.transactions import WriteTransaction
54
63
from bzrlib.transport import get_transport
 
64
from bzrlib.weave import Weave
 
65
""")
 
66
 
 
67
from bzrlib.trace import mutter
55
68
from bzrlib.transport.local import LocalTransport
56
 
import bzrlib.urlutils as urlutils
57
 
from bzrlib.weave import Weave
58
 
from bzrlib.xml4 import serializer_v4
59
 
import bzrlib.xml5
60
69
 
61
70
 
62
71
class BzrDir(object):
188
197
    def _make_tail(self, url):
189
198
        head, tail = urlutils.split(url)
190
199
        if tail and tail != '.':
191
 
            t = bzrlib.transport.get_transport(head)
 
200
            t = get_transport(head)
192
201
            try:
193
202
                t.mkdir(tail)
194
203
            except errors.FileExists:
196
205
 
197
206
    # TODO: Should take a Transport
198
207
    @classmethod
199
 
    def create(cls, base):
 
208
    def create(cls, base, format=None):
200
209
        """Create a new BzrDir at the url 'base'.
201
210
        
202
211
        This will call the current default formats initialize with base
203
212
        as the only parameter.
204
213
 
205
 
        If you need a specific format, consider creating an instance
206
 
        of that and calling initialize().
 
214
        :param format: If supplied, the format of branch to create.  If not
 
215
            supplied, the default is used.
207
216
        """
208
217
        if cls is not BzrDir:
209
 
            raise AssertionError("BzrDir.create always creates the default format, "
210
 
                    "not one of %r" % cls)
 
218
            raise AssertionError("BzrDir.create always creates the default"
 
219
                " format, not one of %r" % cls)
211
220
        head, tail = urlutils.split(base)
212
221
        if tail and tail != '.':
213
 
            t = bzrlib.transport.get_transport(head)
 
222
            t = get_transport(head)
214
223
            try:
215
224
                t.mkdir(tail)
216
225
            except errors.FileExists:
217
226
                pass
218
 
        return BzrDirFormat.get_default_format().initialize(safe_unicode(base))
 
227
        if format is None:
 
228
            format = BzrDirFormat.get_default_format()
 
229
        return format.initialize(safe_unicode(base))
219
230
 
220
231
    def create_branch(self):
221
232
        """Create a branch in this BzrDir.
226
237
        raise NotImplementedError(self.create_branch)
227
238
 
228
239
    @staticmethod
229
 
    def create_branch_and_repo(base, force_new_repo=False):
 
240
    def create_branch_and_repo(base, force_new_repo=False, format=None):
230
241
        """Create a new BzrDir, Branch and Repository at the url 'base'.
231
242
 
232
243
        This will use the current default BzrDirFormat, and use whatever 
239
250
        :param base: The URL to create the branch at.
240
251
        :param force_new_repo: If True a new repository is always created.
241
252
        """
242
 
        bzrdir = BzrDir.create(base)
 
253
        bzrdir = BzrDir.create(base, format)
243
254
        bzrdir._find_or_create_repository(force_new_repo)
244
255
        return bzrdir.create_branch()
245
256
 
283
294
            t = get_transport(safe_unicode(base))
284
295
            if not isinstance(t, LocalTransport):
285
296
                raise errors.NotLocalUrl(base)
286
 
        if format is None:
287
 
            bzrdir = BzrDir.create(base)
288
 
        else:
289
 
            bzrdir = format.initialize(base)
 
297
        bzrdir = BzrDir.create(base, format)
290
298
        repo = bzrdir._find_or_create_repository(force_new_repo)
291
299
        result = bzrdir.create_branch()
292
300
        if force_new_tree or (repo.make_working_trees() and 
298
306
        return result
299
307
        
300
308
    @staticmethod
301
 
    def create_repository(base, shared=False):
 
309
    def create_repository(base, shared=False, format=None):
302
310
        """Create a new BzrDir and Repository at the url 'base'.
303
311
 
304
 
        This will use the current default BzrDirFormat, and use whatever 
305
 
        repository format that that uses for bzrdirformat.create_repository.
 
312
        If no format is supplied, this will default to the current default
 
313
        BzrDirFormat by default, and use whatever repository format that that
 
314
        uses for bzrdirformat.create_repository.
306
315
 
307
316
        :param shared: Create a shared repository rather than a standalone
308
317
                       repository.
312
321
        it should take no parameters and construct whatever repository format
313
322
        that child class desires.
314
323
        """
315
 
        bzrdir = BzrDir.create(base)
 
324
        bzrdir = BzrDir.create(base, format)
316
325
        return bzrdir.create_repository(shared)
317
326
 
318
327
    @staticmethod
319
 
    def create_standalone_workingtree(base):
 
328
    def create_standalone_workingtree(base, format=None):
320
329
        """Create a new BzrDir, WorkingTree, Branch and Repository at 'base'.
321
330
 
322
331
        'base' must be a local path or a file:// url.
331
340
        if not isinstance(t, LocalTransport):
332
341
            raise errors.NotLocalUrl(base)
333
342
        bzrdir = BzrDir.create_branch_and_repo(safe_unicode(base),
334
 
                                               force_new_repo=True).bzrdir
 
343
                                               force_new_repo=True,
 
344
                                               format=format).bzrdir
335
345
        return bzrdir.create_workingtree()
336
346
 
337
347
    def create_workingtree(self, revision_id=None):
548
558
                raise errors.NotBranchError(path=url)
549
559
            a_transport = new_t
550
560
 
 
561
    @classmethod
 
562
    def open_containing_tree_or_branch(klass, location):
 
563
        """Return the branch and working tree contained by a location.
 
564
 
 
565
        Returns (tree, branch, relpath).
 
566
        If there is no tree at containing the location, tree will be None.
 
567
        If there is no branch containing the location, an exception will be
 
568
        raised
 
569
        relpath is the portion of the path that is contained by the branch.
 
570
        """
 
571
        bzrdir, relpath = klass.open_containing(location)
 
572
        try:
 
573
            tree = bzrdir.open_workingtree()
 
574
        except (errors.NoWorkingTree, errors.NotLocalUrl):
 
575
            tree = None
 
576
            branch = bzrdir.open_branch()
 
577
        else:
 
578
            branch = tree.branch
 
579
        return tree, branch, relpath
 
580
 
551
581
    def open_repository(self, _unsupported=False):
552
582
        """Open the repository object at this BzrDir if one is present.
553
583
 
680
710
        # TODO: jam 20060426 we probably need a test in here in the
681
711
        #       case that the newly sprouted branch is a remote one
682
712
        if result_repo is None or result_repo.make_working_trees():
683
 
            result.create_workingtree()
 
713
            wt = result.create_workingtree()
 
714
            if wt.inventory.root is None:
 
715
                try:
 
716
                    wt.set_root_id(self.open_workingtree.get_root_id())
 
717
                except errors.NoWorkingTree:
 
718
                    pass
684
719
        return result
685
720
 
686
721
 
690
725
    def __init__(self, _transport, _format):
691
726
        """See BzrDir.__init__."""
692
727
        super(BzrDirPreSplitOut, self).__init__(_transport, _format)
693
 
        assert self._format._lock_class == TransportLock
 
728
        assert self._format._lock_class == lockable_files.TransportLock
694
729
        assert self._format._lock_file_name == 'branch-lock'
695
 
        self._control_files = LockableFiles(self.get_branch_transport(None),
 
730
        self._control_files = lockable_files.LockableFiles(
 
731
                                            self.get_branch_transport(None),
696
732
                                            self._format._lock_file_name,
697
733
                                            self._format._lock_class)
698
734
 
742
778
        # done on this format anyway. So - acceptable wart.
743
779
        result = self.open_workingtree()
744
780
        if revision_id is not None:
745
 
            if revision_id == bzrlib.revision.NULL_REVISION:
 
781
            if revision_id == _mod_revision.NULL_REVISION:
746
782
                result.set_parent_ids([])
747
783
            else:
748
784
                result.set_parent_ids([revision_id])
906
942
        """See BzrDir.destroy_workingtree."""
907
943
        wt = self.open_workingtree()
908
944
        repository = wt.branch.repository
909
 
        empty = repository.revision_tree(bzrlib.revision.NULL_REVISION)
 
945
        empty = repository.revision_tree(_mod_revision.NULL_REVISION)
910
946
        wt.revert([], old_tree=empty)
911
947
        self.destroy_workingtree_metadata()
912
948
 
915
951
 
916
952
    def _get_mkdir_mode(self):
917
953
        """Figure out the mode to use when creating a bzrdir subdir."""
918
 
        temp_control = LockableFiles(self.transport, '', TransportLock)
 
954
        temp_control = lockable_files.LockableFiles(self.transport, '',
 
955
                                     lockable_files.TransportLock)
919
956
        return temp_control._dir_mode
920
957
 
921
958
    def get_branch_transport(self, branch_format):
1097
1134
        """Initialize a new bzrdir in the base directory of a Transport."""
1098
1135
        # Since we don't have a .bzr directory, inherit the
1099
1136
        # mode from the root directory
1100
 
        temp_control = LockableFiles(transport, '', TransportLock)
 
1137
        temp_control = lockable_files.LockableFiles(transport,
 
1138
                            '', lockable_files.TransportLock)
1101
1139
        temp_control._transport.mkdir('.bzr',
1102
1140
                                      # FIXME: RBC 20060121 don't peek under
1103
1141
                                      # the covers
1112
1150
                      ('branch-format', self.get_format_string()),
1113
1151
                      ]
1114
1152
        # NB: no need to escape relative paths that are url safe.
1115
 
        control_files = LockableFiles(control, self._lock_file_name, 
1116
 
                                      self._lock_class)
 
1153
        control_files = lockable_files.LockableFiles(control,
 
1154
                            self._lock_file_name, self._lock_class)
1117
1155
        control_files.create_lock()
1118
1156
        control_files.lock_write()
1119
1157
        try:
1161
1199
        _found is a private parameter, do not use it.
1162
1200
        """
1163
1201
        if not _found:
1164
 
            assert isinstance(BzrDirFormat.find_format(transport),
1165
 
                              self.__class__)
 
1202
            found_format = BzrDirFormat.find_format(transport)
 
1203
            if not isinstance(found_format, self.__class__):
 
1204
                raise AssertionError("%s was asked to open %s, but it seems to need "
 
1205
                        "format %s" 
 
1206
                        % (self, transport, found_format))
1166
1207
        return self._open(transport)
1167
1208
 
1168
1209
    def _open(self, transport):
1189
1230
        klass._control_formats.append(format)
1190
1231
 
1191
1232
    @classmethod
 
1233
    @symbol_versioning.deprecated_method(symbol_versioning.zero_fourteen)
1192
1234
    def set_default_format(klass, format):
 
1235
        klass._set_default_format(format)
 
1236
 
 
1237
    @classmethod
 
1238
    def _set_default_format(klass, format):
 
1239
        """Set default format (for testing behavior of defaults only)"""
1193
1240
        klass._default_format = format
1194
1241
 
1195
1242
    def __str__(self):
1222
1269
    removed in format 5; write support for this format has been removed.
1223
1270
    """
1224
1271
 
1225
 
    _lock_class = TransportLock
 
1272
    _lock_class = lockable_files.TransportLock
1226
1273
 
1227
1274
    def get_format_string(self):
1228
1275
        """See BzrDirFormat.get_format_string()."""
1272
1319
       Unhashed stores in the repository.
1273
1320
    """
1274
1321
 
1275
 
    _lock_class = TransportLock
 
1322
    _lock_class = lockable_files.TransportLock
1276
1323
 
1277
1324
    def get_format_string(self):
1278
1325
        """See BzrDirFormat.get_format_string()."""
1331
1378
     - Format 6 repositories [always]
1332
1379
    """
1333
1380
 
1334
 
    _lock_class = TransportLock
 
1381
    _lock_class = lockable_files.TransportLock
1335
1382
 
1336
1383
    def get_format_string(self):
1337
1384
        """See BzrDirFormat.get_format_string()."""
1391
1438
     - Format 7 repositories [optional]
1392
1439
    """
1393
1440
 
1394
 
    _lock_class = LockDir
 
1441
    _lock_class = lockdir.LockDir
1395
1442
 
1396
1443
    def get_converter(self, format=None):
1397
1444
        """See BzrDirFormat.get_converter()."""
1433
1480
BzrDirFormat.register_format(BzrDirFormat6())
1434
1481
__default_format = BzrDirMetaFormat1()
1435
1482
BzrDirFormat.register_format(__default_format)
1436
 
BzrDirFormat.set_default_format(__default_format)
 
1483
BzrDirFormat._default_format = __default_format
1437
1484
 
1438
1485
 
1439
1486
class BzrDirTestProviderAdapter(object):
1451
1498
        self._formats = formats
1452
1499
    
1453
1500
    def adapt(self, test):
1454
 
        result = TestSuite()
 
1501
        result = unittest.TestSuite()
1455
1502
        for format in self._formats:
1456
1503
            new_test = deepcopy(test)
1457
1504
            new_test.transport_server = self._transport_server
1555
1602
        self.bzrdir.transport.delete_tree('text-store')
1556
1603
 
1557
1604
    def _convert_working_inv(self):
1558
 
        inv = serializer_v4.read_inventory(self.branch.control_files.get('inventory'))
1559
 
        new_inv_xml = bzrlib.xml5.serializer_v5.write_inventory_to_string(inv)
 
1605
        inv = xml4.serializer_v4.read_inventory(
 
1606
                    self.branch.control_files.get('inventory'))
 
1607
        new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv)
1560
1608
        # FIXME inventory is a working tree change.
1561
1609
        self.branch.control_files.put('inventory', StringIO(new_inv_xml))
1562
1610
 
1588
1636
                                                      prefixed=False,
1589
1637
                                                      compressed=True))
1590
1638
        try:
1591
 
            transaction = bzrlib.transactions.WriteTransaction()
 
1639
            transaction = WriteTransaction()
1592
1640
            for i, rev_id in enumerate(self.converted_revs):
1593
1641
                self.pb.update('write revision', i, len(self.converted_revs))
1594
1642
                _revision_store.add_revision(self.revisions[rev_id], transaction)
1620
1668
    def _load_old_inventory(self, rev_id):
1621
1669
        assert rev_id not in self.converted_revs
1622
1670
        old_inv_xml = self.branch.repository.inventory_store.get(rev_id).read()
1623
 
        inv = serializer_v4.read_inventory_from_string(old_inv_xml)
 
1671
        inv = xml4.serializer_v4.read_inventory_from_string(old_inv_xml)
1624
1672
        inv.revision_id = rev_id
1625
1673
        rev = self.revisions[rev_id]
1626
1674
        if rev.inventory_sha1:
1631
1679
    def _load_updated_inventory(self, rev_id):
1632
1680
        assert rev_id in self.converted_revs
1633
1681
        inv_xml = self.inv_weave.get_text(rev_id)
1634
 
        inv = bzrlib.xml5.serializer_v5.read_inventory_from_string(inv_xml)
 
1682
        inv = xml5.serializer_v5.read_inventory_from_string(inv_xml)
1635
1683
        return inv
1636
1684
 
1637
1685
    def _convert_one_rev(self, rev_id):
1653
1701
                assert getattr(ie, 'revision', None) is not None, \
1654
1702
                    'no revision on {%s} in {%s}' % \
1655
1703
                    (file_id, rev.revision_id)
1656
 
        new_inv_xml = bzrlib.xml5.serializer_v5.write_inventory_to_string(inv)
 
1704
        new_inv_xml = xml5.serializer_v5.write_inventory_to_string(inv)
1657
1705
        new_inv_sha1 = sha_string(new_inv_xml)
1658
1706
        self.inv_weave.add_lines(rev.revision_id, 
1659
1707
                                 present_parents,
1692
1740
                                                  entry_vf=w)
1693
1741
        for old_revision in previous_entries:
1694
1742
                # if this fails, its a ghost ?
1695
 
                assert old_revision in self.converted_revs 
 
1743
                assert old_revision in self.converted_revs, \
 
1744
                    "Revision {%s} not in converted_revs" % old_revision
1696
1745
        self.snapshot_ie(previous_entries, ie, w, rev_id)
1697
1746
        del ie.text_id
1698
1747
        assert getattr(ie, 'revision', None) is not None
1785
1834
 
1786
1835
    def convert(self, to_convert, pb):
1787
1836
        """See Converter.convert()."""
 
1837
        from bzrlib.branch import BzrBranchFormat5
1788
1838
        self.bzrdir = to_convert
1789
1839
        self.pb = pb
1790
1840
        self.count = 0
1819
1869
        # we hard code the formats here because we are converting into
1820
1870
        # the meta format. The meta format upgrader can take this to a 
1821
1871
        # future format within each component.
1822
 
        self.put_format('repository', bzrlib.repository.RepositoryFormat7())
 
1872
        self.put_format('repository', _mod_repository.RepositoryFormat7())
1823
1873
        for entry in repository_names:
1824
1874
            self.move_entry('repository', entry)
1825
1875
 
1826
1876
        self.step('Upgrading branch      ')
1827
1877
        self.bzrdir.transport.mkdir('branch', mode=self.dir_mode)
1828
1878
        self.make_lock('branch')
1829
 
        self.put_format('branch', bzrlib.branch.BzrBranchFormat5())
 
1879
        self.put_format('branch', BzrBranchFormat5())
1830
1880
        branch_files = [('revision-history', True),
1831
1881
                        ('branch-name', True),
1832
1882
                        ('parent', False)]
1852
1902
                if name in bzrcontents:
1853
1903
                    self.bzrdir.transport.delete(name)
1854
1904
        else:
 
1905
            from bzrlib.workingtree import WorkingTreeFormat3
1855
1906
            self.step('Upgrading working tree')
1856
1907
            self.bzrdir.transport.mkdir('checkout', mode=self.dir_mode)
1857
1908
            self.make_lock('checkout')
1858
1909
            self.put_format(
1859
 
                'checkout', bzrlib.workingtree.WorkingTreeFormat3())
 
1910
                'checkout', WorkingTreeFormat3())
1860
1911
            self.bzrdir.transport.delete_multi(
1861
1912
                self.garbage_inventories, self.pb)
1862
1913
            for entry in checkout_files:
1871
1922
    def make_lock(self, name):
1872
1923
        """Make a lock for the new control dir name."""
1873
1924
        self.step('Make %s lock' % name)
1874
 
        ld = LockDir(self.bzrdir.transport, 
1875
 
                     '%s/lock' % name,
1876
 
                     file_modebits=self.file_mode,
1877
 
                     dir_modebits=self.dir_mode)
 
1925
        ld = lockdir.LockDir(self.bzrdir.transport,
 
1926
                             '%s/lock' % name,
 
1927
                             file_modebits=self.file_mode,
 
1928
                             dir_modebits=self.dir_mode)
1878
1929
        ld.create()
1879
1930
 
1880
1931
    def move_entry(self, new_dir, entry):
1920
1971
                converter = CopyConverter(self.target_format.repository_format)
1921
1972
                converter.convert(repo, pb)
1922
1973
        return to_convert
 
1974
 
 
1975
 
 
1976
class BzrDirFormatInfo(object):
 
1977
 
 
1978
    def __init__(self, native, deprecated):
 
1979
        self.deprecated = deprecated
 
1980
        self.native = native
 
1981
 
 
1982
 
 
1983
class BzrDirFormatRegistry(registry.Registry):
 
1984
    """Registry of user-selectable BzrDir subformats.
 
1985
    
 
1986
    Differs from BzrDirFormat._control_formats in that it provides sub-formats,
 
1987
    e.g. BzrDirMeta1 with weave repository.  Also, it's more user-oriented.
 
1988
    """
 
1989
 
 
1990
    def register_metadir(self, key, repo, help, native=True, deprecated=False):
 
1991
        """Register a metadir subformat.
 
1992
        
 
1993
        repo is the repository format name as a string.
 
1994
        """
 
1995
        # This should be expanded to support setting WorkingTree and Branch
 
1996
        # formats, once BzrDirMetaFormat1 supports that.
 
1997
        def helper():
 
1998
            import bzrlib.repository
 
1999
            repo_format = getattr(bzrlib.repository, repo)
 
2000
            bd = BzrDirMetaFormat1()
 
2001
            bd.repository_format = repo_format()
 
2002
            return bd
 
2003
        self.register(key, helper, help, native, deprecated)
 
2004
 
 
2005
    def register(self, key, factory, help, native=True, deprecated=False):
 
2006
        """Register a BzrDirFormat factory.
 
2007
        
 
2008
        The factory must be a callable that takes one parameter: the key.
 
2009
        It must produce an instance of the BzrDirFormat when called.
 
2010
 
 
2011
        This function mainly exists to prevent the info object from being
 
2012
        supplied directly.
 
2013
        """
 
2014
        registry.Registry.register(self, key, factory, help, 
 
2015
            BzrDirFormatInfo(native, deprecated))
 
2016
 
 
2017
    def register_lazy(self, key, module_name, member_name, help, native=True,
 
2018
                      deprecated=False):
 
2019
        registry.Registry.register_lazy(self, key, module_name, member_name, 
 
2020
            help, BzrDirFormatInfo(native, deprecated))
 
2021
 
 
2022
    def set_default(self, key):
 
2023
        """Set the 'default' key to be a clone of the supplied key.
 
2024
        
 
2025
        This method must be called once and only once.
 
2026
        """
 
2027
        registry.Registry.register(self, 'default', self.get(key), 
 
2028
            self.get_help(key), info=self.get_info(key))
 
2029
 
 
2030
    def set_default_repository(self, key):
 
2031
        """Set the FormatRegistry default and Repository default.
 
2032
        
 
2033
        This is a transitional method while Repository.set_default_format
 
2034
        is deprecated.
 
2035
        """
 
2036
        if 'default' in self:
 
2037
            self.remove('default')
 
2038
        self.set_default(key)
 
2039
        format = self.get('default')()
 
2040
        assert isinstance(format, BzrDirMetaFormat1)
 
2041
        from bzrlib import repository
 
2042
        repository.RepositoryFormat._set_default_format(
 
2043
            format.repository_format)
 
2044
 
 
2045
    def make_bzrdir(self, key):
 
2046
        return self.get(key)()
 
2047
 
 
2048
    def help_topic(self, topic):
 
2049
        output = textwrap.dedent("""\
 
2050
            Bazaar directory formats
 
2051
            ------------------------
 
2052
 
 
2053
            These formats can be used for creating branches, working trees, and
 
2054
            repositories.
 
2055
 
 
2056
            """)
 
2057
        default_help = self.get_help('default')
 
2058
        help_pairs = []
 
2059
        for key in self.keys():
 
2060
            if key == 'default':
 
2061
                continue
 
2062
            help = self.get_help(key)
 
2063
            if help == default_help:
 
2064
                default_realkey = key
 
2065
            else:
 
2066
                help_pairs.append((key, help))
 
2067
 
 
2068
        def wrapped(key, help, info):
 
2069
            if info.native:
 
2070
                help = '(native) ' + help
 
2071
            return '  %s:\n%s\n\n' % (key, 
 
2072
                    textwrap.fill(help, initial_indent='    ', 
 
2073
                    subsequent_indent='    '))
 
2074
        output += wrapped('%s/default' % default_realkey, default_help,
 
2075
                          self.get_info('default'))
 
2076
        deprecated_pairs = []
 
2077
        for key, help in help_pairs:
 
2078
            info = self.get_info(key)
 
2079
            if info.deprecated:
 
2080
                deprecated_pairs.append((key, help))
 
2081
            else:
 
2082
                output += wrapped(key, help, info)
 
2083
        if len(deprecated_pairs) > 0:
 
2084
            output += "Deprecated formats\n------------------\n\n"
 
2085
            for key, help in deprecated_pairs:
 
2086
                info = self.get_info(key)
 
2087
                output += wrapped(key, help, info)
 
2088
 
 
2089
        return output
 
2090
 
 
2091
 
 
2092
format_registry = BzrDirFormatRegistry()
 
2093
format_registry.register('weave', BzrDirFormat6,
 
2094
    'Pre-0.8 format.  Slower than knit and does not'
 
2095
    ' support checkouts or shared repositories.', deprecated=True)
 
2096
format_registry.register_metadir('knit', 'RepositoryFormatKnit1',
 
2097
    'Format using knits.  Recommended.')
 
2098
format_registry.set_default('knit')
 
2099
format_registry.register_metadir('metaweave', 'RepositoryFormat7',
 
2100
    'Transitional format in 0.8.  Slower than knit.',
 
2101
    deprecated=True)
 
2102
format_registry.register_metadir('experimental-knit2', 'RepositoryFormatKnit2',
 
2103
    'Experimental successor to knit.  Use at your own risk.')