1
# Copyright (C) 2005, 2006, 2007, 2008 Canonical Ltd
1
# Copyright (C) 2007-2010 Canonical Ltd
3
3
# This program is free software; you can redistribute it and/or modify
4
4
# it under the terms of the GNU General Public License as published by
13
13
# You should have received a copy of the GNU General Public License
14
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
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
17
"""Deprecated weave-based repository formats.
54
56
from bzrlib.store.text import TextStore
55
from bzrlib.trace import mutter
56
57
from bzrlib.tuned_gzip import GzipFile, bytes_to_gzip
57
58
from bzrlib.versionedfile import (
58
59
AbsentContentFactory,
83
84
def get_store(name, compressed=True, prefixed=False):
84
85
# FIXME: This approach of assuming stores are all entirely compressed
85
# or entirely uncompressed is tidy, but breaks upgrade from
86
# some existing branches where there's a mixture; we probably
86
# or entirely uncompressed is tidy, but breaks upgrade from
87
# some existing branches where there's a mixture; we probably
87
88
# still want the option to look for both.
88
89
relpath = self._escape(name)
89
90
store = TextStore(a_bzrdir.transport.clone(relpath),
95
96
# not broken out yet because the controlweaves|inventory_store
96
97
# and texts bits are still different.
97
98
if isinstance(_format, RepositoryFormat4):
98
# cannot remove these - there is still no consistent api
99
# cannot remove these - there is still no consistent api
99
100
# which allows access to this old info.
100
101
self.inventory_store = get_store('inventory-store')
101
102
self._text_store = get_store('text-store')
102
103
super(AllInOneRepository, self).__init__(_format, a_bzrdir, a_bzrdir._control_files)
103
self._fetch_order = 'topological'
104
self._fetch_reconcile = True
107
106
def _all_possible_ids(self):
108
107
"""Return all the possible revisions that we could find."""
109
108
if 'evil' in debug.debug_flags:
110
mutter_callsite(3, "_all_possible_ids scales with size of history.")
109
trace.mutter_callsite(
110
3, "_all_possible_ids scales with size of history.")
111
111
return [key[-1] for key in self.inventories.keys()]
114
114
def _all_revision_ids(self):
115
"""Returns a list of all the revision ids in the repository.
115
"""Returns a list of all the revision ids in the repository.
117
These are in as much topological order as the underlying store can
117
These are in as much topological order as the underlying store can
118
118
present: for weaves ghosts may lead to a lack of correctness until
119
119
the reweave updates the parents list.
177
177
:param new_value: True to restore the default, False to disable making
180
raise errors.RepositoryUpgradeRequired(self.bzrdir.root_transport.base)
180
raise errors.RepositoryUpgradeRequired(self.user_url)
182
182
def make_working_trees(self):
183
183
"""Returns the policy for making working trees on new branches."""
192
192
class WeaveMetaDirRepository(MetaDirVersionedFileRepository):
193
193
"""A subclass of MetaDirRepository to set weave specific policy."""
196
def _serializer(self):
197
return xml5.serializer_v5
199
195
def __init__(self, _format, a_bzrdir, control_files):
200
196
super(WeaveMetaDirRepository, self).__init__(_format, a_bzrdir, control_files)
201
self._fetch_order = 'topological'
202
self._fetch_reconcile = True
197
self._serializer = _format._serializer
205
200
def _all_possible_ids(self):
206
201
"""Return all the possible revisions that we could find."""
207
202
if 'evil' in debug.debug_flags:
208
mutter_callsite(3, "_all_possible_ids scales with size of history.")
203
trace.mutter_callsite(
204
3, "_all_possible_ids scales with size of history.")
209
205
return [key[-1] for key in self.inventories.keys()]
212
208
def _all_revision_ids(self):
213
"""Returns a list of all the revision ids in the repository.
209
"""Returns a list of all the revision ids in the repository.
215
These are in as much topological order as the underlying store can
211
These are in as much topological order as the underlying store can
216
212
present: for weaves ghosts may lead to a lack of correctness until
217
213
the reweave updates the parents list.
273
269
supports_tree_reference = False
274
270
supports_ghosts = False
275
271
supports_external_lookups = False
272
supports_chks = False
273
_fetch_order = 'topological'
274
_fetch_reconcile = True
277
277
def initialize(self, a_bzrdir, shared=False, _internal=False):
278
278
"""Create a weave repository."""
282
282
if not _internal:
283
283
# always initialized when the bzrdir is.
284
284
return self.open(a_bzrdir, _found=True)
286
286
# Create an empty weave
288
288
weavefile.write_weave_v5(weave.Weave(), sio)
289
289
empty_weave = sio.getvalue()
291
mutter('creating repository in %s.', a_bzrdir.transport.base)
291
trace.mutter('creating repository in %s.', a_bzrdir.transport.base)
293
293
# FIXME: RBC 20060125 don't peek under the covers
294
294
# NB: no need to escape relative paths that are url safe.
295
295
control_files = lockable_files.LockableFiles(a_bzrdir.transport,
301
301
transport.mkdir_multi(['revision-store', 'weaves'],
302
302
mode=a_bzrdir._get_dir_mode())
303
transport.put_bytes_non_atomic('inventory.weave', empty_weave)
303
transport.put_bytes_non_atomic('inventory.weave', empty_weave,
304
mode=a_bzrdir._get_file_mode())
305
306
control_files.unlock()
306
return self.open(a_bzrdir, _found=True)
307
repository = self.open(a_bzrdir, _found=True)
308
self._run_post_repo_init_hooks(repository, a_bzrdir, shared)
308
311
def open(self, a_bzrdir, _found=False):
309
312
"""See RepositoryFormat.open()."""
318
321
result.signatures = self._get_signatures(repo_transport, result)
319
322
result.inventories = self._get_inventories(repo_transport, result)
320
323
result.texts = self._get_texts(repo_transport, result)
324
result.chk_bytes = None
323
def check_conversion_target(self, target_format):
327
328
class RepositoryFormat4(PreSplitOutRepositoryFormat):
328
329
"""Bzr repository format 4.
339
340
_matchingbzrdir = bzrdir.BzrDirFormat4()
342
super(RepositoryFormat4, self).__init__()
343
self._fetch_order = 'topological'
344
self._fetch_reconcile = True
346
342
def get_format_description(self):
347
343
"""See RepositoryFormat.get_format_description()."""
348
344
return "Repository format 4"
355
351
"""Format 4 is not supported.
357
353
It is not supported because the model changed from 4 to 5 and the
358
conversion logic is expensive - so doing it on the fly was not
354
conversion logic is expensive - so doing it on the fly was not
391
387
_versionedfile_class = weave.WeaveFile
392
388
_matchingbzrdir = bzrdir.BzrDirFormat5()
395
super(RepositoryFormat5, self).__init__()
396
self._fetch_order = 'topological'
397
self._fetch_reconcile = True
390
def _serializer(self):
391
return xml5.serializer_v5
399
393
def get_format_description(self):
400
394
"""See RepositoryFormat.get_format_description()."""
401
395
return "Weave repository format 5"
397
def network_name(self):
398
"""The network name for this format is the control dirs disk label."""
399
return self._matchingbzrdir.get_format_string()
403
401
def _get_inventories(self, repo_transport, repo, name='inventory'):
404
402
mapper = versionedfile.ConstantMapper(name)
405
403
return versionedfile.ThunkedVersionedFiles(repo_transport,
406
404
weave.WeaveFile, mapper, repo.is_locked)
408
406
def _get_revisions(self, repo_transport, repo):
409
from bzrlib.xml5 import serializer_v5
410
407
return RevisionTextStore(repo_transport.clone('revision-store'),
411
serializer_v5, False, versionedfile.PrefixMapper(),
408
xml5.serializer_v5, False, versionedfile.PrefixMapper(),
412
409
repo.is_locked, repo.is_write_locked)
414
411
def _get_signatures(self, repo_transport, repo):
435
432
_versionedfile_class = weave.WeaveFile
436
433
_matchingbzrdir = bzrdir.BzrDirFormat6()
439
super(RepositoryFormat6, self).__init__()
440
self._fetch_order = 'topological'
441
self._fetch_reconcile = True
435
def _serializer(self):
436
return xml5.serializer_v5
443
438
def get_format_description(self):
444
439
"""See RepositoryFormat.get_format_description()."""
445
440
return "Weave repository format 6"
442
def network_name(self):
443
"""The network name for this format is the control dirs disk label."""
444
return self._matchingbzrdir.get_format_string()
447
446
def _get_inventories(self, repo_transport, repo, name='inventory'):
448
447
mapper = versionedfile.ConstantMapper(name)
449
448
return versionedfile.ThunkedVersionedFiles(repo_transport,
450
449
weave.WeaveFile, mapper, repo.is_locked)
452
451
def _get_revisions(self, repo_transport, repo):
453
from bzrlib.xml5 import serializer_v5
454
452
return RevisionTextStore(repo_transport.clone('revision-store'),
455
serializer_v5, False, versionedfile.HashPrefixMapper(),
453
xml5.serializer_v5, False, versionedfile.HashPrefixMapper(),
456
454
repo.is_locked, repo.is_write_locked)
458
456
def _get_signatures(self, repo_transport, repo):
482
480
_versionedfile_class = weave.WeaveFile
483
481
supports_ghosts = False
482
supports_chks = False
484
_fetch_order = 'topological'
485
_fetch_reconcile = True
488
def _serializer(self):
489
return xml5.serializer_v5
485
491
def get_format_string(self):
486
492
"""See RepositoryFormat.get_format_string()."""
490
496
"""See RepositoryFormat.get_format_description()."""
491
497
return "Weave repository format 7"
493
def check_conversion_target(self, target_format):
496
499
def _get_inventories(self, repo_transport, repo, name='inventory'):
497
500
mapper = versionedfile.ConstantMapper(name)
498
501
return versionedfile.ThunkedVersionedFiles(repo_transport,
499
502
weave.WeaveFile, mapper, repo.is_locked)
501
504
def _get_revisions(self, repo_transport, repo):
502
from bzrlib.xml5 import serializer_v5
503
505
return RevisionTextStore(repo_transport.clone('revision-store'),
504
serializer_v5, True, versionedfile.HashPrefixMapper(),
506
xml5.serializer_v5, True, versionedfile.HashPrefixMapper(),
505
507
repo.is_locked, repo.is_write_locked)
507
509
def _get_signatures(self, repo_transport, repo):
526
528
weavefile.write_weave_v5(weave.Weave(), sio)
527
529
empty_weave = sio.getvalue()
529
mutter('creating repository in %s.', a_bzrdir.transport.base)
531
trace.mutter('creating repository in %s.', a_bzrdir.transport.base)
530
532
dirs = ['revision-store', 'weaves']
531
files = [('inventory.weave', StringIO(empty_weave)),
533
files = [('inventory.weave', StringIO(empty_weave)),
533
535
utf8_files = [('format', self.get_format_string())]
535
537
self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)
536
538
return self.open(a_bzrdir=a_bzrdir, _found=True)
538
540
def open(self, a_bzrdir, _found=False, _override_transport=None):
539
541
"""See RepositoryFormat.open().
541
543
:param _override_transport: INTERNAL USE ONLY. Allows opening the
542
544
repository at a slightly different url
543
545
than normal. I.e. during 'upgrade'.
556
558
result.signatures = self._get_signatures(repo_transport, result)
557
559
result.inventories = self._get_inventories(repo_transport, result)
558
560
result.texts = self._get_texts(repo_transport, result)
561
result.chk_bytes = None
559
562
result._transport = repo_transport
665
668
result[key] = parents
671
def get_known_graph_ancestry(self, keys):
672
"""Get a KnownGraph instance with the ancestry of keys."""
674
parent_map = self.get_parent_map(keys)
675
kg = _mod_graph.KnownGraph(parent_map)
668
678
def get_record_stream(self, keys, sort_order, include_delta_closure):
670
680
text, parents = self._load_text_parents(key)
682
692
path, ext = os.path.splitext(relpath)
685
if '.sig' not in relpath:
695
if not relpath.endswith('.sig'):
686
696
relpaths.add(relpath)
687
697
paths = list(relpaths)
688
698
return set([self._mapper.unmap(path) for path in paths])