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')
103
87
super(AllInOneRepository, self).__init__(_format, a_bzrdir, a_bzrdir._control_files)
88
self._fetch_order = 'topological'
89
self._fetch_reconcile = True
106
92
def _all_possible_ids(self):
107
93
"""Return all the possible revisions that we could find."""
108
94
if 'evil' in debug.debug_flags:
109
trace.mutter_callsite(
110
3, "_all_possible_ids scales with size of history.")
95
mutter_callsite(3, "_all_possible_ids scales with size of history.")
111
96
return [key[-1] for key in self.inventories.keys()]
114
99
def _all_revision_ids(self):
115
"""Returns a list of all the revision ids in the repository.
100
"""Returns a list of all the revision ids in the repository.
117
These are in as much topological order as the underlying store can
102
These are in as much topological order as the underlying store can
118
103
present: for weaves ghosts may lead to a lack of correctness until
119
104
the reweave updates the parents list.
163
148
return self.inventories.add_lines((revision_id,), final_parents, lines,
164
149
check_content=check_content)[0]
166
152
def is_shared(self):
167
153
"""AllInOne repositories cannot be shared."""
177
163
:param new_value: True to restore the default, False to disable making
180
raise errors.RepositoryUpgradeRequired(self.user_url)
166
raise errors.RepositoryUpgradeRequired(self.bzrdir.root_transport.base)
182
168
def make_working_trees(self):
183
169
"""Returns the policy for making working trees on new branches."""
192
178
class WeaveMetaDirRepository(MetaDirVersionedFileRepository):
193
179
"""A subclass of MetaDirRepository to set weave specific policy."""
181
_serializer = xml5.serializer_v5
195
183
def __init__(self, _format, a_bzrdir, control_files):
196
184
super(WeaveMetaDirRepository, self).__init__(_format, a_bzrdir, control_files)
197
self._serializer = _format._serializer
185
self._fetch_order = 'topological'
186
self._fetch_reconcile = True
200
189
def _all_possible_ids(self):
201
190
"""Return all the possible revisions that we could find."""
202
191
if 'evil' in debug.debug_flags:
203
trace.mutter_callsite(
204
3, "_all_possible_ids scales with size of history.")
192
mutter_callsite(3, "_all_possible_ids scales with size of history.")
205
193
return [key[-1] for key in self.inventories.keys()]
208
196
def _all_revision_ids(self):
209
"""Returns a list of all the revision ids in the repository.
197
"""Returns a list of all the revision ids in the repository.
211
These are in as much topological order as the underlying store can
199
These are in as much topological order as the underlying store can
212
200
present: for weaves ghosts may lead to a lack of correctness until
213
201
the reweave updates the parents list.
269
257
supports_tree_reference = False
270
258
supports_ghosts = False
271
259
supports_external_lookups = False
272
supports_chks = False
273
_fetch_order = 'topological'
274
_fetch_reconcile = True
277
261
def initialize(self, a_bzrdir, shared=False, _internal=False):
278
262
"""Create a weave repository."""
282
266
if not _internal:
283
267
# always initialized when the bzrdir is.
284
268
return self.open(a_bzrdir, _found=True)
286
270
# Create an empty weave
288
272
weavefile.write_weave_v5(weave.Weave(), sio)
289
273
empty_weave = sio.getvalue()
291
trace.mutter('creating repository in %s.', a_bzrdir.transport.base)
275
mutter('creating repository in %s.', a_bzrdir.transport.base)
293
277
# FIXME: RBC 20060125 don't peek under the covers
294
278
# NB: no need to escape relative paths that are url safe.
295
279
control_files = lockable_files.LockableFiles(a_bzrdir.transport,
301
285
transport.mkdir_multi(['revision-store', 'weaves'],
302
286
mode=a_bzrdir._get_dir_mode())
303
transport.put_bytes_non_atomic('inventory.weave', empty_weave,
304
mode=a_bzrdir._get_file_mode())
287
transport.put_bytes_non_atomic('inventory.weave', empty_weave)
306
289
control_files.unlock()
307
repository = self.open(a_bzrdir, _found=True)
308
self._run_post_repo_init_hooks(repository, a_bzrdir, shared)
290
return self.open(a_bzrdir, _found=True)
311
292
def open(self, a_bzrdir, _found=False):
312
293
"""See RepositoryFormat.open()."""
321
302
result.signatures = self._get_signatures(repo_transport, result)
322
303
result.inventories = self._get_inventories(repo_transport, result)
323
304
result.texts = self._get_texts(repo_transport, result)
324
result.chk_bytes = None
307
def check_conversion_target(self, target_format):
328
311
class RepositoryFormat4(PreSplitOutRepositoryFormat):
329
312
"""Bzr repository format 4.
340
323
_matchingbzrdir = bzrdir.BzrDirFormat4()
326
super(RepositoryFormat4, self).__init__()
327
self._fetch_order = 'topological'
328
self._fetch_reconcile = True
342
330
def get_format_description(self):
343
331
"""See RepositoryFormat.get_format_description()."""
344
332
return "Repository format 4"
351
339
"""Format 4 is not supported.
353
341
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
342
conversion logic is expensive - so doing it on the fly was not
387
375
_versionedfile_class = weave.WeaveFile
388
376
_matchingbzrdir = bzrdir.BzrDirFormat5()
390
def _serializer(self):
391
return xml5.serializer_v5
379
super(RepositoryFormat5, self).__init__()
380
self._fetch_order = 'topological'
381
self._fetch_reconcile = True
393
383
def get_format_description(self):
394
384
"""See RepositoryFormat.get_format_description()."""
395
385
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
387
def _get_inventories(self, repo_transport, repo, name='inventory'):
402
388
mapper = versionedfile.ConstantMapper(name)
403
389
return versionedfile.ThunkedVersionedFiles(repo_transport,
404
390
weave.WeaveFile, mapper, repo.is_locked)
406
392
def _get_revisions(self, repo_transport, repo):
393
from bzrlib.xml5 import serializer_v5
407
394
return RevisionTextStore(repo_transport.clone('revision-store'),
408
xml5.serializer_v5, False, versionedfile.PrefixMapper(),
395
serializer_v5, False, versionedfile.PrefixMapper(),
409
396
repo.is_locked, repo.is_write_locked)
411
398
def _get_signatures(self, repo_transport, repo):
432
419
_versionedfile_class = weave.WeaveFile
433
420
_matchingbzrdir = bzrdir.BzrDirFormat6()
435
def _serializer(self):
436
return xml5.serializer_v5
423
super(RepositoryFormat6, self).__init__()
424
self._fetch_order = 'topological'
425
self._fetch_reconcile = True
438
427
def get_format_description(self):
439
428
"""See RepositoryFormat.get_format_description()."""
440
429
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
431
def _get_inventories(self, repo_transport, repo, name='inventory'):
447
432
mapper = versionedfile.ConstantMapper(name)
448
433
return versionedfile.ThunkedVersionedFiles(repo_transport,
449
434
weave.WeaveFile, mapper, repo.is_locked)
451
436
def _get_revisions(self, repo_transport, repo):
437
from bzrlib.xml5 import serializer_v5
452
438
return RevisionTextStore(repo_transport.clone('revision-store'),
453
xml5.serializer_v5, False, versionedfile.HashPrefixMapper(),
439
serializer_v5, False, versionedfile.HashPrefixMapper(),
454
440
repo.is_locked, repo.is_write_locked)
456
442
def _get_signatures(self, repo_transport, repo):
480
466
_versionedfile_class = weave.WeaveFile
481
467
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
469
def get_format_string(self):
492
470
"""See RepositoryFormat.get_format_string()."""
496
474
"""See RepositoryFormat.get_format_description()."""
497
475
return "Weave repository format 7"
477
def check_conversion_target(self, target_format):
499
480
def _get_inventories(self, repo_transport, repo, name='inventory'):
500
481
mapper = versionedfile.ConstantMapper(name)
501
482
return versionedfile.ThunkedVersionedFiles(repo_transport,
502
483
weave.WeaveFile, mapper, repo.is_locked)
504
485
def _get_revisions(self, repo_transport, repo):
486
from bzrlib.xml5 import serializer_v5
505
487
return RevisionTextStore(repo_transport.clone('revision-store'),
506
xml5.serializer_v5, True, versionedfile.HashPrefixMapper(),
488
serializer_v5, True, versionedfile.HashPrefixMapper(),
507
489
repo.is_locked, repo.is_write_locked)
509
491
def _get_signatures(self, repo_transport, repo):
528
510
weavefile.write_weave_v5(weave.Weave(), sio)
529
511
empty_weave = sio.getvalue()
531
trace.mutter('creating repository in %s.', a_bzrdir.transport.base)
513
mutter('creating repository in %s.', a_bzrdir.transport.base)
532
514
dirs = ['revision-store', 'weaves']
533
files = [('inventory.weave', StringIO(empty_weave)),
515
files = [('inventory.weave', StringIO(empty_weave)),
535
517
utf8_files = [('format', self.get_format_string())]
537
519
self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)
538
520
return self.open(a_bzrdir=a_bzrdir, _found=True)
540
522
def open(self, a_bzrdir, _found=False, _override_transport=None):
541
523
"""See RepositoryFormat.open().
543
525
:param _override_transport: INTERNAL USE ONLY. Allows opening the
544
526
repository at a slightly different url
545
527
than normal. I.e. during 'upgrade'.
558
540
result.signatures = self._get_signatures(repo_transport, result)
559
541
result.inventories = self._get_inventories(repo_transport, result)
560
542
result.texts = self._get_texts(repo_transport, result)
561
result.chk_bytes = None
562
543
result._transport = repo_transport
668
649
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
652
def get_record_stream(self, keys, sort_order, include_delta_closure):
680
654
text, parents = self._load_text_parents(key)
692
666
path, ext = os.path.splitext(relpath)
695
if not relpath.endswith('.sig'):
669
if '.sig' not in relpath:
696
670
relpaths.add(relpath)
697
671
paths = list(relpaths)
698
672
return set([self._mapper.unmap(path) for path in paths])