46
def __init__(self, transport, branch_format):
47
# circular dependencies:
48
from bzrlib.branch import (BzrBranchFormat4,
52
"""Construct the current default format repository in a_bzrdir."""
53
return RepositoryFormat.get_default_format().initialize(a_bzrdir)
55
def __init__(self, transport, branch_format, _format=None, a_bzrdir=None):
52
56
object.__init__(self)
53
self.control_files = LockableFiles(transport.clone(bzrlib.BZRDIR), 'README')
57
if transport is not None:
58
self.control_files = LockableFiles(transport.clone(bzrlib.BZRDIR), 'README')
60
# TODO: clone into repository if needed
61
self.control_files = LockableFiles(a_bzrdir.transport, 'README')
55
63
dir_mode = self.control_files._dir_mode
56
64
file_mode = self.control_files._file_mode
65
self._format = _format
66
self.bzrdir = a_bzrdir
58
68
def get_weave(name, prefixed=False):
60
name = bzrlib.BZRDIR + '/' + safe_unicode(name)
70
name = safe_unicode(name)
63
73
relpath = self.control_files._escape(name)
64
weave_transport = transport.clone(relpath)
74
weave_transport = self.control_files._transport.clone(relpath)
65
75
ws = WeaveStore(weave_transport, prefixed=prefixed,
67
77
file_mode=file_mode)
90
100
# store = bzrlib.store.CachedStore(store, cache_path)
103
if branch_format is not None:
104
# circular dependencies:
105
from bzrlib.branch import (BzrBranchFormat4,
109
if isinstance(branch_format, BzrBranchFormat4):
110
self._format = RepositoryFormat4()
111
elif isinstance(branch_format, BzrBranchFormat5):
112
self._format = RepositoryFormat5()
113
elif isinstance(branch_format, BzrBranchFormat6):
114
self._format = RepositoryFormat6()
94
if isinstance(branch_format, BzrBranchFormat4):
117
if isinstance(self._format, RepositoryFormat4):
95
118
self.inventory_store = get_store('inventory-store')
96
119
self.text_store = get_store('text-store')
97
120
self.revision_store = get_store('revision-store')
98
elif isinstance(branch_format, BzrBranchFormat5):
121
elif isinstance(self._format, RepositoryFormat5):
99
122
self.control_weaves = get_weave('')
100
123
self.weave_store = get_weave('weaves')
101
124
self.revision_store = get_store('revision-store', compressed=False)
102
elif isinstance(branch_format, BzrBranchFormat6):
125
elif isinstance(self._format, RepositoryFormat6):
103
126
self.control_weaves = get_weave('')
104
127
self.weave_store = get_weave('weaves', prefixed=True)
105
128
self.revision_store = get_store('revision-store', compressed=False,
280
313
def sign_revision(self, revision_id, gpg_strategy):
281
314
plaintext = Testament.from_revision(self, revision_id).as_short_text()
282
315
self.store_revision_signature(gpg_strategy, plaintext, revision_id)
318
class RepositoryFormat(object):
319
"""A repository format.
321
Formats provide three things:
322
* An initialization routine to construct repository data on disk.
323
* a format string which is used when the BzrDir supports versioned
325
* an open routine which returns a Repository instance.
327
Formats are placed in an dict by their format string for reference
328
during opening. These should be subclasses of RepositoryFormat
331
Once a format is deprecated, just deprecate the initialize and open
332
methods on the format class. Do not deprecate the object, as the
333
object will be created every system load.
335
Common instance attributes:
336
_matchingbzrdir - the bzrdir format that the repository format was
337
originally written to work with. This can be used if manually
338
constructing a bzrdir and repository, or more commonly for test suite
342
_default_format = None
343
"""The default format used for new branches."""
346
"""The known formats."""
349
def get_default_format(klass):
350
"""Return the current default format."""
351
return klass._default_format
353
def get_format_string(self):
354
"""Return the ASCII format string that identifies this format.
356
Note that in pre format ?? repositories the format string is
357
not permitted nor written to disk.
359
raise NotImplementedError(self.get_format_string)
361
def initialize(self, a_bzrdir):
362
"""Create a weave repository.
364
TODO: when creating split out bzr branch formats, move this to a common
365
base for Format5, Format6. or something like that.
367
from bzrlib.weavefile import write_weave_v5
368
from bzrlib.weave import Weave
370
# Create an empty weave
372
bzrlib.weavefile.write_weave_v5(Weave(), sio)
373
empty_weave = sio.getvalue()
375
mutter('creating repository in %s.', a_bzrdir.transport.base)
376
dirs = ['revision-store', 'weaves']
377
lock_file = 'branch-lock'
378
files = [('inventory.weave', StringIO(empty_weave)),
381
# FIXME: RBC 20060125 dont peek under the covers
382
# NB: no need to escape relative paths that are url safe.
383
control_files = LockableFiles(a_bzrdir.transport, 'branch-lock')
384
control_files.lock_write()
385
control_files._transport.mkdir_multi(dirs,
386
mode=control_files._dir_mode)
388
for file, content in files:
389
control_files.put(file, content)
391
control_files.unlock()
392
return Repository(None, branch_format=None, _format=self, a_bzrdir=a_bzrdir)
394
def is_supported(self):
395
"""Is this format supported?
397
Supported formats must be initializable and openable.
398
Unsupported formats may not support initialization or committing or
399
some other features depending on the reason for not being supported.
403
def open(self, a_bzrdir, _found=False):
404
"""Return an instance of this format for the bzrdir a_bzrdir.
406
_found is a private parameter, do not use it.
409
raise NotImplementedError
410
return Repository(None, branch_format=None, _format=self, a_bzrdir=a_bzrdir)
413
def register_format(klass, format):
414
klass._formats[format.get_format_string()] = format
417
def set_default_format(klass, format):
418
klass._default_format = format
421
def unregister_format(klass, format):
422
assert klass._formats[format.get_format_string()] is format
423
del klass._formats[format.get_format_string()]
426
class RepositoryFormat4(RepositoryFormat):
427
"""Bzr repository format 4.
429
This repository format has:
431
- TextStores for texts, inventories,revisions.
433
This format is deprecated: it indexes texts using a text id which is
434
removed in format 5; initializationa and write support for this format
439
super(RepositoryFormat4, self).__init__()
440
self._matchingbzrdir = bzrdir.BzrDirFormat4()
442
def initialize(self, url):
443
"""Format 4 branches cannot be created."""
444
raise errors.UninitializableFormat(self)
446
def is_supported(self):
447
"""Format 4 is not supported.
449
It is not supported because the model changed from 4 to 5 and the
450
conversion logic is expensive - so doing it on the fly was not
456
class RepositoryFormat5(RepositoryFormat):
457
"""Bzr control format 5.
459
This repository format has:
460
- weaves for file texts and inventory
462
- TextStores for revisions and signatures.
466
super(RepositoryFormat5, self).__init__()
467
self._matchingbzrdir = bzrdir.BzrDirFormat5()
470
class RepositoryFormat6(RepositoryFormat):
471
"""Bzr control format 6.
473
This repository format has:
474
- weaves for file texts and inventory
475
- hash subdirectory based stores.
476
- TextStores for revisions and signatures.
480
super(RepositoryFormat6, self).__init__()
481
self._matchingbzrdir = bzrdir.BzrDirFormat6()
483
# formats which have no format string are not discoverable
484
# and not independently creatable, so are not registered.
485
# __default_format = RepositoryFormatXXX()
486
# RepositoryFormat.register_format(__default_format)
487
# RepositoryFormat.set_default_format(__default_format)
488
_legacy_formats = [RepositoryFormat4(),
493
class RepositoryTestProviderAdapter(object):
494
"""A tool to generate a suite testing multiple repository formats at once.
496
This is done by copying the test once for each transport and injecting
497
the transport_server, transport_readonly_server, and bzrdir_format and
498
repository_format classes into each copy. Each copy is also given a new id()
499
to make it easy to identify.
502
def __init__(self, transport_server, transport_readonly_server, formats):
503
self._transport_server = transport_server
504
self._transport_readonly_server = transport_readonly_server
505
self._formats = formats
507
def adapt(self, test):
509
for repository_format, bzrdir_format in self._formats:
510
new_test = deepcopy(test)
511
new_test.transport_server = self._transport_server
512
new_test.transport_readonly_server = self._transport_readonly_server
513
new_test.bzrdir_format = bzrdir_format
514
new_test.repository_format = repository_format
515
def make_new_test_id():
516
new_id = "%s(%s)" % (new_test.id(), repository_format.__class__.__name__)
517
return lambda: new_id
518
new_test.id = make_new_test_id()
519
result.addTest(new_test)