Rev 2749: Merge find_previous_heads deprecation. in http://people.ubuntu.com/~robertc/baz2.0/repository
Robert Collins
robertc at robertcollins.net
Mon Sep 3 04:27:26 BST 2007
At http://people.ubuntu.com/~robertc/baz2.0/repository
------------------------------------------------------------
revno: 2749
revision-id: robertc at robertcollins.net-20070903032716-agc2gd18ogf35i3f
parent: robertc at robertcollins.net-20070903031314-2l09xjk51p9f3w63
parent: robertc at robertcollins.net-20070903015712-oo8vn04vryo75xjb
committer: Robert Collins <robertc at robertcollins.net>
branch nick: repository
timestamp: Mon 2007-09-03 13:27:16 +1000
message:
Merge find_previous_heads deprecation.
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/graph.py graph_walker.py-20070525030359-y852guab65d4wtn0-1
bzrlib/inventory.py inventory.py-20050309040759-6648b84ca2005b37
bzrlib/repository.py rev_storage.py-20051111201905-119e9401e46257e3
bzrlib/tests/tree_implementations/test_inv.py test_inv.py-20070312023226-0cdvk5uwhutis9vg-1
------------------------------------------------------------
revno: 2592.1.25.2.7.1.28.1.6.1.3.1.9.2.1.3.74.1.31.1.1
revision-id: robertc at robertcollins.net-20070903015712-oo8vn04vryo75xjb
parent: pqm at pqm.ubuntu.com-20070901160444-hcr66zejwyy0jezc
committer: Robert Collins <robertc at robertcollins.net>
branch nick: commit
timestamp: Mon 2007-09-03 11:57:12 +1000
message:
* Deprecated method ``find_previous_heads`` on
``bzrlib.inventory.InventoryEntry``. This has been superceded by the use
of ``parent_candidates`` and a separate heads check via the repository
API. (Robert Collins)
* New public method ``heads`` on the ``bzrlib.graph.Graph`` class. This is
a simple rename of a previously internal method which implements the same
semantics as heads(). (Robert Collins, John A Meinel)
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/graph.py graph_walker.py-20070525030359-y852guab65d4wtn0-1
bzrlib/inventory.py inventory.py-20050309040759-6648b84ca2005b37
bzrlib/repository.py rev_storage.py-20051111201905-119e9401e46257e3
bzrlib/tests/tree_implementations/test_inv.py test_inv.py-20070312023226-0cdvk5uwhutis9vg-1
=== modified file 'NEWS'
--- a/NEWS 2007-09-03 03:13:14 +0000
+++ b/NEWS 2007-09-03 03:27:16 +0000
@@ -156,6 +156,11 @@
This is done in order to mix the commit messages (which is a unicode
string), and the diff which is a raw string. (Goffredo Baroncelli)
+ * Deprecated method ``find_previous_heads`` on
+ ``bzrlib.inventory.InventoryEntry``. This has been superceded by the use
+ of ``parent_candidates`` and a separate heads check via the repository
+ API. (Robert Collins)
+
* New trace function ``mutter_callsite`` will print out a subset of the
stack to the log, which can be useful for gathering debug details.
(Robert Collins)
@@ -185,6 +190,10 @@
efficiently streaming the knit data for a set of versions over the smart
protocol.
+ * New public method ``heads`` on the ``bzrlib.graph.Graph`` class. This is
+ a simple rename of a previously internal method which implements the same
+ semantics as heads(). (Robert Collins, John A Meinel)
+
TESTING:
* Use UTF-8 encoded StringIO for log tests to avoid failures on
=== modified file 'bzrlib/graph.py'
--- a/bzrlib/graph.py 2007-08-07 15:26:26 +0000
+++ b/bzrlib/graph.py 2007-09-03 01:57:12 +0000
@@ -134,7 +134,10 @@
ancestor of all border ancestors.
"""
border_common, common, sides = self._find_border_ancestors(revisions)
- return self._filter_candidate_lca(border_common)
+ # We may have common ancestors that can be reached from each other.
+ # - ask for the heads of them to filter it down to only ones that
+ # cannot be reached from each other - phase 2.
+ return self.heads(border_common)
def find_difference(self, left_revision, right_revision):
"""Determine the graph difference between two revisions"""
@@ -212,21 +215,20 @@
for searcher in searchers:
update_common(searcher, revision)
- def _filter_candidate_lca(self, candidate_lca):
- """Remove candidates which are ancestors of other candidates.
-
- This is done by searching the ancestries of each border ancestor. It
- is perfomed on the principle that a border ancestor that is not an
- ancestor of any other border ancestor is a lowest common ancestor.
-
- Searches are stopped when they find a node that is determined to be a
- common ancestor of all border ancestors, because this shows that it
- cannot be a descendant of any border ancestor.
-
- This will scale with the number of candidate ancestors and the length
- of the shortest path from a candidate to an ancestor common to all
- candidates.
+ def heads(self, keys):
+ """Return the heads from amongst keys.
+
+ This is done by searching the ancestries of each key. Any key that is
+ reachable from another key is not returned; all the others are.
+
+ This operation scales with the relative depth between any two keys. If
+ any two keys are completely disconnected all ancestry of both sides
+ will be retrieved.
+
+ :param keys: An iterable of keys.
+ :return: A set of the heads.
"""
+ candidate_lca = set(keys)
searchers = dict((c, self._make_breadth_first_searcher([c]))
for c in candidate_lca)
active_searchers = dict(searchers)
=== modified file 'bzrlib/inventory.py'
--- a/bzrlib/inventory.py 2007-08-31 05:54:21 +0000
+++ b/bzrlib/inventory.py 2007-09-03 01:57:12 +0000
@@ -50,6 +50,7 @@
BzrCheckError,
BzrError,
)
+from bzrlib.symbol_versioning import deprecated_method, zero_ninetyone
from bzrlib.trace import mutter
@@ -161,33 +162,19 @@
def _diff(self, text_diff, from_label, tree, to_label, to_entry, to_tree,
output_to, reverse=False):
"""Perform a diff between two entries of the same kind."""
-
- def find_previous_heads(self, previous_inventories,
- versioned_file_store,
- transaction,
- entry_vf=None):
- """Return the revisions and entries that directly precede this.
-
- Returned as a map from revision to inventory entry.
-
- This is a map containing the file revisions in all parents
- for which the file exists, and its revision is not a parent of
- any other. If the file is new, the set will be empty.
-
- :param versioned_file_store: A store where ancestry data on this
- file id can be queried.
- :param transaction: The transaction that queries to the versioned
- file store should be completed under.
- :param entry_vf: The entry versioned file, if its already available.
+
+ def parent_candidates(self, previous_inventories):
+ """Find possible per-file graph parents.
+
+ This is currently defined by:
+ - The kind has not changed (* not sure why this is a clause *)
+ - Select the last changed revision in the parent inventory.
+ - Do deal with a short lived bug in bzr 0.8's development two entries
+ that have the same last changed but different 'x' bit settings are
+ changed in-place.
"""
- def get_ancestors(weave, entry):
- return set(weave.get_ancestry(entry.revision, topo_sorted=False))
# revision:ie mapping for each ie found in previous_inventories.
candidates = {}
- # revision:ie mapping with one revision for each head.
- heads = {}
- # revision: ancestor list for each head
- head_ancestors = {}
# identify candidate head revision ids.
for inv in previous_inventories:
if self.file_id in inv:
@@ -212,19 +199,52 @@
else:
# add this revision as a candidate.
candidates[ie.revision] = ie
-
+ return candidates
+
+ @deprecated_method(zero_ninetyone)
+ def find_previous_heads(self, previous_inventories,
+ versioned_file_store,
+ transaction,
+ entry_vf=None):
+ """Return the revisions and entries that directly precede this.
+
+ Returned as a map from revision to inventory entry.
+
+ This is a map containing the file revisions in all parents
+ for which the file exists, and its revision is not a parent of
+ any other. If the file is new, the set will be empty.
+
+ :param versioned_file_store: A store where ancestry data on this
+ file id can be queried.
+ :param transaction: The transaction that queries to the versioned
+ file store should be completed under.
+ :param entry_vf: The entry versioned file, if its already available.
+ """
+ candidates = self.parent_candidates(previous_inventories)
+
+ # revision:ie mapping with one revision for each head.
+ heads = {}
# common case optimisation
if len(candidates) == 1:
# if there is only one candidate revision found
- # then we can opening the versioned file to access ancestry:
+ # then we can avoid opening the versioned file to access ancestry:
# there cannot be any ancestors to eliminate when there is
# only one revision available.
- heads[ie.revision] = ie
- return heads
+ return candidates
+
+ # --- what follows is now encapsulated in repository.get_graph.heads(),
+ # but that is not accessible from here as we have no repository
+ # pointer. Note that the repository.get_graph.heads() call can return
+ # different results *at the moment* because of the kind-changing check
+ # we have in parent_candidates().
# eliminate ancestors amongst the available candidates:
# heads are those that are not an ancestor of any other candidate
# - this provides convergence at a per-file level.
+ def get_ancestors(weave, entry):
+ return set(weave.get_ancestry(entry.revision, topo_sorted=False))
+ # revision: ancestor list for each head
+ head_ancestors = {}
for ie in candidates.values():
# may be an ancestor of a known head:
already_present = 0 != len(
=== modified file 'bzrlib/repository.py'
--- a/bzrlib/repository.py 2007-09-03 03:13:14 +0000
+++ b/bzrlib/repository.py 2007-09-03 03:27:16 +0000
@@ -2372,44 +2372,57 @@
if self._new_revision_id is None:
self._new_revision_id = self._gen_revision_id()
- def record_entry_contents(self, ie, parent_invs, path, tree):
- """Record the content of ie from tree into the commit if needed.
-
- Side effect: sets ie.revision when unchanged
-
- :param ie: An inventory entry present in the commit.
+ def _check_root(self, ie, parent_invs, tree):
+ """Helper for record_entry_contents.
+
+ :param ie: An entry being added.
:param parent_invs: The inventories of the parent revisions of the
commit.
- :param path: The path the entry is at in the tree.
- :param tree: The tree which contains this entry and should be used to
- obtain content.
+ :param tree: The tree that is being committed.
"""
- if self.new_inventory.root is None and ie.parent_id is not None:
+ if ie.parent_id is not None:
+ # if ie is not root, add a root automatically.
symbol_versioning.warn('Root entry should be supplied to'
' record_entry_contents, as of bzr 0.10.',
DeprecationWarning, stacklevel=2)
self.record_entry_contents(tree.inventory.root.copy(), parent_invs,
'', tree)
- self.new_inventory.add(ie)
-
- # ie.revision is always None if the InventoryEntry is considered
- # for committing. ie.snapshot will record the correct revision
- # which may be the sole parent if it is untouched.
- if ie.revision is not None:
- return
-
- # In this revision format, root entries have no knit or weave
- if ie is self.new_inventory.root:
- # When serializing out to disk and back in
- # root.revision is always _new_revision_id
+ else:
+ # In this revision format, root entries have no knit or weave When
+ # serializing out to disk and back in root.revision is always
+ # _new_revision_id
ie.revision = self._new_revision_id
+
+ def record_entry_contents(self, ie, parent_invs, path, tree):
+ """Record the content of ie from tree into the commit if needed.
+
+ Side effect: sets ie.revision when unchanged
+
+ :param ie: An inventory entry present in the commit.
+ :param parent_invs: The inventories of the parent revisions of the
+ commit.
+ :param path: The path the entry is at in the tree.
+ :param tree: The tree which contains this entry and should be used to
+ obtain content.
+ """
+ if self.new_inventory.root is None:
+ self._check_root(ie, parent_invs, tree)
+ self.new_inventory.add(ie)
+
+ # ie.revision is always None if the InventoryEntry is considered
+ # for committing. ie.snapshot will record the correct revision
+ # which may be the sole parent if it is untouched.
+ if ie.revision is not None:
return
- previous_entries = ie.find_previous_heads(
- parent_invs,
- self.repository.weave_store,
- self.repository.get_transaction())
- # we are creating a new revision for ie in the history store
- # and inventory.
+
+ parent_candiate_entries = ie.parent_candidates(parent_invs)
+ heads = self.repository.get_graph().heads(parent_candiate_entries.keys())
+ # XXX: Note that this is unordered - and this is tolerable because
+ # the previous code was also unordered.
+ previous_entries = dict((head, parent_candiate_entries[head]) for head
+ in heads)
+ # we are creating a new revision for ie in the history store and
+ # inventory.
ie.snapshot(self._new_revision_id, path, previous_entries, tree, self)
def modified_directory(self, file_id, file_parents):
@@ -2490,34 +2503,16 @@
record_root_entry = True
- def record_entry_contents(self, ie, parent_invs, path, tree):
- """Record the content of ie from tree into the commit if needed.
-
- Side effect: sets ie.revision when unchanged
-
- :param ie: An inventory entry present in the commit.
+ def _check_root(self, ie, parent_invs, tree):
+ """Helper for record_entry_contents.
+
+ :param ie: An entry being added.
:param parent_invs: The inventories of the parent revisions of the
commit.
- :param path: The path the entry is at in the tree.
- :param tree: The tree which contains this entry and should be used to
- obtain content.
+ :param tree: The tree that is being committed.
"""
- assert self.new_inventory.root is not None or ie.parent_id is None
- self.new_inventory.add(ie)
-
- # ie.revision is always None if the InventoryEntry is considered
- # for committing. ie.snapshot will record the correct revision
- # which may be the sole parent if it is untouched.
- if ie.revision is not None:
- return
-
- previous_entries = ie.find_previous_heads(
- parent_invs,
- self.repository.weave_store,
- self.repository.get_transaction())
- # we are creating a new revision for ie in the history store
- # and inventory.
- ie.snapshot(self._new_revision_id, path, previous_entries, tree, self)
+ # ie must be root for this builder
+ assert ie.parent_id is None
_unescape_map = {
=== modified file 'bzrlib/tests/tree_implementations/test_inv.py'
--- a/bzrlib/tests/tree_implementations/test_inv.py 2007-04-14 11:55:51 +0000
+++ b/bzrlib/tests/tree_implementations/test_inv.py 2007-09-03 01:57:12 +0000
@@ -25,6 +25,7 @@
from bzrlib.osutils import (
has_symlinks,
)
+from bzrlib.symbol_versioning import zero_ninetyone
from bzrlib.tests import TestSkipped
from bzrlib.tests.tree_implementations import TestCaseWithTree
from bzrlib.uncommit import uncommit
@@ -177,8 +178,9 @@
self.branch.repository.get_transaction())
def get_previous_heads(self, inventories):
- return self.file_active.find_previous_heads(
- inventories,
+ return self.applyDeprecated(zero_ninetyone,
+ self.file_active.find_previous_heads,
+ inventories,
self.branch.repository.weave_store,
self.branch.repository.get_transaction())
More information about the bazaar-commits
mailing list