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