~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repofmt/weaverepo.py

  • Committer: Andrew Bennetts
  • Date: 2011-01-06 06:26:23 UTC
  • mto: This revision was merged to the branch mainline in revision 5612.
  • Revision ID: andrew.bennetts@canonical.com-20110106062623-43tda58mqroybjui
Start of a developer doc describing how fetch works.

Show diffs side-by-side

added added

removed removed

Lines of Context:
29
29
from bzrlib import (
30
30
    xml5,
31
31
    graph as _mod_graph,
 
32
    ui,
32
33
    )
33
34
""")
34
35
from bzrlib import (
38
39
    lockable_files,
39
40
    lockdir,
40
41
    osutils,
41
 
    revision as _mod_revision,
 
42
    symbol_versioning,
42
43
    trace,
43
44
    urlutils,
44
45
    versionedfile,
48
49
from bzrlib.decorators import needs_read_lock, needs_write_lock
49
50
from bzrlib.repository import (
50
51
    CommitBuilder,
 
52
    InterRepository,
 
53
    InterSameDataRepository,
51
54
    MetaDirVersionedFileRepository,
52
55
    MetaDirRepositoryFormat,
53
56
    Repository,
738
741
        paths = list(relpaths)
739
742
        return set([self._mapper.unmap(path) for path in paths])
740
743
 
 
744
 
 
745
class InterWeaveRepo(InterSameDataRepository):
 
746
    """Optimised code paths between Weave based repositories.
 
747
 
 
748
    This should be in bzrlib/repofmt/weaverepo.py but we have not yet
 
749
    implemented lazy inter-object optimisation.
 
750
    """
 
751
 
 
752
    @classmethod
 
753
    def _get_repo_format_to_test(self):
 
754
        return RepositoryFormat7()
 
755
 
 
756
    @staticmethod
 
757
    def is_compatible(source, target):
 
758
        """Be compatible with known Weave formats.
 
759
 
 
760
        We don't test for the stores being of specific types because that
 
761
        could lead to confusing results, and there is no need to be
 
762
        overly general.
 
763
        """
 
764
        try:
 
765
            return (isinstance(source._format, (RepositoryFormat5,
 
766
                                                RepositoryFormat6,
 
767
                                                RepositoryFormat7)) and
 
768
                    isinstance(target._format, (RepositoryFormat5,
 
769
                                                RepositoryFormat6,
 
770
                                                RepositoryFormat7)))
 
771
        except AttributeError:
 
772
            return False
 
773
 
 
774
    @needs_write_lock
 
775
    def copy_content(self, revision_id=None):
 
776
        """See InterRepository.copy_content()."""
 
777
        # weave specific optimised path:
 
778
        try:
 
779
            self.target.set_make_working_trees(self.source.make_working_trees())
 
780
        except (errors.RepositoryUpgradeRequired, NotImplemented):
 
781
            pass
 
782
        # FIXME do not peek!
 
783
        if self.source._transport.listable():
 
784
            pb = ui.ui_factory.nested_progress_bar()
 
785
            try:
 
786
                self.target.texts.insert_record_stream(
 
787
                    self.source.texts.get_record_stream(
 
788
                        self.source.texts.keys(), 'topological', False))
 
789
                pb.update('Copying inventory', 0, 1)
 
790
                self.target.inventories.insert_record_stream(
 
791
                    self.source.inventories.get_record_stream(
 
792
                        self.source.inventories.keys(), 'topological', False))
 
793
                self.target.signatures.insert_record_stream(
 
794
                    self.source.signatures.get_record_stream(
 
795
                        self.source.signatures.keys(),
 
796
                        'unordered', True))
 
797
                self.target.revisions.insert_record_stream(
 
798
                    self.source.revisions.get_record_stream(
 
799
                        self.source.revisions.keys(),
 
800
                        'topological', True))
 
801
            finally:
 
802
                pb.finished()
 
803
        else:
 
804
            self.target.fetch(self.source, revision_id=revision_id)
 
805
 
 
806
    @needs_read_lock
 
807
    def search_missing_revision_ids(self,
 
808
            revision_id=symbol_versioning.DEPRECATED_PARAMETER,
 
809
            find_ghosts=True, revision_ids=None, if_present_ids=None):
 
810
        """See InterRepository.search_missing_revision_ids()."""
 
811
        # we want all revisions to satisfy revision_id in source.
 
812
        # but we don't want to stat every file here and there.
 
813
        # we want then, all revisions other needs to satisfy revision_id
 
814
        # checked, but not those that we have locally.
 
815
        # so the first thing is to get a subset of the revisions to
 
816
        # satisfy revision_id in source, and then eliminate those that
 
817
        # we do already have.
 
818
        # this is slow on high latency connection to self, but as this
 
819
        # disk format scales terribly for push anyway due to rewriting
 
820
        # inventory.weave, this is considered acceptable.
 
821
        # - RBC 20060209
 
822
        if symbol_versioning.deprecated_passed(revision_id):
 
823
            symbol_versioning.warn(
 
824
                'search_missing_revision_ids(revision_id=...) was '
 
825
                'deprecated in 2.3.  Use revision_ids=[...] instead.',
 
826
                DeprecationWarning, stacklevel=2)
 
827
            if revision_ids is not None:
 
828
                raise AssertionError(
 
829
                    'revision_ids is mutually exclusive with revision_id')
 
830
            if revision_id is not None:
 
831
                revision_ids = [revision_id]
 
832
        del revision_id
 
833
        source_ids_set = self._present_source_revisions_for(
 
834
            revision_ids, if_present_ids)
 
835
        # source_ids is the worst possible case we may need to pull.
 
836
        # now we want to filter source_ids against what we actually
 
837
        # have in target, but don't try to check for existence where we know
 
838
        # we do not have a revision as that would be pointless.
 
839
        target_ids = set(self.target._all_possible_ids())
 
840
        possibly_present_revisions = target_ids.intersection(source_ids_set)
 
841
        actually_present_revisions = set(
 
842
            self.target._eliminate_revisions_not_present(possibly_present_revisions))
 
843
        required_revisions = source_ids_set.difference(actually_present_revisions)
 
844
        if revision_ids is not None:
 
845
            # we used get_ancestry to determine source_ids then we are assured all
 
846
            # revisions referenced are present as they are installed in topological order.
 
847
            # and the tip revision was validated by get_ancestry.
 
848
            result_set = required_revisions
 
849
        else:
 
850
            # if we just grabbed the possibly available ids, then
 
851
            # we only have an estimate of whats available and need to validate
 
852
            # that against the revision records.
 
853
            result_set = set(
 
854
                self.source._eliminate_revisions_not_present(required_revisions))
 
855
        return self.source.revision_ids_to_search_result(result_set)
 
856
 
 
857
 
741
858
_legacy_formats = [RepositoryFormat4(),
742
859
                   RepositoryFormat5(),
743
860
                   RepositoryFormat6()]
 
861
 
 
862
 
 
863
InterRepository.register_optimiser(InterWeaveRepo)