~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/repository.py

  • Committer: INADA Naoki
  • Date: 2011-05-18 06:27:34 UTC
  • mfrom: (5887 +trunk)
  • mto: This revision was merged to the branch mainline in revision 5894.
  • Revision ID: songofacandy@gmail.com-20110518062734-1ilhll0rrqyyp8um
merge from lp:bzr and resolve conflicts.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1676
1676
    InterRepository.get(other).method_name(parameters).
1677
1677
    """
1678
1678
 
1679
 
    _walk_to_common_revisions_batch_size = 50
1680
1679
    _optimisers = []
1681
1680
    """The available optimised InterRepository types."""
1682
1681
 
1707
1706
                            content is copied.
1708
1707
        :return: None.
1709
1708
        """
1710
 
        ui.ui_factory.warn_experimental_format_fetch(self)
1711
 
        from bzrlib.fetch import RepoFetcher
1712
 
        # See <https://launchpad.net/bugs/456077> asking for a warning here
1713
 
        if self.source._format.network_name() != self.target._format.network_name():
1714
 
            ui.ui_factory.show_user_warning('cross_format_fetch',
1715
 
                from_format=self.source._format,
1716
 
                to_format=self.target._format)
1717
 
        f = RepoFetcher(to_repository=self.target,
1718
 
                               from_repository=self.source,
1719
 
                               last_revision=revision_id,
1720
 
                               fetch_spec=fetch_spec,
1721
 
                               find_ghosts=find_ghosts)
1722
 
 
1723
 
    def _walk_to_common_revisions(self, revision_ids, if_present_ids=None):
1724
 
        """Walk out from revision_ids in source to revisions target has.
1725
 
 
1726
 
        :param revision_ids: The start point for the search.
1727
 
        :return: A set of revision ids.
1728
 
        """
1729
 
        target_graph = self.target.get_graph()
1730
 
        revision_ids = frozenset(revision_ids)
1731
 
        if if_present_ids:
1732
 
            all_wanted_revs = revision_ids.union(if_present_ids)
1733
 
        else:
1734
 
            all_wanted_revs = revision_ids
1735
 
        missing_revs = set()
1736
 
        source_graph = self.source.get_graph()
1737
 
        # ensure we don't pay silly lookup costs.
1738
 
        searcher = source_graph._make_breadth_first_searcher(all_wanted_revs)
1739
 
        null_set = frozenset([_mod_revision.NULL_REVISION])
1740
 
        searcher_exhausted = False
1741
 
        while True:
1742
 
            next_revs = set()
1743
 
            ghosts = set()
1744
 
            # Iterate the searcher until we have enough next_revs
1745
 
            while len(next_revs) < self._walk_to_common_revisions_batch_size:
1746
 
                try:
1747
 
                    next_revs_part, ghosts_part = searcher.next_with_ghosts()
1748
 
                    next_revs.update(next_revs_part)
1749
 
                    ghosts.update(ghosts_part)
1750
 
                except StopIteration:
1751
 
                    searcher_exhausted = True
1752
 
                    break
1753
 
            # If there are ghosts in the source graph, and the caller asked for
1754
 
            # them, make sure that they are present in the target.
1755
 
            # We don't care about other ghosts as we can't fetch them and
1756
 
            # haven't been asked to.
1757
 
            ghosts_to_check = set(revision_ids.intersection(ghosts))
1758
 
            revs_to_get = set(next_revs).union(ghosts_to_check)
1759
 
            if revs_to_get:
1760
 
                have_revs = set(target_graph.get_parent_map(revs_to_get))
1761
 
                # we always have NULL_REVISION present.
1762
 
                have_revs = have_revs.union(null_set)
1763
 
                # Check if the target is missing any ghosts we need.
1764
 
                ghosts_to_check.difference_update(have_revs)
1765
 
                if ghosts_to_check:
1766
 
                    # One of the caller's revision_ids is a ghost in both the
1767
 
                    # source and the target.
1768
 
                    raise errors.NoSuchRevision(
1769
 
                        self.source, ghosts_to_check.pop())
1770
 
                missing_revs.update(next_revs - have_revs)
1771
 
                # Because we may have walked past the original stop point, make
1772
 
                # sure everything is stopped
1773
 
                stop_revs = searcher.find_seen_ancestors(have_revs)
1774
 
                searcher.stop_searching_any(stop_revs)
1775
 
            if searcher_exhausted:
1776
 
                break
1777
 
        return searcher.get_result()
 
1709
        raise NotImplementedError(self.fetch)
1778
1710
 
1779
1711
    @needs_read_lock
1780
1712
    def search_missing_revision_ids(self,
1795
1727
            rather than just finding the surface difference.
1796
1728
        :return: A bzrlib.graph.SearchResult.
1797
1729
        """
1798
 
        if symbol_versioning.deprecated_passed(revision_id):
1799
 
            symbol_versioning.warn(
1800
 
                'search_missing_revision_ids(revision_id=...) was '
1801
 
                'deprecated in 2.4.  Use revision_ids=[...] instead.',
1802
 
                DeprecationWarning, stacklevel=2)
1803
 
            if revision_ids is not None:
1804
 
                raise AssertionError(
1805
 
                    'revision_ids is mutually exclusive with revision_id')
1806
 
            if revision_id is not None:
1807
 
                revision_ids = [revision_id]
1808
 
        del revision_id
1809
 
        # stop searching at found target revisions.
1810
 
        if not find_ghosts and (revision_ids is not None or if_present_ids is
1811
 
                not None):
1812
 
            return self._walk_to_common_revisions(revision_ids,
1813
 
                    if_present_ids=if_present_ids)
1814
 
        # generic, possibly worst case, slow code path.
1815
 
        target_ids = set(self.target.all_revision_ids())
1816
 
        source_ids = self._present_source_revisions_for(
1817
 
            revision_ids, if_present_ids)
1818
 
        result_set = set(source_ids).difference(target_ids)
1819
 
        return self.source.revision_ids_to_search_result(result_set)
1820
 
 
1821
 
    def _present_source_revisions_for(self, revision_ids, if_present_ids=None):
1822
 
        """Returns set of all revisions in ancestry of revision_ids present in
1823
 
        the source repo.
1824
 
 
1825
 
        :param revision_ids: if None, all revisions in source are returned.
1826
 
        :param if_present_ids: like revision_ids, but if any/all of these are
1827
 
            absent no error is raised.
1828
 
        """
1829
 
        if revision_ids is not None or if_present_ids is not None:
1830
 
            # First, ensure all specified revisions exist.  Callers expect
1831
 
            # NoSuchRevision when they pass absent revision_ids here.
1832
 
            if revision_ids is None:
1833
 
                revision_ids = set()
1834
 
            if if_present_ids is None:
1835
 
                if_present_ids = set()
1836
 
            revision_ids = set(revision_ids)
1837
 
            if_present_ids = set(if_present_ids)
1838
 
            all_wanted_ids = revision_ids.union(if_present_ids)
1839
 
            graph = self.source.get_graph()
1840
 
            present_revs = set(graph.get_parent_map(all_wanted_ids))
1841
 
            missing = revision_ids.difference(present_revs)
1842
 
            if missing:
1843
 
                raise errors.NoSuchRevision(self.source, missing.pop())
1844
 
            found_ids = all_wanted_ids.intersection(present_revs)
1845
 
            source_ids = [rev_id for (rev_id, parents) in
1846
 
                          graph.iter_ancestry(found_ids)
1847
 
                          if rev_id != _mod_revision.NULL_REVISION
1848
 
                          and parents is not None]
1849
 
        else:
1850
 
            source_ids = self.source.all_revision_ids()
1851
 
        return set(source_ids)
 
1730
        raise NotImplementedError(self.search_missing_revision_ids)
1852
1731
 
1853
1732
    @staticmethod
1854
1733
    def _same_model(source, target):
1874
1753
            raise errors.IncompatibleRepositories(source, target,
1875
1754
                "different serializers")
1876
1755
 
1877
 
    @classmethod
1878
 
    def _get_repo_format_to_test(self):
1879
 
        return None
1880
 
 
1881
 
    @classmethod
1882
 
    def is_compatible(cls, source, target):
1883
 
        # The default implementation is compatible with everything
1884
 
        return True
1885
 
 
1886
 
 
1887
 
InterRepository.register_optimiser(InterRepository)
1888
 
 
1889
1756
 
1890
1757
class CopyConverter(object):
1891
1758
    """A repository conversion tool which just performs a copy of the content.