Rev 5887: (jelmer) Move VersionedFiles-specific implementation from InterRepository to in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Wed May 18 03:39:46 UTC 2011


At file:///home/pqm/archives/thelove/bzr/%2Btrunk/

------------------------------------------------------------
revno: 5887 [merge]
revision-id: pqm at pqm.ubuntu.com-20110518033943-sgm50fqtljmq8ixc
parent: pqm at pqm.ubuntu.com-20110518024733-fktxni9qajxu2pwh
parent: jelmer at samba.org-20110517215849-4j68572jtn60fgz5
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Wed 2011-05-18 03:39:43 +0000
message:
  (jelmer) Move VersionedFiles-specific implementation from InterRepository to
   InterVersionedFileRepository. (Jelmer Vernooij)
modified:
  bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
  bzrlib/tests/per_interbranch/test_push.py test_push.py-20090330192649-pca31sb2ubbtcs15-1
  bzrlib/vf_repository.py        vf_repository.py-20110502151858-yh9nnoxpokg86unk-1
=== modified file 'bzrlib/repository.py'
--- a/bzrlib/repository.py	2011-05-14 21:16:04 +0000
+++ b/bzrlib/repository.py	2011-05-15 17:58:19 +0000
@@ -1676,7 +1676,6 @@
     InterRepository.get(other).method_name(parameters).
     """
 
-    _walk_to_common_revisions_batch_size = 50
     _optimisers = []
     """The available optimised InterRepository types."""
 
@@ -1707,74 +1706,7 @@
                             content is copied.
         :return: None.
         """
-        ui.ui_factory.warn_experimental_format_fetch(self)
-        from bzrlib.fetch import RepoFetcher
-        # See <https://launchpad.net/bugs/456077> asking for a warning here
-        if self.source._format.network_name() != self.target._format.network_name():
-            ui.ui_factory.show_user_warning('cross_format_fetch',
-                from_format=self.source._format,
-                to_format=self.target._format)
-        f = RepoFetcher(to_repository=self.target,
-                               from_repository=self.source,
-                               last_revision=revision_id,
-                               fetch_spec=fetch_spec,
-                               find_ghosts=find_ghosts)
-
-    def _walk_to_common_revisions(self, revision_ids, if_present_ids=None):
-        """Walk out from revision_ids in source to revisions target has.
-
-        :param revision_ids: The start point for the search.
-        :return: A set of revision ids.
-        """
-        target_graph = self.target.get_graph()
-        revision_ids = frozenset(revision_ids)
-        if if_present_ids:
-            all_wanted_revs = revision_ids.union(if_present_ids)
-        else:
-            all_wanted_revs = revision_ids
-        missing_revs = set()
-        source_graph = self.source.get_graph()
-        # ensure we don't pay silly lookup costs.
-        searcher = source_graph._make_breadth_first_searcher(all_wanted_revs)
-        null_set = frozenset([_mod_revision.NULL_REVISION])
-        searcher_exhausted = False
-        while True:
-            next_revs = set()
-            ghosts = set()
-            # Iterate the searcher until we have enough next_revs
-            while len(next_revs) < self._walk_to_common_revisions_batch_size:
-                try:
-                    next_revs_part, ghosts_part = searcher.next_with_ghosts()
-                    next_revs.update(next_revs_part)
-                    ghosts.update(ghosts_part)
-                except StopIteration:
-                    searcher_exhausted = True
-                    break
-            # If there are ghosts in the source graph, and the caller asked for
-            # them, make sure that they are present in the target.
-            # We don't care about other ghosts as we can't fetch them and
-            # haven't been asked to.
-            ghosts_to_check = set(revision_ids.intersection(ghosts))
-            revs_to_get = set(next_revs).union(ghosts_to_check)
-            if revs_to_get:
-                have_revs = set(target_graph.get_parent_map(revs_to_get))
-                # we always have NULL_REVISION present.
-                have_revs = have_revs.union(null_set)
-                # Check if the target is missing any ghosts we need.
-                ghosts_to_check.difference_update(have_revs)
-                if ghosts_to_check:
-                    # One of the caller's revision_ids is a ghost in both the
-                    # source and the target.
-                    raise errors.NoSuchRevision(
-                        self.source, ghosts_to_check.pop())
-                missing_revs.update(next_revs - have_revs)
-                # Because we may have walked past the original stop point, make
-                # sure everything is stopped
-                stop_revs = searcher.find_seen_ancestors(have_revs)
-                searcher.stop_searching_any(stop_revs)
-            if searcher_exhausted:
-                break
-        return searcher.get_result()
+        raise NotImplementedError(self.fetch)
 
     @needs_read_lock
     def search_missing_revision_ids(self,
@@ -1795,60 +1727,7 @@
             rather than just finding the surface difference.
         :return: A bzrlib.graph.SearchResult.
         """
-        if symbol_versioning.deprecated_passed(revision_id):
-            symbol_versioning.warn(
-                'search_missing_revision_ids(revision_id=...) was '
-                'deprecated in 2.4.  Use revision_ids=[...] instead.',
-                DeprecationWarning, stacklevel=2)
-            if revision_ids is not None:
-                raise AssertionError(
-                    'revision_ids is mutually exclusive with revision_id')
-            if revision_id is not None:
-                revision_ids = [revision_id]
-        del revision_id
-        # stop searching at found target revisions.
-        if not find_ghosts and (revision_ids is not None or if_present_ids is
-                not None):
-            return self._walk_to_common_revisions(revision_ids,
-                    if_present_ids=if_present_ids)
-        # generic, possibly worst case, slow code path.
-        target_ids = set(self.target.all_revision_ids())
-        source_ids = self._present_source_revisions_for(
-            revision_ids, if_present_ids)
-        result_set = set(source_ids).difference(target_ids)
-        return self.source.revision_ids_to_search_result(result_set)
-
-    def _present_source_revisions_for(self, revision_ids, if_present_ids=None):
-        """Returns set of all revisions in ancestry of revision_ids present in
-        the source repo.
-
-        :param revision_ids: if None, all revisions in source are returned.
-        :param if_present_ids: like revision_ids, but if any/all of these are
-            absent no error is raised.
-        """
-        if revision_ids is not None or if_present_ids is not None:
-            # First, ensure all specified revisions exist.  Callers expect
-            # NoSuchRevision when they pass absent revision_ids here.
-            if revision_ids is None:
-                revision_ids = set()
-            if if_present_ids is None:
-                if_present_ids = set()
-            revision_ids = set(revision_ids)
-            if_present_ids = set(if_present_ids)
-            all_wanted_ids = revision_ids.union(if_present_ids)
-            graph = self.source.get_graph()
-            present_revs = set(graph.get_parent_map(all_wanted_ids))
-            missing = revision_ids.difference(present_revs)
-            if missing:
-                raise errors.NoSuchRevision(self.source, missing.pop())
-            found_ids = all_wanted_ids.intersection(present_revs)
-            source_ids = [rev_id for (rev_id, parents) in
-                          graph.iter_ancestry(found_ids)
-                          if rev_id != _mod_revision.NULL_REVISION
-                          and parents is not None]
-        else:
-            source_ids = self.source.all_revision_ids()
-        return set(source_ids)
+        raise NotImplementedError(self.search_missing_revision_ids)
 
     @staticmethod
     def _same_model(source, target):
@@ -1874,18 +1753,6 @@
             raise errors.IncompatibleRepositories(source, target,
                 "different serializers")
 
-    @classmethod
-    def _get_repo_format_to_test(self):
-        return None
-
-    @classmethod
-    def is_compatible(cls, source, target):
-        # The default implementation is compatible with everything
-        return True
-
-
-InterRepository.register_optimiser(InterRepository)
-
 
 class CopyConverter(object):
     """A repository conversion tool which just performs a copy of the content.

=== modified file 'bzrlib/tests/per_interbranch/test_push.py'
--- a/bzrlib/tests/per_interbranch/test_push.py	2011-01-13 06:18:13 +0000
+++ b/bzrlib/tests/per_interbranch/test_push.py	2011-05-17 21:58:49 +0000
@@ -30,9 +30,9 @@
     check,
     errors,
     push,
-    repository,
     symbol_versioning,
     tests,
+    vf_repository,
     )
 from bzrlib.branch import Branch
 from bzrlib.bzrdir import BzrDir
@@ -287,7 +287,7 @@
     def disableOptimisticGetParentMap(self):
         # Tweak some class variables to stop remote get_parent_map calls asking
         # for or receiving more data than the caller asked for.
-        self.overrideAttr(repository.InterRepository,
+        self.overrideAttr(vf_repository.InterVersionedFileRepository,
                           '_walk_to_common_revisions_batch_size', 1)
         self.overrideAttr(SmartServerRepositoryGetParentMap,
                             'no_extra_results', True)

=== modified file 'bzrlib/vf_repository.py'
--- a/bzrlib/vf_repository.py	2011-05-14 23:42:30 +0000
+++ b/bzrlib/vf_repository.py	2011-05-15 17:58:19 +0000
@@ -32,6 +32,7 @@
     revision as _mod_revision,
     serializer as _mod_serializer,
     static_tuple,
+    symbol_versioning,
     tsort,
     ui,
     versionedfile,
@@ -2464,7 +2465,176 @@
         return wrong_parents, unused_keys
 
 
-class InterDifferingSerializer(InterRepository):
+class InterVersionedFileRepository(InterRepository):
+
+    _walk_to_common_revisions_batch_size = 50
+
+    @needs_write_lock
+    def fetch(self, revision_id=None, find_ghosts=False,
+            fetch_spec=None):
+        """Fetch the content required to construct revision_id.
+
+        The content is copied from self.source to self.target.
+
+        :param revision_id: if None all content is copied, if NULL_REVISION no
+                            content is copied.
+        :return: None.
+        """
+        ui.ui_factory.warn_experimental_format_fetch(self)
+        from bzrlib.fetch import RepoFetcher
+        # See <https://launchpad.net/bugs/456077> asking for a warning here
+        if self.source._format.network_name() != self.target._format.network_name():
+            ui.ui_factory.show_user_warning('cross_format_fetch',
+                from_format=self.source._format,
+                to_format=self.target._format)
+        f = RepoFetcher(to_repository=self.target,
+                               from_repository=self.source,
+                               last_revision=revision_id,
+                               fetch_spec=fetch_spec,
+                               find_ghosts=find_ghosts)
+
+    def _walk_to_common_revisions(self, revision_ids, if_present_ids=None):
+        """Walk out from revision_ids in source to revisions target has.
+
+        :param revision_ids: The start point for the search.
+        :return: A set of revision ids.
+        """
+        target_graph = self.target.get_graph()
+        revision_ids = frozenset(revision_ids)
+        if if_present_ids:
+            all_wanted_revs = revision_ids.union(if_present_ids)
+        else:
+            all_wanted_revs = revision_ids
+        missing_revs = set()
+        source_graph = self.source.get_graph()
+        # ensure we don't pay silly lookup costs.
+        searcher = source_graph._make_breadth_first_searcher(all_wanted_revs)
+        null_set = frozenset([_mod_revision.NULL_REVISION])
+        searcher_exhausted = False
+        while True:
+            next_revs = set()
+            ghosts = set()
+            # Iterate the searcher until we have enough next_revs
+            while len(next_revs) < self._walk_to_common_revisions_batch_size:
+                try:
+                    next_revs_part, ghosts_part = searcher.next_with_ghosts()
+                    next_revs.update(next_revs_part)
+                    ghosts.update(ghosts_part)
+                except StopIteration:
+                    searcher_exhausted = True
+                    break
+            # If there are ghosts in the source graph, and the caller asked for
+            # them, make sure that they are present in the target.
+            # We don't care about other ghosts as we can't fetch them and
+            # haven't been asked to.
+            ghosts_to_check = set(revision_ids.intersection(ghosts))
+            revs_to_get = set(next_revs).union(ghosts_to_check)
+            if revs_to_get:
+                have_revs = set(target_graph.get_parent_map(revs_to_get))
+                # we always have NULL_REVISION present.
+                have_revs = have_revs.union(null_set)
+                # Check if the target is missing any ghosts we need.
+                ghosts_to_check.difference_update(have_revs)
+                if ghosts_to_check:
+                    # One of the caller's revision_ids is a ghost in both the
+                    # source and the target.
+                    raise errors.NoSuchRevision(
+                        self.source, ghosts_to_check.pop())
+                missing_revs.update(next_revs - have_revs)
+                # Because we may have walked past the original stop point, make
+                # sure everything is stopped
+                stop_revs = searcher.find_seen_ancestors(have_revs)
+                searcher.stop_searching_any(stop_revs)
+            if searcher_exhausted:
+                break
+        return searcher.get_result()
+
+    @needs_read_lock
+    def search_missing_revision_ids(self,
+            revision_id=symbol_versioning.DEPRECATED_PARAMETER,
+            find_ghosts=True, revision_ids=None, if_present_ids=None):
+        """Return the revision ids that source has that target does not.
+
+        :param revision_id: only return revision ids included by this
+            revision_id.
+        :param revision_ids: return revision ids included by these
+            revision_ids.  NoSuchRevision will be raised if any of these
+            revisions are not present.
+        :param if_present_ids: like revision_ids, but will not cause
+            NoSuchRevision if any of these are absent, instead they will simply
+            not be in the result.  This is useful for e.g. finding revisions
+            to fetch for tags, which may reference absent revisions.
+        :param find_ghosts: If True find missing revisions in deep history
+            rather than just finding the surface difference.
+        :return: A bzrlib.graph.SearchResult.
+        """
+        if symbol_versioning.deprecated_passed(revision_id):
+            symbol_versioning.warn(
+                'search_missing_revision_ids(revision_id=...) was '
+                'deprecated in 2.4.  Use revision_ids=[...] instead.',
+                DeprecationWarning, stacklevel=2)
+            if revision_ids is not None:
+                raise AssertionError(
+                    'revision_ids is mutually exclusive with revision_id')
+            if revision_id is not None:
+                revision_ids = [revision_id]
+        del revision_id
+        # stop searching at found target revisions.
+        if not find_ghosts and (revision_ids is not None or if_present_ids is
+                not None):
+            return self._walk_to_common_revisions(revision_ids,
+                    if_present_ids=if_present_ids)
+        # generic, possibly worst case, slow code path.
+        target_ids = set(self.target.all_revision_ids())
+        source_ids = self._present_source_revisions_for(
+            revision_ids, if_present_ids)
+        result_set = set(source_ids).difference(target_ids)
+        return self.source.revision_ids_to_search_result(result_set)
+
+    def _present_source_revisions_for(self, revision_ids, if_present_ids=None):
+        """Returns set of all revisions in ancestry of revision_ids present in
+        the source repo.
+
+        :param revision_ids: if None, all revisions in source are returned.
+        :param if_present_ids: like revision_ids, but if any/all of these are
+            absent no error is raised.
+        """
+        if revision_ids is not None or if_present_ids is not None:
+            # First, ensure all specified revisions exist.  Callers expect
+            # NoSuchRevision when they pass absent revision_ids here.
+            if revision_ids is None:
+                revision_ids = set()
+            if if_present_ids is None:
+                if_present_ids = set()
+            revision_ids = set(revision_ids)
+            if_present_ids = set(if_present_ids)
+            all_wanted_ids = revision_ids.union(if_present_ids)
+            graph = self.source.get_graph()
+            present_revs = set(graph.get_parent_map(all_wanted_ids))
+            missing = revision_ids.difference(present_revs)
+            if missing:
+                raise errors.NoSuchRevision(self.source, missing.pop())
+            found_ids = all_wanted_ids.intersection(present_revs)
+            source_ids = [rev_id for (rev_id, parents) in
+                          graph.iter_ancestry(found_ids)
+                          if rev_id != _mod_revision.NULL_REVISION
+                          and parents is not None]
+        else:
+            source_ids = self.source.all_revision_ids()
+        return set(source_ids)
+
+    @classmethod
+    def _get_repo_format_to_test(self):
+        return None
+
+    @classmethod
+    def is_compatible(cls, source, target):
+        # The default implementation is compatible with everything
+        return (source._format.supports_full_versioned_files and
+                target._format.supports_full_versioned_files)
+
+
+class InterDifferingSerializer(InterVersionedFileRepository):
 
     @classmethod
     def _get_repo_format_to_test(self):
@@ -2806,7 +2976,7 @@
         return basis_id, basis_tree
 
 
-class InterSameDataRepository(InterRepository):
+class InterSameDataRepository(InterVersionedFileRepository):
     """Code for converting between repositories that represent the same data.
 
     Data format and model must match for this to work.
@@ -2830,6 +3000,7 @@
             target._format.supports_full_versioned_files)
 
 
+InterRepository.register_optimiser(InterVersionedFileRepository)
 InterRepository.register_optimiser(InterDifferingSerializer)
 InterRepository.register_optimiser(InterSameDataRepository)
 




More information about the bazaar-commits mailing list