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
53
from bzrlib.store.text import TextStore
54
from bzrlib.trace import mutter
57
55
from bzrlib.tuned_gzip import GzipFile, bytes_to_gzip
58
56
from bzrlib.versionedfile import (
59
57
AbsentContentFactory,
69
67
def _serializer(self):
70
68
return xml5.serializer_v5
72
def _escape(self, file_or_path):
73
if not isinstance(file_or_path, basestring):
74
file_or_path = '/'.join(file_or_path)
75
if file_or_path == '':
77
return urlutils.escape(osutils.safe_unicode(file_or_path))
79
70
def __init__(self, _format, a_bzrdir):
80
71
# we reuse one control files instance.
81
72
dir_mode = a_bzrdir._get_dir_mode()
84
75
def get_store(name, compressed=True, prefixed=False):
85
76
# 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
77
# or entirely uncompressed is tidy, but breaks upgrade from
78
# some existing branches where there's a mixture; we probably
88
79
# still want the option to look for both.
89
relpath = self._escape(name)
80
relpath = a_bzrdir._control_files._escape(name)
90
81
store = TextStore(a_bzrdir.transport.clone(relpath),
91
82
prefixed=prefixed, compressed=compressed,
96
87
# not broken out yet because the controlweaves|inventory_store
97
88
# and texts bits are still different.
98
89
if isinstance(_format, RepositoryFormat4):
99
# cannot remove these - there is still no consistent api
90
# cannot remove these - there is still no consistent api
100
91
# which allows access to this old info.
101
92
self.inventory_store = get_store('inventory-store')
102
93
self._text_store = get_store('text-store')
103
94
super(AllInOneRepository, self).__init__(_format, a_bzrdir, a_bzrdir._control_files)
95
self._fetch_order = 'topological'
96
self._fetch_reconcile = True
106
99
def _all_possible_ids(self):
107
100
"""Return all the possible revisions that we could find."""
108
101
if 'evil' in debug.debug_flags:
109
trace.mutter_callsite(
110
3, "_all_possible_ids scales with size of history.")
102
mutter_callsite(3, "_all_possible_ids scales with size of history.")
111
103
return [key[-1] for key in self.inventories.keys()]
114
106
def _all_revision_ids(self):
115
"""Returns a list of all the revision ids in the repository.
107
"""Returns a list of all the revision ids in the repository.
117
These are in as much topological order as the underlying store can
109
These are in as much topological order as the underlying store can
118
110
present: for weaves ghosts may lead to a lack of correctness until
119
111
the reweave updates the parents list.
177
169
:param new_value: True to restore the default, False to disable making
180
raise errors.RepositoryUpgradeRequired(self.user_url)
172
raise errors.RepositoryUpgradeRequired(self.bzrdir.root_transport.base)
182
174
def make_working_trees(self):
183
175
"""Returns the policy for making working trees on new branches."""
192
184
class WeaveMetaDirRepository(MetaDirVersionedFileRepository):
193
185
"""A subclass of MetaDirRepository to set weave specific policy."""
188
def _serializer(self):
189
return xml5.serializer_v5
195
191
def __init__(self, _format, a_bzrdir, control_files):
196
192
super(WeaveMetaDirRepository, self).__init__(_format, a_bzrdir, control_files)
197
self._serializer = _format._serializer
193
self._fetch_order = 'topological'
194
self._fetch_reconcile = True
200
197
def _all_possible_ids(self):
201
198
"""Return all the possible revisions that we could find."""
202
199
if 'evil' in debug.debug_flags:
203
trace.mutter_callsite(
204
3, "_all_possible_ids scales with size of history.")
200
mutter_callsite(3, "_all_possible_ids scales with size of history.")
205
201
return [key[-1] for key in self.inventories.keys()]
208
204
def _all_revision_ids(self):
209
"""Returns a list of all the revision ids in the repository.
205
"""Returns a list of all the revision ids in the repository.
211
These are in as much topological order as the underlying store can
207
These are in as much topological order as the underlying store can
212
208
present: for weaves ghosts may lead to a lack of correctness until
213
209
the reweave updates the parents list.
269
265
supports_tree_reference = False
270
266
supports_ghosts = False
271
267
supports_external_lookups = False
272
supports_chks = False
273
_fetch_order = 'topological'
274
_fetch_reconcile = True
277
269
def initialize(self, a_bzrdir, shared=False, _internal=False):
278
270
"""Create a weave repository."""
282
274
if not _internal:
283
275
# always initialized when the bzrdir is.
284
276
return self.open(a_bzrdir, _found=True)
286
278
# Create an empty weave
288
280
weavefile.write_weave_v5(weave.Weave(), sio)
289
281
empty_weave = sio.getvalue()
291
trace.mutter('creating repository in %s.', a_bzrdir.transport.base)
283
mutter('creating repository in %s.', a_bzrdir.transport.base)
293
285
# FIXME: RBC 20060125 don't peek under the covers
294
286
# NB: no need to escape relative paths that are url safe.
295
287
control_files = lockable_files.LockableFiles(a_bzrdir.transport,
301
293
transport.mkdir_multi(['revision-store', 'weaves'],
302
294
mode=a_bzrdir._get_dir_mode())
303
transport.put_bytes_non_atomic('inventory.weave', empty_weave,
304
mode=a_bzrdir._get_file_mode())
295
transport.put_bytes_non_atomic('inventory.weave', empty_weave)
306
297
control_files.unlock()
307
repository = self.open(a_bzrdir, _found=True)
308
self._run_post_repo_init_hooks(repository, a_bzrdir, shared)
298
return self.open(a_bzrdir, _found=True)
311
300
def open(self, a_bzrdir, _found=False):
312
301
"""See RepositoryFormat.open()."""
321
310
result.signatures = self._get_signatures(repo_transport, result)
322
311
result.inventories = self._get_inventories(repo_transport, result)
323
312
result.texts = self._get_texts(repo_transport, result)
324
result.chk_bytes = None
315
def check_conversion_target(self, target_format):
328
319
class RepositoryFormat4(PreSplitOutRepositoryFormat):
329
320
"""Bzr repository format 4.
340
331
_matchingbzrdir = bzrdir.BzrDirFormat4()
334
super(RepositoryFormat4, self).__init__()
335
self._fetch_order = 'topological'
336
self._fetch_reconcile = True
342
338
def get_format_description(self):
343
339
"""See RepositoryFormat.get_format_description()."""
344
340
return "Repository format 4"
351
347
"""Format 4 is not supported.
353
349
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
350
conversion logic is expensive - so doing it on the fly was not
387
383
_versionedfile_class = weave.WeaveFile
388
384
_matchingbzrdir = bzrdir.BzrDirFormat5()
390
def _serializer(self):
391
return xml5.serializer_v5
387
super(RepositoryFormat5, self).__init__()
388
self._fetch_order = 'topological'
389
self._fetch_reconcile = True
393
391
def get_format_description(self):
394
392
"""See RepositoryFormat.get_format_description()."""
395
393
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
395
def _get_inventories(self, repo_transport, repo, name='inventory'):
402
396
mapper = versionedfile.ConstantMapper(name)
403
397
return versionedfile.ThunkedVersionedFiles(repo_transport,
404
398
weave.WeaveFile, mapper, repo.is_locked)
406
400
def _get_revisions(self, repo_transport, repo):
401
from bzrlib.xml5 import serializer_v5
407
402
return RevisionTextStore(repo_transport.clone('revision-store'),
408
xml5.serializer_v5, False, versionedfile.PrefixMapper(),
403
serializer_v5, False, versionedfile.PrefixMapper(),
409
404
repo.is_locked, repo.is_write_locked)
411
406
def _get_signatures(self, repo_transport, repo):
432
427
_versionedfile_class = weave.WeaveFile
433
428
_matchingbzrdir = bzrdir.BzrDirFormat6()
435
def _serializer(self):
436
return xml5.serializer_v5
431
super(RepositoryFormat6, self).__init__()
432
self._fetch_order = 'topological'
433
self._fetch_reconcile = True
438
435
def get_format_description(self):
439
436
"""See RepositoryFormat.get_format_description()."""
440
437
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
439
def _get_inventories(self, repo_transport, repo, name='inventory'):
447
440
mapper = versionedfile.ConstantMapper(name)
448
441
return versionedfile.ThunkedVersionedFiles(repo_transport,
449
442
weave.WeaveFile, mapper, repo.is_locked)
451
444
def _get_revisions(self, repo_transport, repo):
445
from bzrlib.xml5 import serializer_v5
452
446
return RevisionTextStore(repo_transport.clone('revision-store'),
453
xml5.serializer_v5, False, versionedfile.HashPrefixMapper(),
447
serializer_v5, False, versionedfile.HashPrefixMapper(),
454
448
repo.is_locked, repo.is_write_locked)
456
450
def _get_signatures(self, repo_transport, repo):
480
474
_versionedfile_class = weave.WeaveFile
481
475
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
477
def get_format_string(self):
492
478
"""See RepositoryFormat.get_format_string()."""
496
482
"""See RepositoryFormat.get_format_description()."""
497
483
return "Weave repository format 7"
485
def check_conversion_target(self, target_format):
499
488
def _get_inventories(self, repo_transport, repo, name='inventory'):
500
489
mapper = versionedfile.ConstantMapper(name)
501
490
return versionedfile.ThunkedVersionedFiles(repo_transport,
502
491
weave.WeaveFile, mapper, repo.is_locked)
504
493
def _get_revisions(self, repo_transport, repo):
494
from bzrlib.xml5 import serializer_v5
505
495
return RevisionTextStore(repo_transport.clone('revision-store'),
506
xml5.serializer_v5, True, versionedfile.HashPrefixMapper(),
496
serializer_v5, True, versionedfile.HashPrefixMapper(),
507
497
repo.is_locked, repo.is_write_locked)
509
499
def _get_signatures(self, repo_transport, repo):
528
518
weavefile.write_weave_v5(weave.Weave(), sio)
529
519
empty_weave = sio.getvalue()
531
trace.mutter('creating repository in %s.', a_bzrdir.transport.base)
521
mutter('creating repository in %s.', a_bzrdir.transport.base)
532
522
dirs = ['revision-store', 'weaves']
533
files = [('inventory.weave', StringIO(empty_weave)),
523
files = [('inventory.weave', StringIO(empty_weave)),
535
525
utf8_files = [('format', self.get_format_string())]
537
527
self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)
538
528
return self.open(a_bzrdir=a_bzrdir, _found=True)
540
530
def open(self, a_bzrdir, _found=False, _override_transport=None):
541
531
"""See RepositoryFormat.open().
543
533
:param _override_transport: INTERNAL USE ONLY. Allows opening the
544
534
repository at a slightly different url
545
535
than normal. I.e. during 'upgrade'.
558
548
result.signatures = self._get_signatures(repo_transport, result)
559
549
result.inventories = self._get_inventories(repo_transport, result)
560
550
result.texts = self._get_texts(repo_transport, result)
561
result.chk_bytes = None
562
551
result._transport = repo_transport
668
657
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
660
def get_record_stream(self, keys, sort_order, include_delta_closure):
680
662
text, parents = self._load_text_parents(key)
692
674
path, ext = os.path.splitext(relpath)
695
if not relpath.endswith('.sig'):
677
if '.sig' not in relpath:
696
678
relpaths.add(relpath)
697
679
paths = list(relpaths)
698
680
return set([self._mapper.unmap(path) for path in paths])