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