~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/bzrdir.py

  • Committer: Jelmer Vernooij
  • Date: 2010-08-02 13:40:08 UTC
  • mto: This revision was merged to the branch mainline in revision 5389.
  • Revision ID: jelmer@samba.org-20100802134008-kbinww4ikgqu8g1f
Add ControlDirFormat.{un,}register_{server_,}prober.

Show diffs side-by-side

added added

removed removed

Lines of Context:
34
34
from bzrlib.lazy_import import lazy_import
35
35
lazy_import(globals(), """
36
36
from stat import S_ISDIR
37
 
import textwrap
38
37
 
39
38
import bzrlib
40
39
from bzrlib import (
79
78
    ControlDir,
80
79
    ControlDirFormat,
81
80
    Prober,
82
 
    probers,
83
 
    server_probers,
 
81
    format_registry,
84
82
    )
85
83
 
86
84
from bzrlib.trace import (
333
331
        t = get_transport(url)
334
332
        t.ensure_base()
335
333
 
336
 
    @classmethod
337
 
    def create(cls, base, format=None, possible_transports=None):
338
 
        """Create a new BzrDir at the url 'base'.
339
 
 
340
 
        :param format: If supplied, the format of branch to create.  If not
341
 
            supplied, the default is used.
342
 
        :param possible_transports: If supplied, a list of transports that
343
 
            can be reused to share a remote connection.
344
 
        """
345
 
        if cls is not BzrDir:
346
 
            raise AssertionError("BzrDir.create always creates the default"
347
 
                " format, not one of %r" % cls)
348
 
        t = get_transport(base, possible_transports)
349
 
        t.ensure_base()
350
 
        if format is None:
351
 
            format = BzrDirFormat.get_default_format()
352
 
        return format.initialize_on_transport(t)
353
 
 
354
334
    @staticmethod
355
335
    def find_bzrdirs(transport, evaluate=None, list_current=None):
356
336
        """Find bzrdirs recursively from current location.
1528
1508
        klass._formats[format.get_format_string()] = format
1529
1509
 
1530
1510
    @classmethod
1531
 
    def unregister_format(klass, format):
 
1511
    def unregister_bzrdir_format(klass, format):
1532
1512
        del klass._formats[format.get_format_string()]
1533
1513
 
1534
 
    @classmethod
1535
 
    def probe_transport(klass, transport):
 
1514
    def probe_transport(self, transport):
1536
1515
        """Return the .bzrdir style format present in a directory."""
1537
1516
        try:
1538
1517
            format_string = transport.get_bytes(".bzr/branch-format")
1539
1518
        except errors.NoSuchFile:
1540
1519
            raise errors.NotBranchError(path=transport.base)
1541
1520
        try:
1542
 
            return klass._formats[format_string]
 
1521
            return self._formats[format_string]
1543
1522
        except KeyError:
1544
1523
            raise errors.UnknownFormatError(format=format_string, kind='bzrdir')
1545
1524
 
1546
1525
 
 
1526
ControlDirFormat.register_prober(BzrProber)
 
1527
 
 
1528
 
1547
1529
class RemoteBzrProber(Prober):
1548
1530
 
1549
1531
    @classmethod
1571
1553
            return klass()
1572
1554
 
1573
1555
 
1574
 
 
1575
 
 
1576
1556
class BzrDirFormat(ControlDirFormat):
1577
1557
    """ControlDirFormat base class for .bzr/ directories.
1578
1558
 
1792
1772
 
1793
1773
    @classmethod
1794
1774
    def unregister_format(klass, format):
1795
 
        BzrProber.unregister_format(format)
 
1775
        BzrProber.unregister_bzrdir_format(format)
1796
1776
        ControlDirFormat.unregister_format(format)
 
1777
        network_format_registry.unregister(format.get_format_string())
1797
1778
 
1798
1779
 
1799
1780
class BzrDirFormat4(BzrDirFormat):
2990
2971
        BzrDirMetaFormat1._set_repository_format) #.im_func)
2991
2972
 
2992
2973
 
2993
 
ControlDirFormat.register_server_format(RemoteBzrDirFormat)
2994
 
 
2995
 
 
2996
 
class BzrDirFormatInfo(object):
2997
 
 
2998
 
    def __init__(self, native, deprecated, hidden, experimental):
2999
 
        self.deprecated = deprecated
3000
 
        self.native = native
3001
 
        self.hidden = hidden
3002
 
        self.experimental = experimental
3003
 
 
3004
 
 
3005
 
class BzrDirFormatRegistry(registry.Registry):
3006
 
    """Registry of user-selectable BzrDir subformats.
3007
 
 
3008
 
    Differs from ControlDirFormat._formats in that it provides sub-formats,
3009
 
    e.g. BzrDirMeta1 with weave repository.  Also, it's more user-oriented.
3010
 
    """
3011
 
 
3012
 
    def __init__(self):
3013
 
        """Create a BzrDirFormatRegistry."""
3014
 
        self._aliases = set()
3015
 
        self._registration_order = list()
3016
 
        super(BzrDirFormatRegistry, self).__init__()
3017
 
 
3018
 
    def aliases(self):
3019
 
        """Return a set of the format names which are aliases."""
3020
 
        return frozenset(self._aliases)
3021
 
 
3022
 
    def register_metadir(self, key,
3023
 
             repository_format, help, native=True, deprecated=False,
3024
 
             branch_format=None,
3025
 
             tree_format=None,
3026
 
             hidden=False,
3027
 
             experimental=False,
3028
 
             alias=False):
3029
 
        """Register a metadir subformat.
3030
 
 
3031
 
        These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
3032
 
        by the Repository/Branch/WorkingTreeformats.
3033
 
 
3034
 
        :param repository_format: The fully-qualified repository format class
3035
 
            name as a string.
3036
 
        :param branch_format: Fully-qualified branch format class name as
3037
 
            a string.
3038
 
        :param tree_format: Fully-qualified tree format class name as
3039
 
            a string.
3040
 
        """
3041
 
        # This should be expanded to support setting WorkingTree and Branch
3042
 
        # formats, once BzrDirMetaFormat1 supports that.
3043
 
        def _load(full_name):
3044
 
            mod_name, factory_name = full_name.rsplit('.', 1)
3045
 
            try:
3046
 
                mod = __import__(mod_name, globals(), locals(),
3047
 
                        [factory_name])
3048
 
            except ImportError, e:
3049
 
                raise ImportError('failed to load %s: %s' % (full_name, e))
3050
 
            try:
3051
 
                factory = getattr(mod, factory_name)
3052
 
            except AttributeError:
3053
 
                raise AttributeError('no factory %s in module %r'
3054
 
                    % (full_name, mod))
3055
 
            return factory()
3056
 
 
3057
 
        def helper():
3058
 
            bd = BzrDirMetaFormat1()
3059
 
            if branch_format is not None:
3060
 
                bd.set_branch_format(_load(branch_format))
3061
 
            if tree_format is not None:
3062
 
                bd.workingtree_format = _load(tree_format)
3063
 
            if repository_format is not None:
3064
 
                bd.repository_format = _load(repository_format)
3065
 
            return bd
3066
 
        self.register(key, helper, help, native, deprecated, hidden,
3067
 
            experimental, alias)
3068
 
 
3069
 
    def register(self, key, factory, help, native=True, deprecated=False,
3070
 
                 hidden=False, experimental=False, alias=False):
3071
 
        """Register a BzrDirFormat factory.
3072
 
 
3073
 
        The factory must be a callable that takes one parameter: the key.
3074
 
        It must produce an instance of the BzrDirFormat when called.
3075
 
 
3076
 
        This function mainly exists to prevent the info object from being
3077
 
        supplied directly.
3078
 
        """
3079
 
        registry.Registry.register(self, key, factory, help,
3080
 
            BzrDirFormatInfo(native, deprecated, hidden, experimental))
3081
 
        if alias:
3082
 
            self._aliases.add(key)
3083
 
        self._registration_order.append(key)
3084
 
 
3085
 
    def register_lazy(self, key, module_name, member_name, help, native=True,
3086
 
        deprecated=False, hidden=False, experimental=False, alias=False):
3087
 
        registry.Registry.register_lazy(self, key, module_name, member_name,
3088
 
            help, BzrDirFormatInfo(native, deprecated, hidden, experimental))
3089
 
        if alias:
3090
 
            self._aliases.add(key)
3091
 
        self._registration_order.append(key)
3092
 
 
3093
 
    def set_default(self, key):
3094
 
        """Set the 'default' key to be a clone of the supplied key.
3095
 
 
3096
 
        This method must be called once and only once.
3097
 
        """
3098
 
        registry.Registry.register(self, 'default', self.get(key),
3099
 
            self.get_help(key), info=self.get_info(key))
3100
 
        self._aliases.add('default')
3101
 
 
3102
 
    def set_default_repository(self, key):
3103
 
        """Set the FormatRegistry default and Repository default.
3104
 
 
3105
 
        This is a transitional method while Repository.set_default_format
3106
 
        is deprecated.
3107
 
        """
3108
 
        if 'default' in self:
3109
 
            self.remove('default')
3110
 
        self.set_default(key)
3111
 
        format = self.get('default')()
3112
 
 
3113
 
    def make_bzrdir(self, key):
3114
 
        return self.get(key)()
3115
 
 
3116
 
    def help_topic(self, topic):
3117
 
        output = ""
3118
 
        default_realkey = None
3119
 
        default_help = self.get_help('default')
3120
 
        help_pairs = []
3121
 
        for key in self._registration_order:
3122
 
            if key == 'default':
3123
 
                continue
3124
 
            help = self.get_help(key)
3125
 
            if help == default_help:
3126
 
                default_realkey = key
3127
 
            else:
3128
 
                help_pairs.append((key, help))
3129
 
 
3130
 
        def wrapped(key, help, info):
3131
 
            if info.native:
3132
 
                help = '(native) ' + help
3133
 
            return ':%s:\n%s\n\n' % (key,
3134
 
                textwrap.fill(help, initial_indent='    ',
3135
 
                    subsequent_indent='    ',
3136
 
                    break_long_words=False))
3137
 
        if default_realkey is not None:
3138
 
            output += wrapped(default_realkey, '(default) %s' % default_help,
3139
 
                              self.get_info('default'))
3140
 
        deprecated_pairs = []
3141
 
        experimental_pairs = []
3142
 
        for key, help in help_pairs:
3143
 
            info = self.get_info(key)
3144
 
            if info.hidden:
3145
 
                continue
3146
 
            elif info.deprecated:
3147
 
                deprecated_pairs.append((key, help))
3148
 
            elif info.experimental:
3149
 
                experimental_pairs.append((key, help))
3150
 
            else:
3151
 
                output += wrapped(key, help, info)
3152
 
        output += "\nSee :doc:`formats-help` for more about storage formats."
3153
 
        other_output = ""
3154
 
        if len(experimental_pairs) > 0:
3155
 
            other_output += "Experimental formats are shown below.\n\n"
3156
 
            for key, help in experimental_pairs:
3157
 
                info = self.get_info(key)
3158
 
                other_output += wrapped(key, help, info)
3159
 
        else:
3160
 
            other_output += \
3161
 
                "No experimental formats are available.\n\n"
3162
 
        if len(deprecated_pairs) > 0:
3163
 
            other_output += "\nDeprecated formats are shown below.\n\n"
3164
 
            for key, help in deprecated_pairs:
3165
 
                info = self.get_info(key)
3166
 
                other_output += wrapped(key, help, info)
3167
 
        else:
3168
 
            other_output += \
3169
 
                "\nNo deprecated formats are available.\n\n"
3170
 
        other_output += \
3171
 
                "\nSee :doc:`formats-help` for more about storage formats."
3172
 
 
3173
 
        if topic == 'other-formats':
3174
 
            return other_output
3175
 
        else:
3176
 
            return output
 
2974
ControlDirFormat.register_server_prober(RemoteBzrProber)
3177
2975
 
3178
2976
 
3179
2977
class RepositoryAcquisitionPolicy(object):
3333
3131
        return self._repository, False
3334
3132
 
3335
3133
 
3336
 
# Please register new formats after old formats so that formats
3337
 
# appear in chronological order and format descriptions can build
3338
 
# on previous ones.
3339
 
format_registry = BzrDirFormatRegistry()
 
3134
def register_metadir(key,
 
3135
         repository_format, help, native=True, deprecated=False,
 
3136
         branch_format=None,
 
3137
         tree_format=None,
 
3138
         hidden=False,
 
3139
         experimental=False,
 
3140
         alias=False):
 
3141
    """Register a metadir subformat.
 
3142
 
 
3143
    These all use a BzrDirMetaFormat1 bzrdir, but can be parameterized
 
3144
    by the Repository/Branch/WorkingTreeformats.
 
3145
 
 
3146
    :param repository_format: The fully-qualified repository format class
 
3147
        name as a string.
 
3148
    :param branch_format: Fully-qualified branch format class name as
 
3149
        a string.
 
3150
    :param tree_format: Fully-qualified tree format class name as
 
3151
        a string.
 
3152
    """
 
3153
    # This should be expanded to support setting WorkingTree and Branch
 
3154
    # formats, once BzrDirMetaFormat1 supports that.
 
3155
    def _load(full_name):
 
3156
        mod_name, factory_name = full_name.rsplit('.', 1)
 
3157
        try:
 
3158
            mod = __import__(mod_name, globals(), locals(),
 
3159
                    [factory_name])
 
3160
        except ImportError, e:
 
3161
            raise ImportError('failed to load %s: %s' % (full_name, e))
 
3162
        try:
 
3163
            factory = getattr(mod, factory_name)
 
3164
        except AttributeError:
 
3165
            raise AttributeError('no factory %s in module %r'
 
3166
                % (full_name, mod))
 
3167
        return factory()
 
3168
 
 
3169
    def helper():
 
3170
        bd = BzrDirMetaFormat1()
 
3171
        if branch_format is not None:
 
3172
            bd.set_branch_format(_load(branch_format))
 
3173
        if tree_format is not None:
 
3174
            bd.workingtree_format = _load(tree_format)
 
3175
        if repository_format is not None:
 
3176
            bd.repository_format = _load(repository_format)
 
3177
        return bd
 
3178
    format_registry.register(key, helper, help, native, deprecated, hidden,
 
3179
        experimental, alias)
 
3180
 
3340
3181
# The pre-0.8 formats have their repository format network name registered in
3341
3182
# repository.py. MetaDir formats have their repository format network name
3342
3183
# inferred from their disk format string.
3345
3186
    ' support checkouts or shared repositories.',
3346
3187
    hidden=True,
3347
3188
    deprecated=True)
3348
 
format_registry.register_metadir('metaweave',
 
3189
register_metadir('metaweave',
3349
3190
    'bzrlib.repofmt.weaverepo.RepositoryFormat7',
3350
3191
    'Transitional format in 0.8.  Slower than knit.',
3351
3192
    branch_format='bzrlib.branch.BzrBranchFormat5',
3352
3193
    tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3353
3194
    hidden=True,
3354
3195
    deprecated=True)
3355
 
format_registry.register_metadir('knit',
 
3196
register_metadir('knit',
3356
3197
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3357
3198
    'Format using knits.  Recommended for interoperation with bzr <= 0.14.',
3358
3199
    branch_format='bzrlib.branch.BzrBranchFormat5',
3359
3200
    tree_format='bzrlib.workingtree.WorkingTreeFormat3',
3360
3201
    hidden=True,
3361
3202
    deprecated=True)
3362
 
format_registry.register_metadir('dirstate',
 
3203
register_metadir('dirstate',
3363
3204
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3364
3205
    help='New in 0.15: Fast local operations. Compatible with bzr 0.8 and '
3365
3206
        'above when accessed over the network.',
3369
3210
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3370
3211
    hidden=True,
3371
3212
    deprecated=True)
3372
 
format_registry.register_metadir('dirstate-tags',
 
3213
register_metadir('dirstate-tags',
3373
3214
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit1',
3374
3215
    help='New in 0.15: Fast local operations and improved scaling for '
3375
3216
        'network operations. Additionally adds support for tags.'
3378
3219
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3379
3220
    hidden=True,
3380
3221
    deprecated=True)
3381
 
format_registry.register_metadir('rich-root',
 
3222
register_metadir('rich-root',
3382
3223
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit4',
3383
3224
    help='New in 1.0.  Better handling of tree roots.  Incompatible with'
3384
3225
        ' bzr < 1.0.',
3386
3227
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3387
3228
    hidden=True,
3388
3229
    deprecated=True)
3389
 
format_registry.register_metadir('dirstate-with-subtree',
 
3230
register_metadir('dirstate-with-subtree',
3390
3231
    'bzrlib.repofmt.knitrepo.RepositoryFormatKnit3',
3391
3232
    help='New in 0.15: Fast local operations and improved scaling for '
3392
3233
        'network operations. Additionally adds support for versioning nested '
3396
3237
    experimental=True,
3397
3238
    hidden=True,
3398
3239
    )
3399
 
format_registry.register_metadir('pack-0.92',
 
3240
register_metadir('pack-0.92',
3400
3241
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack1',
3401
3242
    help='New in 0.92: Pack-based format with data compatible with '
3402
3243
        'dirstate-tags format repositories. Interoperates with '
3405
3246
    branch_format='bzrlib.branch.BzrBranchFormat6',
3406
3247
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3407
3248
    )
3408
 
format_registry.register_metadir('pack-0.92-subtree',
 
3249
register_metadir('pack-0.92-subtree',
3409
3250
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack3',
3410
3251
    help='New in 0.92: Pack-based format with data compatible with '
3411
3252
        'dirstate-with-subtree format repositories. Interoperates with '
3416
3257
    hidden=True,
3417
3258
    experimental=True,
3418
3259
    )
3419
 
format_registry.register_metadir('rich-root-pack',
 
3260
register_metadir('rich-root-pack',
3420
3261
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack4',
3421
3262
    help='New in 1.0: A variant of pack-0.92 that supports rich-root data '
3422
3263
         '(needed for bzr-svn and bzr-git).',
3424
3265
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3425
3266
    hidden=True,
3426
3267
    )
3427
 
format_registry.register_metadir('1.6',
 
3268
register_metadir('1.6',
3428
3269
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5',
3429
3270
    help='A format that allows a branch to indicate that there is another '
3430
3271
         '(stacked) repository that should be used to access data that is '
3433
3274
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3434
3275
    hidden=True,
3435
3276
    )
3436
 
format_registry.register_metadir('1.6.1-rich-root',
 
3277
register_metadir('1.6.1-rich-root',
3437
3278
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack5RichRoot',
3438
3279
    help='A variant of 1.6 that supports rich-root data '
3439
3280
         '(needed for bzr-svn and bzr-git).',
3441
3282
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3442
3283
    hidden=True,
3443
3284
    )
3444
 
format_registry.register_metadir('1.9',
 
3285
register_metadir('1.9',
3445
3286
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3446
3287
    help='A repository format using B+tree indexes. These indexes '
3447
3288
         'are smaller in size, have smarter caching and provide faster '
3450
3291
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3451
3292
    hidden=True,
3452
3293
    )
3453
 
format_registry.register_metadir('1.9-rich-root',
 
3294
register_metadir('1.9-rich-root',
3454
3295
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3455
3296
    help='A variant of 1.9 that supports rich-root data '
3456
3297
         '(needed for bzr-svn and bzr-git).',
3458
3299
    tree_format='bzrlib.workingtree.WorkingTreeFormat4',
3459
3300
    hidden=True,
3460
3301
    )
3461
 
format_registry.register_metadir('1.14',
 
3302
register_metadir('1.14',
3462
3303
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6',
3463
3304
    help='A working-tree format that supports content filtering.',
3464
3305
    branch_format='bzrlib.branch.BzrBranchFormat7',
3465
3306
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
3466
3307
    )
3467
 
format_registry.register_metadir('1.14-rich-root',
 
3308
register_metadir('1.14-rich-root',
3468
3309
    'bzrlib.repofmt.pack_repo.RepositoryFormatKnitPack6RichRoot',
3469
3310
    help='A variant of 1.14 that supports rich-root data '
3470
3311
         '(needed for bzr-svn and bzr-git).',
3472
3313
    tree_format='bzrlib.workingtree.WorkingTreeFormat5',
3473
3314
    )
3474
3315
# The following un-numbered 'development' formats should always just be aliases.
3475
 
format_registry.register_metadir('development-rich-root',
 
3316
register_metadir('development-rich-root',
3476
3317
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
3477
3318
    help='Current development format. Supports rich roots. Can convert data '
3478
3319
        'to and from rich-root-pack (and anything compatible with '
3486
3327
    alias=True,
3487
3328
    hidden=True,
3488
3329
    )
3489
 
format_registry.register_metadir('development-subtree',
 
3330
register_metadir('development-subtree',
3490
3331
    'bzrlib.repofmt.pack_repo.RepositoryFormatPackDevelopment2Subtree',
3491
3332
    help='Current development format, subtree variant. Can convert data to and '
3492
3333
        'from pack-0.92-subtree (and anything compatible with '
3504
3345
    )
3505
3346
 
3506
3347
# And the development formats above will have aliased one of the following:
3507
 
format_registry.register_metadir('development6-rich-root',
 
3348
register_metadir('development6-rich-root',
3508
3349
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK1',
3509
3350
    help='pack-1.9 with 255-way hashed CHK inv, group compress, rich roots '
3510
3351
        'Please read '
3516
3357
    experimental=True,
3517
3358
    )
3518
3359
 
3519
 
format_registry.register_metadir('development7-rich-root',
 
3360
register_metadir('development7-rich-root',
3520
3361
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormatCHK2',
3521
3362
    help='pack-1.9 with 255-way hashed CHK inv, bencode revision, group compress, '
3522
3363
        'rich roots. Please read '
3528
3369
    experimental=True,
3529
3370
    )
3530
3371
 
3531
 
format_registry.register_metadir('2a',
 
3372
register_metadir('2a',
3532
3373
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
3533
3374
    help='First format for bzr 2.0 series.\n'
3534
3375
        'Uses group-compress storage.\n'
3542
3383
 
3543
3384
# The following format should be an alias for the rich root equivalent 
3544
3385
# of the default format
3545
 
format_registry.register_metadir('default-rich-root',
 
3386
register_metadir('default-rich-root',
3546
3387
    'bzrlib.repofmt.groupcompress_repo.RepositoryFormat2a',
3547
3388
    branch_format='bzrlib.branch.BzrBranchFormat7',
3548
3389
    tree_format='bzrlib.workingtree.WorkingTreeFormat6',
3552
3393
 
3553
3394
# The current format that is made on 'bzr init'.
3554
3395
format_registry.set_default('2a')
3555
 
 
3556
 
probers.append(BzrProber)
3557
 
server_probers.append(RemoteBzrProber)