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
48
from bzrlib.store.text import TextStore
49
from bzrlib.trace import mutter
57
50
from bzrlib.tuned_gzip import GzipFile, bytes_to_gzip
58
51
from bzrlib.versionedfile import (
59
52
AbsentContentFactory,
65
58
class AllInOneRepository(Repository):
66
59
"""Legacy support - the repository behaviour for all-in-one branches."""
69
def _serializer(self):
70
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))
61
_serializer = xml5.serializer_v5
79
63
def __init__(self, _format, a_bzrdir):
80
64
# we reuse one control files instance.
84
68
def get_store(name, compressed=True, prefixed=False):
85
69
# 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
70
# or entirely uncompressed is tidy, but breaks upgrade from
71
# some existing branches where there's a mixture; we probably
88
72
# still want the option to look for both.
89
relpath = self._escape(name)
73
relpath = a_bzrdir._control_files._escape(name)
90
74
store = TextStore(a_bzrdir.transport.clone(relpath),
91
75
prefixed=prefixed, compressed=compressed,
96
80
# not broken out yet because the controlweaves|inventory_store
97
81
# and texts bits are still different.
98
82
if isinstance(_format, RepositoryFormat4):
99
# cannot remove these - there is still no consistent api
83
# cannot remove these - there is still no consistent api
100
84
# which allows access to this old info.
101
85
self.inventory_store = get_store('inventory-store')
102
86
self._text_store = get_store('text-store')
106
90
def _all_possible_ids(self):
107
91
"""Return all the possible revisions that we could find."""
108
92
if 'evil' in debug.debug_flags:
109
trace.mutter_callsite(
110
3, "_all_possible_ids scales with size of history.")
93
mutter_callsite(3, "_all_possible_ids scales with size of history.")
111
94
return [key[-1] for key in self.inventories.keys()]
114
97
def _all_revision_ids(self):
115
"""Returns a list of all the revision ids in the repository.
98
"""Returns a list of all the revision ids in the repository.
117
These are in as much topological order as the underlying store can
100
These are in as much topological order as the underlying store can
118
101
present: for weaves ghosts may lead to a lack of correctness until
119
102
the reweave updates the parents list.
163
146
return self.inventories.add_lines((revision_id,), final_parents, lines,
164
147
check_content=check_content)[0]
166
150
def is_shared(self):
167
151
"""AllInOne repositories cannot be shared."""
177
161
:param new_value: True to restore the default, False to disable making
180
raise errors.RepositoryUpgradeRequired(self.user_url)
164
raise errors.RepositoryUpgradeRequired(self.bzrdir.root_transport.base)
182
166
def make_working_trees(self):
183
167
"""Returns the policy for making working trees on new branches."""
192
176
class WeaveMetaDirRepository(MetaDirVersionedFileRepository):
193
177
"""A subclass of MetaDirRepository to set weave specific policy."""
195
def __init__(self, _format, a_bzrdir, control_files):
196
super(WeaveMetaDirRepository, self).__init__(_format, a_bzrdir, control_files)
197
self._serializer = _format._serializer
179
_serializer = xml5.serializer_v5
200
182
def _all_possible_ids(self):
201
183
"""Return all the possible revisions that we could find."""
202
184
if 'evil' in debug.debug_flags:
203
trace.mutter_callsite(
204
3, "_all_possible_ids scales with size of history.")
185
mutter_callsite(3, "_all_possible_ids scales with size of history.")
205
186
return [key[-1] for key in self.inventories.keys()]
208
189
def _all_revision_ids(self):
209
"""Returns a list of all the revision ids in the repository.
190
"""Returns a list of all the revision ids in the repository.
211
These are in as much topological order as the underlying store can
192
These are in as much topological order as the underlying store can
212
193
present: for weaves ghosts may lead to a lack of correctness until
213
194
the reweave updates the parents list.
269
250
supports_tree_reference = False
270
251
supports_ghosts = False
271
252
supports_external_lookups = False
272
supports_chks = False
273
_fetch_order = 'topological'
274
_fetch_reconcile = True
277
254
def initialize(self, a_bzrdir, shared=False, _internal=False):
278
255
"""Create a weave repository."""
282
259
if not _internal:
283
260
# always initialized when the bzrdir is.
284
261
return self.open(a_bzrdir, _found=True)
286
263
# Create an empty weave
288
265
weavefile.write_weave_v5(weave.Weave(), sio)
289
266
empty_weave = sio.getvalue()
291
trace.mutter('creating repository in %s.', a_bzrdir.transport.base)
268
mutter('creating repository in %s.', a_bzrdir.transport.base)
293
270
# FIXME: RBC 20060125 don't peek under the covers
294
271
# NB: no need to escape relative paths that are url safe.
295
272
control_files = lockable_files.LockableFiles(a_bzrdir.transport,
301
278
transport.mkdir_multi(['revision-store', 'weaves'],
302
279
mode=a_bzrdir._get_dir_mode())
303
transport.put_bytes_non_atomic('inventory.weave', empty_weave,
304
mode=a_bzrdir._get_file_mode())
280
transport.put_bytes_non_atomic('inventory.weave', empty_weave)
306
282
control_files.unlock()
307
repository = self.open(a_bzrdir, _found=True)
308
self._run_post_repo_init_hooks(repository, a_bzrdir, shared)
283
return self.open(a_bzrdir, _found=True)
311
285
def open(self, a_bzrdir, _found=False):
312
286
"""See RepositoryFormat.open()."""
321
295
result.signatures = self._get_signatures(repo_transport, result)
322
296
result.inventories = self._get_inventories(repo_transport, result)
323
297
result.texts = self._get_texts(repo_transport, result)
324
result.chk_bytes = None
300
def check_conversion_target(self, target_format):
328
304
class RepositoryFormat4(PreSplitOutRepositoryFormat):
329
305
"""Bzr repository format 4.
340
316
_matchingbzrdir = bzrdir.BzrDirFormat4()
319
super(RepositoryFormat4, self).__init__()
342
321
def get_format_description(self):
343
322
"""See RepositoryFormat.get_format_description()."""
344
323
return "Repository format 4"
351
330
"""Format 4 is not supported.
353
332
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
333
conversion logic is expensive - so doing it on the fly was not
387
366
_versionedfile_class = weave.WeaveFile
388
367
_matchingbzrdir = bzrdir.BzrDirFormat5()
390
def _serializer(self):
391
return xml5.serializer_v5
370
super(RepositoryFormat5, self).__init__()
393
372
def get_format_description(self):
394
373
"""See RepositoryFormat.get_format_description()."""
395
374
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
376
def _get_inventories(self, repo_transport, repo, name='inventory'):
402
377
mapper = versionedfile.ConstantMapper(name)
403
378
return versionedfile.ThunkedVersionedFiles(repo_transport,
404
379
weave.WeaveFile, mapper, repo.is_locked)
406
381
def _get_revisions(self, repo_transport, repo):
382
from bzrlib.xml5 import serializer_v5
407
383
return RevisionTextStore(repo_transport.clone('revision-store'),
408
xml5.serializer_v5, False, versionedfile.PrefixMapper(),
384
serializer_v5, False, versionedfile.PrefixMapper(),
409
385
repo.is_locked, repo.is_write_locked)
411
387
def _get_signatures(self, repo_transport, repo):
432
408
_versionedfile_class = weave.WeaveFile
433
409
_matchingbzrdir = bzrdir.BzrDirFormat6()
435
def _serializer(self):
436
return xml5.serializer_v5
412
super(RepositoryFormat6, self).__init__()
438
414
def get_format_description(self):
439
415
"""See RepositoryFormat.get_format_description()."""
440
416
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
418
def _get_inventories(self, repo_transport, repo, name='inventory'):
447
419
mapper = versionedfile.ConstantMapper(name)
448
420
return versionedfile.ThunkedVersionedFiles(repo_transport,
449
421
weave.WeaveFile, mapper, repo.is_locked)
451
423
def _get_revisions(self, repo_transport, repo):
424
from bzrlib.xml5 import serializer_v5
452
425
return RevisionTextStore(repo_transport.clone('revision-store'),
453
xml5.serializer_v5, False, versionedfile.HashPrefixMapper(),
426
serializer_v5, False, versionedfile.HashPrefixMapper(),
454
427
repo.is_locked, repo.is_write_locked)
456
429
def _get_signatures(self, repo_transport, repo):
480
453
_versionedfile_class = weave.WeaveFile
481
454
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
456
def get_format_string(self):
492
457
"""See RepositoryFormat.get_format_string()."""
496
461
"""See RepositoryFormat.get_format_description()."""
497
462
return "Weave repository format 7"
464
def check_conversion_target(self, target_format):
499
467
def _get_inventories(self, repo_transport, repo, name='inventory'):
500
468
mapper = versionedfile.ConstantMapper(name)
501
469
return versionedfile.ThunkedVersionedFiles(repo_transport,
502
470
weave.WeaveFile, mapper, repo.is_locked)
504
472
def _get_revisions(self, repo_transport, repo):
473
from bzrlib.xml5 import serializer_v5
505
474
return RevisionTextStore(repo_transport.clone('revision-store'),
506
xml5.serializer_v5, True, versionedfile.HashPrefixMapper(),
475
serializer_v5, True, versionedfile.HashPrefixMapper(),
507
476
repo.is_locked, repo.is_write_locked)
509
478
def _get_signatures(self, repo_transport, repo):
528
497
weavefile.write_weave_v5(weave.Weave(), sio)
529
498
empty_weave = sio.getvalue()
531
trace.mutter('creating repository in %s.', a_bzrdir.transport.base)
500
mutter('creating repository in %s.', a_bzrdir.transport.base)
532
501
dirs = ['revision-store', 'weaves']
533
files = [('inventory.weave', StringIO(empty_weave)),
502
files = [('inventory.weave', StringIO(empty_weave)),
535
504
utf8_files = [('format', self.get_format_string())]
537
506
self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)
538
507
return self.open(a_bzrdir=a_bzrdir, _found=True)
540
509
def open(self, a_bzrdir, _found=False, _override_transport=None):
541
510
"""See RepositoryFormat.open().
543
512
:param _override_transport: INTERNAL USE ONLY. Allows opening the
544
513
repository at a slightly different url
545
514
than normal. I.e. during 'upgrade'.
558
527
result.signatures = self._get_signatures(repo_transport, result)
559
528
result.inventories = self._get_inventories(repo_transport, result)
560
529
result.texts = self._get_texts(repo_transport, result)
561
result.chk_bytes = None
562
530
result._transport = repo_transport
668
636
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
639
def get_record_stream(self, keys, sort_order, include_delta_closure):
680
641
text, parents = self._load_text_parents(key)
692
653
path, ext = os.path.splitext(relpath)
695
if not relpath.endswith('.sig'):
656
if '.sig' not in relpath:
696
657
relpaths.add(relpath)
697
658
paths = list(relpaths)
698
659
return set([self._mapper.unmap(path) for path in paths])