2491
2515
ancestors will be traversed.
2493
2517
graph = self.get_graph()
2494
next_id = revision_id
2496
if next_id in (None, _mod_revision.NULL_REVISION):
2499
parents = graph.get_parent_map([next_id])[next_id]
2501
raise errors.RevisionNotPresent(next_id, self)
2503
if len(parents) == 0:
2506
next_id = parents[0]
2509
def get_revision_inventory(self, revision_id):
2510
"""Return inventory of a past revision."""
2511
# TODO: Unify this with get_inventory()
2512
# bzr 0.0.6 and later imposes the constraint that the inventory_id
2513
# must be the same as its revision, so this is trivial.
2514
if revision_id is None:
2515
# This does not make sense: if there is no revision,
2516
# then it is the current tree inventory surely ?!
2517
# and thus get_root_id() is something that looks at the last
2518
# commit on the branch, and the get_root_id is an inventory check.
2519
raise NotImplementedError
2520
# return Inventory(self.get_root_id())
2522
return self.get_inventory(revision_id)
2518
stop_revisions = (None, _mod_revision.NULL_REVISION)
2519
return graph.iter_lefthand_ancestry(revision_id, stop_revisions)
2524
2521
def is_shared(self):
2525
2522
"""Return True if this repository is flagged as a shared repository."""
3335
3352
'bzrlib.repofmt.pack_repo',
3336
3353
'RepositoryFormatKnitPack6RichRoot',
3355
format_registry.register_lazy(
3356
'Bazaar repository format 2a (needs bzr 1.16 or later)\n',
3357
'bzrlib.repofmt.groupcompress_repo',
3358
'RepositoryFormat2a',
3339
3361
# Development formats.
3340
# Obsolete but kept pending a CHK based subtree format.
3362
# Check their docstrings to see if/when they are obsolete.
3341
3363
format_registry.register_lazy(
3342
3364
("Bazaar development format 2 with subtree support "
3343
3365
"(needs bzr.dev from before 1.8)\n"),
3344
3366
'bzrlib.repofmt.pack_repo',
3345
3367
'RepositoryFormatPackDevelopment2Subtree',
3348
# 1.14->1.16 go below here
3349
format_registry.register_lazy(
3350
'Bazaar development format - group compression and chk inventory'
3351
' (needs bzr.dev from 1.14)\n',
3352
'bzrlib.repofmt.groupcompress_repo',
3353
'RepositoryFormatCHK1',
3356
format_registry.register_lazy(
3357
'Bazaar development format - chk repository with bencode revision '
3358
'serialization (needs bzr.dev from 1.16)\n',
3359
'bzrlib.repofmt.groupcompress_repo',
3360
'RepositoryFormatCHK2',
3362
format_registry.register_lazy(
3363
'Bazaar repository format 2a (needs bzr 1.16 or later)\n',
3364
'bzrlib.repofmt.groupcompress_repo',
3365
'RepositoryFormat2a',
3369
format_registry.register_lazy(
3370
'Bazaar development format 8\n',
3371
'bzrlib.repofmt.groupcompress_repo',
3372
'RepositoryFormat2aSubtree',
3540
3553
return InterRepository._same_model(source, target)
3543
class InterWeaveRepo(InterSameDataRepository):
3544
"""Optimised code paths between Weave based repositories.
3546
This should be in bzrlib/repofmt/weaverepo.py but we have not yet
3547
implemented lazy inter-object optimisation.
3551
def _get_repo_format_to_test(self):
3552
from bzrlib.repofmt import weaverepo
3553
return weaverepo.RepositoryFormat7()
3556
def is_compatible(source, target):
3557
"""Be compatible with known Weave formats.
3559
We don't test for the stores being of specific types because that
3560
could lead to confusing results, and there is no need to be
3563
from bzrlib.repofmt.weaverepo import (
3569
return (isinstance(source._format, (RepositoryFormat5,
3571
RepositoryFormat7)) and
3572
isinstance(target._format, (RepositoryFormat5,
3574
RepositoryFormat7)))
3575
except AttributeError:
3579
def copy_content(self, revision_id=None):
3580
"""See InterRepository.copy_content()."""
3581
# weave specific optimised path:
3583
self.target.set_make_working_trees(self.source.make_working_trees())
3584
except (errors.RepositoryUpgradeRequired, NotImplemented):
3586
# FIXME do not peek!
3587
if self.source._transport.listable():
3588
pb = ui.ui_factory.nested_progress_bar()
3590
self.target.texts.insert_record_stream(
3591
self.source.texts.get_record_stream(
3592
self.source.texts.keys(), 'topological', False))
3593
pb.update('Copying inventory', 0, 1)
3594
self.target.inventories.insert_record_stream(
3595
self.source.inventories.get_record_stream(
3596
self.source.inventories.keys(), 'topological', False))
3597
self.target.signatures.insert_record_stream(
3598
self.source.signatures.get_record_stream(
3599
self.source.signatures.keys(),
3601
self.target.revisions.insert_record_stream(
3602
self.source.revisions.get_record_stream(
3603
self.source.revisions.keys(),
3604
'topological', True))
3608
self.target.fetch(self.source, revision_id=revision_id)
3611
def search_missing_revision_ids(self, revision_id=None, find_ghosts=True):
3612
"""See InterRepository.missing_revision_ids()."""
3613
# we want all revisions to satisfy revision_id in source.
3614
# but we don't want to stat every file here and there.
3615
# we want then, all revisions other needs to satisfy revision_id
3616
# checked, but not those that we have locally.
3617
# so the first thing is to get a subset of the revisions to
3618
# satisfy revision_id in source, and then eliminate those that
3619
# we do already have.
3620
# this is slow on high latency connection to self, but as this
3621
# disk format scales terribly for push anyway due to rewriting
3622
# inventory.weave, this is considered acceptable.
3624
if revision_id is not None:
3625
source_ids = self.source.get_ancestry(revision_id)
3626
if source_ids[0] is not None:
3627
raise AssertionError()
3630
source_ids = self.source._all_possible_ids()
3631
source_ids_set = set(source_ids)
3632
# source_ids is the worst possible case we may need to pull.
3633
# now we want to filter source_ids against what we actually
3634
# have in target, but don't try to check for existence where we know
3635
# we do not have a revision as that would be pointless.
3636
target_ids = set(self.target._all_possible_ids())
3637
possibly_present_revisions = target_ids.intersection(source_ids_set)
3638
actually_present_revisions = set(
3639
self.target._eliminate_revisions_not_present(possibly_present_revisions))
3640
required_revisions = source_ids_set.difference(actually_present_revisions)
3641
if revision_id is not None:
3642
# we used get_ancestry to determine source_ids then we are assured all
3643
# revisions referenced are present as they are installed in topological order.
3644
# and the tip revision was validated by get_ancestry.
3645
result_set = required_revisions
3647
# if we just grabbed the possibly available ids, then
3648
# we only have an estimate of whats available and need to validate
3649
# that against the revision records.
3651
self.source._eliminate_revisions_not_present(required_revisions))
3652
return self.source.revision_ids_to_search_result(result_set)
3655
class InterKnitRepo(InterSameDataRepository):
3656
"""Optimised code paths between Knit based repositories."""
3659
def _get_repo_format_to_test(self):
3660
from bzrlib.repofmt import knitrepo
3661
return knitrepo.RepositoryFormatKnit1()
3664
def is_compatible(source, target):
3665
"""Be compatible with known Knit formats.
3667
We don't test for the stores being of specific types because that
3668
could lead to confusing results, and there is no need to be
3671
from bzrlib.repofmt.knitrepo import RepositoryFormatKnit
3673
are_knits = (isinstance(source._format, RepositoryFormatKnit) and
3674
isinstance(target._format, RepositoryFormatKnit))
3675
except AttributeError:
3677
return are_knits and InterRepository._same_model(source, target)
3680
def search_missing_revision_ids(self, revision_id=None, find_ghosts=True):
3681
"""See InterRepository.missing_revision_ids()."""
3682
if revision_id is not None:
3683
source_ids = self.source.get_ancestry(revision_id)
3684
if source_ids[0] is not None:
3685
raise AssertionError()
3688
source_ids = self.source.all_revision_ids()
3689
source_ids_set = set(source_ids)
3690
# source_ids is the worst possible case we may need to pull.
3691
# now we want to filter source_ids against what we actually
3692
# have in target, but don't try to check for existence where we know
3693
# we do not have a revision as that would be pointless.
3694
target_ids = set(self.target.all_revision_ids())
3695
possibly_present_revisions = target_ids.intersection(source_ids_set)
3696
actually_present_revisions = set(
3697
self.target._eliminate_revisions_not_present(possibly_present_revisions))
3698
required_revisions = source_ids_set.difference(actually_present_revisions)
3699
if revision_id is not None:
3700
# we used get_ancestry to determine source_ids then we are assured all
3701
# revisions referenced are present as they are installed in topological order.
3702
# and the tip revision was validated by get_ancestry.
3703
result_set = required_revisions
3705
# if we just grabbed the possibly available ids, then
3706
# we only have an estimate of whats available and need to validate
3707
# that against the revision records.
3709
self.source._eliminate_revisions_not_present(required_revisions))
3710
return self.source.revision_ids_to_search_result(result_set)
3713
3556
class InterDifferingSerializer(InterRepository):