~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/bzrdir.py

Merge from bzr.dev

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
 
31
31
from cStringIO import StringIO
32
32
import os
 
33
import textwrap
33
34
 
34
35
from bzrlib.lazy_import import lazy_import
35
36
lazy_import(globals(), """
42
43
    errors,
43
44
    lockable_files,
44
45
    lockdir,
 
46
    registry,
45
47
    revision as _mod_revision,
46
48
    repository as _mod_repository,
 
49
    symbol_versioning,
47
50
    urlutils,
48
51
    xml4,
49
52
    xml5,
202
205
 
203
206
    # TODO: Should take a Transport
204
207
    @classmethod
205
 
    def create(cls, base):
 
208
    def create(cls, base, format=None):
206
209
        """Create a new BzrDir at the url 'base'.
207
210
        
208
211
        This will call the current default formats initialize with base
209
212
        as the only parameter.
210
213
 
211
 
        If you need a specific format, consider creating an instance
212
 
        of that and calling initialize().
 
214
        :param format: If supplied, the format of branch to create.  If not
 
215
            supplied, the default is used.
213
216
        """
214
217
        if cls is not BzrDir:
215
 
            raise AssertionError("BzrDir.create always creates the default format, "
216
 
                    "not one of %r" % cls)
 
218
            raise AssertionError("BzrDir.create always creates the default"
 
219
                " format, not one of %r" % cls)
217
220
        head, tail = urlutils.split(base)
218
221
        if tail and tail != '.':
219
222
            t = get_transport(head)
221
224
                t.mkdir(tail)
222
225
            except errors.FileExists:
223
226
                pass
224
 
        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))
225
230
 
226
231
    def create_branch(self):
227
232
        """Create a branch in this BzrDir.
232
237
        raise NotImplementedError(self.create_branch)
233
238
 
234
239
    @staticmethod
235
 
    def create_branch_and_repo(base, force_new_repo=False):
 
240
    def create_branch_and_repo(base, force_new_repo=False, format=None):
236
241
        """Create a new BzrDir, Branch and Repository at the url 'base'.
237
242
 
238
243
        This will use the current default BzrDirFormat, and use whatever 
245
250
        :param base: The URL to create the branch at.
246
251
        :param force_new_repo: If True a new repository is always created.
247
252
        """
248
 
        bzrdir = BzrDir.create(base)
 
253
        bzrdir = BzrDir.create(base, format)
249
254
        bzrdir._find_or_create_repository(force_new_repo)
250
255
        return bzrdir.create_branch()
251
256
 
289
294
            t = get_transport(safe_unicode(base))
290
295
            if not isinstance(t, LocalTransport):
291
296
                raise errors.NotLocalUrl(base)
292
 
        if format is None:
293
 
            bzrdir = BzrDir.create(base)
294
 
        else:
295
 
            bzrdir = format.initialize(base)
 
297
        bzrdir = BzrDir.create(base, format)
296
298
        repo = bzrdir._find_or_create_repository(force_new_repo)
297
299
        result = bzrdir.create_branch()
298
300
        if force_new_tree or (repo.make_working_trees() and 
304
306
        return result
305
307
        
306
308
    @staticmethod
307
 
    def create_repository(base, shared=False):
 
309
    def create_repository(base, shared=False, format=None):
308
310
        """Create a new BzrDir and Repository at the url 'base'.
309
311
 
310
 
        This will use the current default BzrDirFormat, and use whatever 
311
 
        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.
312
315
 
313
316
        :param shared: Create a shared repository rather than a standalone
314
317
                       repository.
318
321
        it should take no parameters and construct whatever repository format
319
322
        that child class desires.
320
323
        """
321
 
        bzrdir = BzrDir.create(base)
 
324
        bzrdir = BzrDir.create(base, format)
322
325
        return bzrdir.create_repository(shared)
323
326
 
324
327
    @staticmethod
325
 
    def create_standalone_workingtree(base):
 
328
    def create_standalone_workingtree(base, format=None):
326
329
        """Create a new BzrDir, WorkingTree, Branch and Repository at 'base'.
327
330
 
328
331
        'base' must be a local path or a file:// url.
337
340
        if not isinstance(t, LocalTransport):
338
341
            raise errors.NotLocalUrl(base)
339
342
        bzrdir = BzrDir.create_branch_and_repo(safe_unicode(base),
340
 
                                               force_new_repo=True).bzrdir
 
343
                                               force_new_repo=True,
 
344
                                               format=format).bzrdir
341
345
        return bzrdir.create_workingtree()
342
346
 
343
347
    def create_workingtree(self, revision_id=None):
1226
1230
        klass._control_formats.append(format)
1227
1231
 
1228
1232
    @classmethod
 
1233
    @symbol_versioning.deprecated_method(symbol_versioning.zero_fourteen)
1229
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)"""
1230
1240
        klass._default_format = format
1231
1241
 
1232
1242
    def __str__(self):
1470
1480
BzrDirFormat.register_format(BzrDirFormat6())
1471
1481
__default_format = BzrDirMetaFormat1()
1472
1482
BzrDirFormat.register_format(__default_format)
1473
 
BzrDirFormat.set_default_format(__default_format)
 
1483
BzrDirFormat._default_format = __default_format
1474
1484
 
1475
1485
 
1476
1486
class BzrDirTestProviderAdapter(object):
1961
1971
                converter = CopyConverter(self.target_format.repository_format)
1962
1972
                converter.convert(repo, pb)
1963
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.')