14
14
# along with this program; if not, write to the Free Software
15
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17
from ..lazy_import import lazy_import
17
from __future__ import absolute_import
19
from bzrlib.lazy_import import lazy_import
18
20
lazy_import(globals(), """
26
30
revision as _mod_revision,
30
from breezy.bzr import (
41
from ..repository import (
39
from bzrlib.decorators import needs_read_lock, needs_write_lock
40
from bzrlib.repository import (
43
42
IsInWriteGroupError,
45
from ..bzr.repository import (
46
43
RepositoryFormatMetaDir,
48
from ..bzr.vf_repository import (
45
from bzrlib.vf_repository import (
49
46
InterSameDataRepository,
50
47
MetaDirVersionedFileRepository,
51
48
MetaDirVersionedFileRepositoryFormat,
52
49
VersionedFileCommitBuilder,
50
VersionedFileRootCommitBuilder,
52
from bzrlib import symbol_versioning
56
55
class _KnitParentsProvider(object):
120
119
_commit_builder_class = None
121
120
_serializer = None
123
def __init__(self, _format, a_controldir, control_files, _commit_builder_class,
125
super(KnitRepository, self).__init__(
126
_format, a_controldir, control_files)
122
def __init__(self, _format, a_bzrdir, control_files, _commit_builder_class,
124
super(KnitRepository, self).__init__(_format, a_bzrdir, control_files)
127
125
self._commit_builder_class = _commit_builder_class
128
126
self._serializer = _serializer
129
127
self._reconcile_fixes_text_parents = True
131
130
def _all_revision_ids(self):
132
131
"""See Repository.all_revision_ids()."""
133
with self.lock_read():
134
return [key[0] for key in self.revisions.keys()]
132
return [key[0] for key in self.revisions.keys()]
136
134
def _activate_new_inventory(self):
137
135
"""Put a replacement inventory.new into use as inventories."""
258
257
def _get_inventories(self, repo_transport, repo, name='inventory'):
259
258
mapper = versionedfile.ConstantMapper(name)
260
259
index = _mod_knit._KndxIndex(repo_transport, mapper,
261
repo.get_transaction, repo.is_write_locked, repo.is_locked)
260
repo.get_transaction, repo.is_write_locked, repo.is_locked)
262
261
access = _mod_knit._KnitKeyAccess(repo_transport, mapper)
263
262
return _mod_knit.KnitVersionedFiles(index, access, annotated=False)
265
264
def _get_revisions(self, repo_transport, repo):
266
265
mapper = versionedfile.ConstantMapper('revisions')
267
266
index = _mod_knit._KndxIndex(repo_transport, mapper,
268
repo.get_transaction, repo.is_write_locked, repo.is_locked)
267
repo.get_transaction, repo.is_write_locked, repo.is_locked)
269
268
access = _mod_knit._KnitKeyAccess(repo_transport, mapper)
270
269
return _mod_knit.KnitVersionedFiles(index, access, max_delta_chain=0,
273
272
def _get_signatures(self, repo_transport, repo):
274
273
mapper = versionedfile.ConstantMapper('signatures')
275
274
index = _mod_knit._KndxIndex(repo_transport, mapper,
276
repo.get_transaction, repo.is_write_locked, repo.is_locked)
275
repo.get_transaction, repo.is_write_locked, repo.is_locked)
277
276
access = _mod_knit._KnitKeyAccess(repo_transport, mapper)
278
277
return _mod_knit.KnitVersionedFiles(index, access, max_delta_chain=0,
281
280
def _get_texts(self, repo_transport, repo):
282
281
mapper = versionedfile.HashEscapedPrefixMapper()
283
282
base_transport = repo_transport.clone('knits')
284
283
index = _mod_knit._KndxIndex(base_transport, mapper,
285
repo.get_transaction, repo.is_write_locked, repo.is_locked)
284
repo.get_transaction, repo.is_write_locked, repo.is_locked)
286
285
access = _mod_knit._KnitKeyAccess(base_transport, mapper)
287
286
return _mod_knit.KnitVersionedFiles(index, access, max_delta_chain=200,
290
def initialize(self, a_controldir, shared=False):
289
def initialize(self, a_bzrdir, shared=False):
291
290
"""Create a knit format 1 repository.
293
:param a_controldir: bzrdir to contain the new repository; must already
292
:param a_bzrdir: bzrdir to contain the new repository; must already
295
294
:param shared: If true the repository will be initialized as a shared
298
trace.mutter('creating repository in %s.', a_controldir.transport.base)
297
trace.mutter('creating repository in %s.', a_bzrdir.transport.base)
301
300
utf8_files = [('format', self.get_format_string())]
303
self._upload_blank_content(
304
a_controldir, dirs, files, utf8_files, shared)
305
repo_transport = a_controldir.get_repository_transport(None)
302
self._upload_blank_content(a_bzrdir, dirs, files, utf8_files, shared)
303
repo_transport = a_bzrdir.get_repository_transport(None)
306
304
control_files = lockable_files.LockableFiles(repo_transport,
307
'lock', lockdir.LockDir)
305
'lock', lockdir.LockDir)
308
306
transaction = transactions.WriteTransaction()
309
result = self.open(a_controldir=a_controldir, _found=True)
307
result = self.open(a_bzrdir=a_bzrdir, _found=True)
310
308
result.lock_write()
311
309
# the revision id here is irrelevant: it will not be stored, and cannot
312
310
# already exist, we do this to create files on disk for older clients.
313
result.inventories.get_parent_map([(b'A',)])
314
result.revisions.get_parent_map([(b'A',)])
315
result.signatures.get_parent_map([(b'A',)])
311
result.inventories.get_parent_map([('A',)])
312
result.revisions.get_parent_map([('A',)])
313
result.signatures.get_parent_map([('A',)])
317
self._run_post_repo_init_hooks(result, a_controldir, shared)
315
self._run_post_repo_init_hooks(result, a_bzrdir, shared)
320
def open(self, a_controldir, _found=False, _override_transport=None):
318
def open(self, a_bzrdir, _found=False, _override_transport=None):
321
319
"""See RepositoryFormat.open().
323
321
:param _override_transport: INTERNAL USE ONLY. Allows opening the
325
323
than normal. I.e. during 'upgrade'.
328
format = RepositoryFormatMetaDir.find_format(a_controldir)
326
format = RepositoryFormatMetaDir.find_format(a_bzrdir)
329
327
if _override_transport is not None:
330
328
repo_transport = _override_transport
332
repo_transport = a_controldir.get_repository_transport(None)
330
repo_transport = a_bzrdir.get_repository_transport(None)
333
331
control_files = lockable_files.LockableFiles(repo_transport,
334
'lock', lockdir.LockDir)
332
'lock', lockdir.LockDir)
335
333
repo = self.repository_class(_format=self,
336
a_controldir=a_controldir,
337
control_files=control_files,
338
_commit_builder_class=self._commit_builder_class,
339
_serializer=self._serializer)
335
control_files=control_files,
336
_commit_builder_class=self._commit_builder_class,
337
_serializer=self._serializer)
340
338
repo.revisions = self._get_revisions(repo_transport, repo)
341
339
repo.signatures = self._get_signatures(repo_transport, repo)
342
340
repo.inventories = self._get_inventories(repo_transport, repo)
401
398
repository_class = KnitRepository
402
_commit_builder_class = VersionedFileCommitBuilder
399
_commit_builder_class = VersionedFileRootCommitBuilder
403
400
rich_root_data = True
404
401
experimental = True
405
402
supports_tree_reference = True
408
404
def _serializer(self):
409
405
return xml7.serializer_v7
411
407
def _get_matching_bzrdir(self):
412
return controldir.format_registry.make_controldir('dirstate-with-subtree')
408
return controldir.format_registry.make_bzrdir('dirstate-with-subtree')
414
410
def _ignore_setting_bzrdir(self, format):
417
_matchingcontroldir = property(
418
_get_matching_bzrdir, _ignore_setting_bzrdir)
413
_matchingbzrdir = property(_get_matching_bzrdir, _ignore_setting_bzrdir)
421
416
def get_format_string(cls):
422
417
"""See RepositoryFormat.get_format_string()."""
423
return b"Bazaar Knit Repository Format 3 (bzr 0.15)\n"
418
return "Bazaar Knit Repository Format 3 (bzr 0.15)\n"
425
420
def get_format_description(self):
426
421
"""See RepositoryFormat.get_format_description()."""
446
441
repository_class = KnitRepository
447
_commit_builder_class = VersionedFileCommitBuilder
442
_commit_builder_class = VersionedFileRootCommitBuilder
448
443
rich_root_data = True
449
444
supports_tree_reference = False
452
446
def _serializer(self):
453
447
return xml6.serializer_v6
455
449
def _get_matching_bzrdir(self):
456
return controldir.format_registry.make_controldir('rich-root')
450
return controldir.format_registry.make_bzrdir('rich-root')
458
452
def _ignore_setting_bzrdir(self, format):
461
_matchingcontroldir = property(
462
_get_matching_bzrdir, _ignore_setting_bzrdir)
455
_matchingbzrdir = property(_get_matching_bzrdir, _ignore_setting_bzrdir)
465
458
def get_format_string(cls):
466
459
"""See RepositoryFormat.get_format_string()."""
467
return b'Bazaar Knit Repository Format 4 (bzr 1.0)\n'
460
return 'Bazaar Knit Repository Format 4 (bzr 1.0)\n'
469
462
def get_format_description(self):
470
463
"""See RepositoryFormat.get_format_description()."""
490
are_knits = (isinstance(source._format, RepositoryFormatKnit)
491
and isinstance(target._format, RepositoryFormatKnit))
483
are_knits = (isinstance(source._format, RepositoryFormatKnit) and
484
isinstance(target._format, RepositoryFormatKnit))
492
485
except AttributeError:
494
487
return are_knits and InterRepository._same_model(source, target)
496
490
def search_missing_revision_ids(self,
497
find_ghosts=True, revision_ids=None, if_present_ids=None,
491
find_ghosts=True, revision_ids=None, if_present_ids=None,
499
493
"""See InterRepository.search_missing_revision_ids()."""
500
with self.lock_read():
501
source_ids_set = self._present_source_revisions_for(
502
revision_ids, if_present_ids)
503
# source_ids is the worst possible case we may need to pull.
504
# now we want to filter source_ids against what we actually
505
# have in target, but don't try to check for existence where we know
506
# we do not have a revision as that would be pointless.
507
target_ids = set(self.target.all_revision_ids())
508
possibly_present_revisions = target_ids.intersection(
510
actually_present_revisions = set(
511
self.target._eliminate_revisions_not_present(possibly_present_revisions))
512
required_revisions = source_ids_set.difference(
513
actually_present_revisions)
514
if revision_ids is not None:
515
# we used get_ancestry to determine source_ids then we are assured all
516
# revisions referenced are present as they are installed in topological order.
517
# and the tip revision was validated by get_ancestry.
518
result_set = required_revisions
520
# if we just grabbed the possibly available ids, then
521
# we only have an estimate of whats available and need to validate
522
# that against the revision records.
524
self.source._eliminate_revisions_not_present(required_revisions))
525
if limit is not None:
526
topo_ordered = self.source.get_graph().iter_topo_order(result_set)
527
result_set = set(itertools.islice(topo_ordered, limit))
528
return self.source.revision_ids_to_search_result(result_set)
494
source_ids_set = self._present_source_revisions_for(
495
revision_ids, if_present_ids)
496
# source_ids is the worst possible case we may need to pull.
497
# now we want to filter source_ids against what we actually
498
# have in target, but don't try to check for existence where we know
499
# we do not have a revision as that would be pointless.
500
target_ids = set(self.target.all_revision_ids())
501
possibly_present_revisions = target_ids.intersection(source_ids_set)
502
actually_present_revisions = set(
503
self.target._eliminate_revisions_not_present(possibly_present_revisions))
504
required_revisions = source_ids_set.difference(actually_present_revisions)
505
if revision_ids is not None:
506
# we used get_ancestry to determine source_ids then we are assured all
507
# revisions referenced are present as they are installed in topological order.
508
# and the tip revision was validated by get_ancestry.
509
result_set = required_revisions
511
# if we just grabbed the possibly available ids, then
512
# we only have an estimate of whats available and need to validate
513
# that against the revision records.
515
self.source._eliminate_revisions_not_present(required_revisions))
516
if limit is not None:
517
topo_ordered = self.source.get_graph().iter_topo_order(result_set)
518
result_set = set(itertools.islice(topo_ordered, limit))
519
return self.source.revision_ids_to_search_result(result_set)
531
522
InterRepository.register_optimiser(InterKnitRepo)