1
# Copyright (C) 2005, 2006, 2007 Canonical Ltd
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
# GNU General Public License for more details.
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17
from bzrlib.lazy_import import lazy_import
18
lazy_import(globals(), """
22
from bzrlib.index import InMemoryGraphIndex, GraphIndex, CombinedGraphIndex
23
from bzrlib.knit import KnitGraphIndex
24
from bzrlib.store import revision
39
from bzrlib.decorators import needs_read_lock, needs_write_lock
40
from bzrlib.repository import (
42
MetaDirRepositoryFormat,
46
import bzrlib.revision as _mod_revision
47
from bzrlib.store.revision.knit import KnitRevisionStore
48
from bzrlib.store.versioned import VersionedFileStore
49
from bzrlib.trace import mutter, note, warning
52
class _KnitParentsProvider(object):
54
def __init__(self, knit):
58
return 'KnitParentsProvider(%r)' % self._knit
60
def get_parents(self, revision_ids):
62
for revision_id in revision_ids:
63
if revision_id == _mod_revision.NULL_REVISION:
67
parents = self._knit.get_parents_with_ghosts(revision_id)
68
except errors.RevisionNotPresent:
72
parents = [_mod_revision.NULL_REVISION]
73
parents_list.append(parents)
77
class KnitRepository(MetaDirRepository):
78
"""Knit format repository."""
80
_serializer = xml5.serializer_v5
82
def _warn_if_deprecated(self):
83
# This class isn't deprecated
86
def _inventory_add_lines(self, inv_vf, revid, parents, lines):
87
inv_vf.add_lines_with_ghosts(revid, parents, lines)
90
def _all_revision_ids(self):
91
"""See Repository.all_revision_ids()."""
92
# Knits get the revision graph from the index of the revision knit, so
93
# it's always possible even if they're on an unlistable transport.
94
return self._revision_store.all_revision_ids(self.get_transaction())
96
def fileid_involved_between_revs(self, from_revid, to_revid):
97
"""Find file_id(s) which are involved in the changes between revisions.
99
This determines the set of revisions which are involved, and then
100
finds all file ids affected by those revisions.
102
from_revid = osutils.safe_revision_id(from_revid)
103
to_revid = osutils.safe_revision_id(to_revid)
104
vf = self._get_revision_vf()
105
from_set = set(vf.get_ancestry(from_revid))
106
to_set = set(vf.get_ancestry(to_revid))
107
changed = to_set.difference(from_set)
108
return self._fileid_involved_by_set(changed)
110
def fileid_involved(self, last_revid=None):
111
"""Find all file_ids modified in the ancestry of last_revid.
113
:param last_revid: If None, last_revision() will be used.
116
changed = set(self.all_revision_ids())
118
changed = set(self.get_ancestry(last_revid))
121
return self._fileid_involved_by_set(changed)
124
def get_ancestry(self, revision_id, topo_sorted=True):
125
"""Return a list of revision-ids integrated by a revision.
127
This is topologically sorted, unless 'topo_sorted' is specified as
130
if _mod_revision.is_null(revision_id):
132
revision_id = osutils.safe_revision_id(revision_id)
133
vf = self._get_revision_vf()
135
return [None] + vf.get_ancestry(revision_id, topo_sorted)
136
except errors.RevisionNotPresent:
137
raise errors.NoSuchRevision(self, revision_id)
140
def get_revision(self, revision_id):
141
"""Return the Revision object for a named revision"""
142
revision_id = osutils.safe_revision_id(revision_id)
143
return self.get_revision_reconcile(revision_id)
146
def get_revision_graph(self, revision_id=None):
147
"""Return a dictionary containing the revision graph.
149
:param revision_id: The revision_id to get a graph from. If None, then
150
the entire revision graph is returned. This is a deprecated mode of
151
operation and will be removed in the future.
152
:return: a dictionary of revision_id->revision_parents_list.
154
# special case NULL_REVISION
155
if revision_id == _mod_revision.NULL_REVISION:
157
revision_id = osutils.safe_revision_id(revision_id)
158
a_weave = self._get_revision_vf()
159
if revision_id is None:
160
return a_weave.get_graph()
161
if revision_id not in a_weave:
162
raise errors.NoSuchRevision(self, revision_id)
164
return a_weave.get_graph([revision_id])
167
def get_revision_graph_with_ghosts(self, revision_ids=None):
168
"""Return a graph of the revisions with ghosts marked as applicable.
170
:param revision_ids: an iterable of revisions to graph or None for all.
171
:return: a Graph object with the graph reachable from revision_ids.
173
result = deprecated_graph.Graph()
174
vf = self._get_revision_vf()
175
versions = set(vf.versions())
177
pending = set(self.all_revision_ids())
180
pending = set(osutils.safe_revision_id(r) for r in revision_ids)
181
# special case NULL_REVISION
182
if _mod_revision.NULL_REVISION in pending:
183
pending.remove(_mod_revision.NULL_REVISION)
184
required = set(pending)
187
revision_id = pending.pop()
188
if not revision_id in versions:
189
if revision_id in required:
190
raise errors.NoSuchRevision(self, revision_id)
192
result.add_ghost(revision_id)
193
# mark it as done so we don't try for it again.
194
done.add(revision_id)
196
parent_ids = vf.get_parents_with_ghosts(revision_id)
197
for parent_id in parent_ids:
198
# is this queued or done ?
199
if (parent_id not in pending and
200
parent_id not in done):
202
pending.add(parent_id)
203
result.add_node(revision_id, parent_ids)
204
done.add(revision_id)
207
def _get_revision_vf(self):
208
""":return: a versioned file containing the revisions."""
209
vf = self._revision_store.get_revision_file(self.get_transaction())
212
def _get_history_vf(self):
213
"""Get a versionedfile whose history graph reflects all revisions.
215
For knit repositories, this is the revision knit.
217
return self._get_revision_vf()
220
def reconcile(self, other=None, thorough=False):
221
"""Reconcile this repository."""
222
from bzrlib.reconcile import KnitReconciler
223
reconciler = KnitReconciler(self, thorough=thorough)
224
reconciler.reconcile()
227
def revision_parents(self, revision_id):
228
revision_id = osutils.safe_revision_id(revision_id)
229
return self._get_revision_vf().get_parents(revision_id)
231
def _make_parents_provider(self):
232
return _KnitParentsProvider(self._get_revision_vf())
235
class KnitRepository3(KnitRepository):
237
def __init__(self, _format, a_bzrdir, control_files, _revision_store,
238
control_store, text_store):
239
KnitRepository.__init__(self, _format, a_bzrdir, control_files,
240
_revision_store, control_store, text_store)
241
self._serializer = xml7.serializer_v7
243
def deserialise_inventory(self, revision_id, xml):
244
"""Transform the xml into an inventory object.
246
:param revision_id: The expected revision id of the inventory.
247
:param xml: A serialised inventory.
249
result = self._serializer.read_inventory_from_string(xml)
250
assert result.root.revision is not None
253
def serialise_inventory(self, inv):
254
"""Transform the inventory object into XML text.
256
:param revision_id: The expected revision id of the inventory.
257
:param xml: A serialised inventory.
259
assert inv.revision_id is not None
260
assert inv.root.revision is not None
261
return KnitRepository.serialise_inventory(self, inv)
263
def get_commit_builder(self, branch, parents, config, timestamp=None,
264
timezone=None, committer=None, revprops=None,
266
"""Obtain a CommitBuilder for this repository.
268
:param branch: Branch to commit to.
269
:param parents: Revision ids of the parents of the new revision.
270
:param config: Configuration to use.
271
:param timestamp: Optional timestamp recorded for commit.
272
:param timezone: Optional timezone for timestamp.
273
:param committer: Optional committer to set for commit.
274
:param revprops: Optional dictionary of revision properties.
275
:param revision_id: Optional revision id.
277
revision_id = osutils.safe_revision_id(revision_id)
278
result = RootCommitBuilder(self, parents, config, timestamp, timezone,
279
committer, revprops, revision_id)
280
self.start_write_group()
284
class GraphKnitRevisionStore(KnitRevisionStore):
285
"""An object to adapt access from RevisionStore's to use GraphKnits.
287
This should not live through to production: by production time we should
288
have fully integrated the new indexing and have new data for the
289
repository classes; also we may choose not to do a Knit1 compatible
290
new repository, just a Knit3 one. If neither of these happen, this
291
should definately be cleaned up before merging.
293
This class works by replacing the original RevisionStore.
294
We need to do this because the GraphKnitRevisionStore is less
295
isolated in its layering - it uses services from the repo.
298
- unlock writes an index even on error. This is fine while we are writing
299
data to knits, but we really should not use unlock to trigger writes,
300
rather operations should finish explicitly.
303
def __init__(self, repo, revisionstore):
304
"""Create a GraphKnitRevisionStore on repo with revisionstore.
306
This will store its state in the Repository, use the
307
revision-indices FileNames to provide a KnitGraphIndex,
308
and at the end of transactions write new indices.
310
KnitRevisionStore.__init__(self, revisionstore.versioned_file_store)
312
self._serializer = revisionstore._serializer
314
def _ensure_names_loaded(self):
315
if self.repo._revision_indices is None:
316
index_transport = self.get_indices_transport()
317
self.repo._revision_indices = file_names.FileNames(
318
index_transport, 'index')
319
self.repo._revision_indices.load()
321
def get_indices_transport(self):
322
return self.versioned_file_store._transport.clone('indices')
324
def get_revision_file(self, transaction):
325
"""Get the revision versioned file object."""
326
if getattr(self.repo, '_revision_knit', None) is not None:
327
return self.repo._revision_knit
328
index_transport = self.get_indices_transport()
330
self._ensure_names_loaded()
331
def _cmp(x, y): return cmp(int(x), int(y))
332
for name in sorted(self.repo._revision_indices.names(), cmp=_cmp, reverse=True):
333
# TODO: maybe this should expose size to us to allow
334
# sorting of the indices for better performance ?
335
index_name = self.name_to_revision_index_name(name)
336
indices.append(GraphIndex(index_transport, index_name))
337
if self.repo.is_in_write_group():
338
# allow writing: queue writes to a new index
339
indices.append(self.repo._revision_write_index)
340
add_callback = self.repo._revision_write_index.add_nodes
342
add_callback = None # no data-adding permitted.
343
self.repo._revision_all_indices = CombinedGraphIndex(indices)
344
knit_index = KnitGraphIndex(self.repo._revision_all_indices,
345
add_callback=add_callback)
346
self.repo._revision_knit = knit.KnitVersionedFile(
347
'revisions', index_transport.clone('..'),
348
self.repo.control_files._file_mode,
349
create=False, access_mode=self.repo.control_files._lock_mode,
350
index=knit_index, delta=False, factory=knit.KnitPlainFactory())
351
return self.repo._revision_knit
353
def get_signature_file(self, transaction):
354
"""Get the signature versioned file object."""
355
if getattr(self.repo, '_signature_knit', None) is not None:
356
return self.repo._signature_knit
357
index_transport = self.get_indices_transport()
359
self._ensure_names_loaded()
360
def _cmp(x, y): return cmp(int(x), int(y))
361
for name in sorted(self.repo._revision_indices.names(), cmp=_cmp, reverse=True):
362
# TODO: maybe this should expose size to us to allow
363
# sorting of the indices for better performance ?
364
index_name = self.name_to_signature_index_name(name)
365
indices.append(GraphIndex(index_transport, index_name))
366
if self.repo.is_in_write_group():
367
# allow writing: queue writes to a new index
368
indices.append(self.repo._signature_write_index)
369
add_callback = self.repo._signature_write_index.add_nodes
371
add_callback = None # no data-adding permitted.
372
self.repo._signature_all_indices = CombinedGraphIndex(indices)
373
knit_index = KnitGraphIndex(self.repo._signature_all_indices,
374
add_callback=add_callback, parents=False)
375
self.repo._signature_knit = knit.KnitVersionedFile(
376
'signatures', index_transport.clone('..'),
377
self.repo.control_files._file_mode,
378
create=False, access_mode=self.repo.control_files._lock_mode,
379
index=knit_index, delta=False, factory=knit.KnitPlainFactory())
380
return self.repo._signature_knit
383
"""Write out pending indices."""
384
# if any work has been done, allocate a new name
385
if (getattr(self.repo, '_revision_knit', None) is not None or
386
getattr(self.repo, '_signature_knit', None) is not None):
387
new_name = self.repo._revision_indices.allocate()
388
self.repo._revision_indices.save()
390
# no knits actually accessed
392
index_transport = self.get_indices_transport()
393
# write a revision index (might be empty)
394
new_index_name = self.name_to_revision_index_name(new_name)
395
index_transport.put_file(new_index_name,
396
self.repo._revision_write_index.finish())
397
self.repo._revision_write_index = None
398
if self.repo._revision_all_indices is not None:
399
# revisions 'knit' accessed : update it.
400
self.repo._revision_all_indices.insert_index(0,
401
GraphIndex(index_transport, new_index_name))
402
# remove the write buffering index. XXX: API break
403
# - clearly we need a remove_index call too.
404
del self.repo._revision_all_indices._indices[-1]
405
# write a signatures index (might be empty)
406
new_index_name = self.name_to_signature_index_name(new_name)
407
index_transport.put_file(new_index_name,
408
self.repo._signature_write_index.finish())
409
self.repo._signature_write_index = None
410
if self.repo._signature_all_indices is not None:
411
# sigatures 'knit' accessed : update it.
412
self.repo._signature_all_indices.insert_index(0,
413
GraphIndex(index_transport, new_index_name))
414
# remove the write buffering index. XXX: API break
415
# - clearly we need a remove_index call too.
416
del self.repo._signature_all_indices._indices[-1]
418
def name_to_revision_index_name(self, name):
419
"""The revision index is the name + .rix."""
422
def name_to_signature_index_name(self, name):
423
"""The signature index is the name + .six."""
427
"""Clear all cached data."""
428
# the packs that exist
429
self.repo._revision_indices = None
430
# cached revision data
431
self.repo._revision_knit = None
432
self.repo._revision_write_index = None
433
self.repo._revision_all_indices = None
434
# cached signature data
435
self.repo._signature_knit = None
436
self.repo._signature_write_index = None
437
self.repo._signature_all_indices = None
440
# setup in-memory indices to accumulate data.
441
if self.repo.control_files._lock_mode != 'w':
442
raise errors.NotWriteLocked(self)
443
self.repo._revision_write_index = InMemoryGraphIndex(1)
444
self.repo._signature_write_index = InMemoryGraphIndex(0)
445
# if knit indices have been handed out, add a mutable
447
if self.repo._revision_knit is not None:
448
self.repo._revision_all_indices.insert_index(0, self.repo._revision_write_index)
449
self.repo._revision_knit._index._add_callback = self.repo._revision_write_index.add_nodes
450
if self.repo._signature_knit is not None:
451
self.repo._signature_all_indices.insert_index(0, self.repo._signature_write_index)
452
self.repo._signature_knit._index._add_callback = self.repo._signature_write_index.add_nodes
455
class GraphKnitRepository1(KnitRepository):
456
"""Experimental graph-knit using repository."""
458
def __init__(self, _format, a_bzrdir, control_files, _revision_store,
459
control_store, text_store):
460
KnitRepository.__init__(self, _format, a_bzrdir, control_files,
461
_revision_store, control_store, text_store)
462
self._revision_store = GraphKnitRevisionStore(self, self._revision_store)
464
def _abort_write_group(self):
465
# FIXME: just drop the transient index.
466
self._revision_store.reset()
468
def _refresh_data(self):
469
if self.control_files._lock_count==1:
470
self._revision_store.reset()
472
def _start_write_group(self):
473
self._revision_store.setup()
475
def _commit_write_group(self):
476
self._revision_store.flush()
477
self._revision_store.reset()
480
class GraphKnitRepository3(KnitRepository3):
481
"""Experimental graph-knit using subtrees repository."""
483
def __init__(self, _format, a_bzrdir, control_files, _revision_store,
484
control_store, text_store):
485
KnitRepository3.__init__(self, _format, a_bzrdir, control_files,
486
_revision_store, control_store, text_store)
487
self._revision_store = GraphKnitRevisionStore(self, self._revision_store)
489
def _abort_write_group(self):
490
# FIXME: just drop the transient index.
491
self._revision_store.reset()
493
def _refresh_data(self):
494
if self.control_files._lock_count==1:
495
self._revision_store.reset()
497
def _start_write_group(self):
498
self._revision_store.setup()
500
def _commit_write_group(self):
501
self._revision_store.flush()
502
self._revision_store.reset()
505
class RepositoryFormatKnit(MetaDirRepositoryFormat):
506
"""Bzr repository knit format (generalized).
508
This repository format has:
509
- knits for file texts and inventory
510
- hash subdirectory based stores.
511
- knits for revisions and signatures
512
- TextStores for revisions and signatures.
513
- a format marker of its own
514
- an optional 'shared-storage' flag
515
- an optional 'no-working-trees' flag
519
def _get_control_store(self, repo_transport, control_files):
520
"""Return the control store for this repository."""
521
return VersionedFileStore(
524
file_mode=control_files._file_mode,
525
versionedfile_class=knit.KnitVersionedFile,
526
versionedfile_kwargs={'factory':knit.KnitPlainFactory()},
529
def _get_revision_store(self, repo_transport, control_files):
530
"""See RepositoryFormat._get_revision_store()."""
531
versioned_file_store = VersionedFileStore(
533
file_mode=control_files._file_mode,
536
versionedfile_class=knit.KnitVersionedFile,
537
versionedfile_kwargs={'delta':False,
538
'factory':knit.KnitPlainFactory(),
542
return KnitRevisionStore(versioned_file_store)
544
def _get_text_store(self, transport, control_files):
545
"""See RepositoryFormat._get_text_store()."""
546
return self._get_versioned_file_store('knits',
549
versionedfile_class=knit.KnitVersionedFile,
550
versionedfile_kwargs={
551
'create_parent_dir':True,
553
'dir_mode':control_files._dir_mode,
557
def initialize(self, a_bzrdir, shared=False):
558
"""Create a knit format 1 repository.
560
:param a_bzrdir: bzrdir to contain the new repository; must already
562
:param shared: If true the repository will be initialized as a shared
565
mutter('creating repository in %s.', a_bzrdir.transport.base)
566
dirs = ['revision-store', 'knits']
568
utf8_files = [('format', self.get_format_string())]
570
self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)
571
repo_transport = a_bzrdir.get_repository_transport(None)
572
control_files = lockable_files.LockableFiles(repo_transport,
573
'lock', lockdir.LockDir)
574
control_store = self._get_control_store(repo_transport, control_files)
575
transaction = transactions.WriteTransaction()
576
# trigger a write of the inventory store.
577
control_store.get_weave_or_empty('inventory', transaction)
578
_revision_store = self._get_revision_store(repo_transport, control_files)
579
# the revision id here is irrelevant: it will not be stored, and cannot
581
_revision_store.has_revision_id('A', transaction)
582
_revision_store.get_signature_file(transaction)
583
return self.open(a_bzrdir=a_bzrdir, _found=True)
585
def open(self, a_bzrdir, _found=False, _override_transport=None):
586
"""See RepositoryFormat.open().
588
:param _override_transport: INTERNAL USE ONLY. Allows opening the
589
repository at a slightly different url
590
than normal. I.e. during 'upgrade'.
593
format = RepositoryFormat.find_format(a_bzrdir)
594
assert format.__class__ == self.__class__
595
if _override_transport is not None:
596
repo_transport = _override_transport
598
repo_transport = a_bzrdir.get_repository_transport(None)
599
control_files = lockable_files.LockableFiles(repo_transport,
600
'lock', lockdir.LockDir)
601
text_store = self._get_text_store(repo_transport, control_files)
602
control_store = self._get_control_store(repo_transport, control_files)
603
_revision_store = self._get_revision_store(repo_transport, control_files)
604
return self.repository_class(_format=self,
606
control_files=control_files,
607
_revision_store=_revision_store,
608
control_store=control_store,
609
text_store=text_store)
612
class RepositoryFormatKnit1(RepositoryFormatKnit):
613
"""Bzr repository knit format 1.
615
This repository format has:
616
- knits for file texts and inventory
617
- hash subdirectory based stores.
618
- knits for revisions and signatures
619
- TextStores for revisions and signatures.
620
- a format marker of its own
621
- an optional 'shared-storage' flag
622
- an optional 'no-working-trees' flag
625
This format was introduced in bzr 0.8.
628
repository_class = KnitRepository
630
def __ne__(self, other):
631
return self.__class__ is not other.__class__
633
def get_format_string(self):
634
"""See RepositoryFormat.get_format_string()."""
635
return "Bazaar-NG Knit Repository Format 1"
637
def get_format_description(self):
638
"""See RepositoryFormat.get_format_description()."""
639
return "Knit repository format 1"
641
def check_conversion_target(self, target_format):
645
class RepositoryFormatKnit3(RepositoryFormatKnit):
646
"""Bzr repository knit format 2.
648
This repository format has:
649
- knits for file texts and inventory
650
- hash subdirectory based stores.
651
- knits for revisions and signatures
652
- TextStores for revisions and signatures.
653
- a format marker of its own
654
- an optional 'shared-storage' flag
655
- an optional 'no-working-trees' flag
657
- support for recording full info about the tree root
658
- support for recording tree-references
661
repository_class = KnitRepository3
662
rich_root_data = True
663
supports_tree_reference = True
665
def _get_matching_bzrdir(self):
666
return bzrdir.format_registry.make_bzrdir('dirstate-with-subtree')
668
def _ignore_setting_bzrdir(self, format):
671
_matchingbzrdir = property(_get_matching_bzrdir, _ignore_setting_bzrdir)
673
def check_conversion_target(self, target_format):
674
if not target_format.rich_root_data:
675
raise errors.BadConversionTarget(
676
'Does not support rich root data.', target_format)
677
if not getattr(target_format, 'supports_tree_reference', False):
678
raise errors.BadConversionTarget(
679
'Does not support nested trees', target_format)
681
def get_format_string(self):
682
"""See RepositoryFormat.get_format_string()."""
683
return "Bazaar Knit Repository Format 3 (bzr 0.15)\n"
685
def get_format_description(self):
686
"""See RepositoryFormat.get_format_description()."""
687
return "Knit repository format 3"
690
class RepositoryFormatGraphKnit1(RepositoryFormatKnit):
691
"""Experimental repository with knit1 style data.
693
This repository format has:
694
- knits for file texts and inventory
695
- hash subdirectory based stores.
696
- knits for revisions and signatures
697
- uses a GraphKnitIndex for revisions.knit.
698
- TextStores for revisions and signatures.
699
- a format marker of its own
700
- an optional 'shared-storage' flag
701
- an optional 'no-working-trees' flag
704
This format was introduced in bzr.dev.
707
repository_class = GraphKnitRepository1
709
def _get_matching_bzrdir(self):
710
return bzrdir.format_registry.make_bzrdir('experimental')
712
def _ignore_setting_bzrdir(self, format):
715
_matchingbzrdir = property(_get_matching_bzrdir, _ignore_setting_bzrdir)
717
def __ne__(self, other):
718
return self.__class__ is not other.__class__
720
def get_format_string(self):
721
"""See RepositoryFormat.get_format_string()."""
722
return "Bazaar Experimental no-subtrees\n"
724
def get_format_description(self):
725
"""See RepositoryFormat.get_format_description()."""
726
return "Experimental no-subtrees"
728
def check_conversion_target(self, target_format):
731
def initialize(self, a_bzrdir, shared=False):
732
"""Create an experimental repository.
734
:param a_bzrdir: bzrdir to contain the new repository; must already
736
:param shared: If true the repository will be initialized as a shared
739
# setup a basic Knit1 repository.
740
result = RepositoryFormatKnit.initialize(self, a_bzrdir, shared)
741
_knit_to_experimental(result, a_bzrdir)
745
def _knit_to_experimental(result, a_bzrdir):
746
"""Convert a knit1/3 repo to an experimental layout repo."""
747
# and adapt it to a GraphKnit repo
748
mutter('changing to GraphKnit1 repository in %s.', a_bzrdir.transport.base)
749
repo_transport = a_bzrdir.get_repository_transport(None)
750
repo_transport.mkdir('indices')
751
names = file_names.FileNames(
752
repo_transport.clone('indices'), 'index')
755
repo_transport.delete('revisions.kndx')
756
repo_transport.delete('signatures.kndx')
759
class RepositoryFormatGraphKnit3(RepositoryFormatKnit3):
760
"""Experimental repository with knit3 style data.
762
This repository format has:
763
- knits for file texts and inventory
764
- hash subdirectory based stores.
765
- knits for revisions and signatures
766
- uses a GraphKnitIndex for revisions.knit.
767
- TextStores for revisions and signatures.
768
- a format marker of its own
769
- an optional 'shared-storage' flag
770
- an optional 'no-working-trees' flag
772
- support for recording full info about the tree root
773
- support for recording tree-references
776
repository_class = GraphKnitRepository3
778
def _get_matching_bzrdir(self):
779
return bzrdir.format_registry.make_bzrdir('experimental-subtree')
781
def _ignore_setting_bzrdir(self, format):
784
_matchingbzrdir = property(_get_matching_bzrdir, _ignore_setting_bzrdir)
786
def get_format_string(self):
787
"""See RepositoryFormat.get_format_string()."""
788
return "Bazaar Experimental subtrees\n"
790
def get_format_description(self):
791
"""See RepositoryFormat.get_format_description()."""
792
return "Experimental no-subtrees\n"
794
def initialize(self, a_bzrdir, shared=False):
795
"""Create an experimental repository.
797
:param a_bzrdir: bzrdir to contain the new repository; must already
799
:param shared: If true the repository will be initialized as a shared
802
# setup a basic Knit1 repository.
803
result = RepositoryFormatKnit.initialize(self, a_bzrdir, shared)
804
_knit_to_experimental(result, a_bzrdir)