Rev 3450: allow passing a 'graph' object into Branch.update_revisions. in http://bzr.arbash-meinel.com/branches/bzr/1.6-dev/graph_find_distance_to_null
John Arbash Meinel
john at arbash-meinel.com
Thu May 22 23:57:05 BST 2008
At http://bzr.arbash-meinel.com/branches/bzr/1.6-dev/graph_find_distance_to_null
------------------------------------------------------------
revno: 3450
revision-id: john at arbash-meinel.com-20080522225634-bl5qfq1caf119hr2
parent: john at arbash-meinel.com-20080522220257-z3cnrx690d6ue4oz
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: graph_find_distance_to_null
timestamp: Thu 2008-05-22 17:56:34 -0500
message:
allow passing a 'graph' object into Branch.update_revisions.
modified:
NEWS NEWS-20050323055033-4e00b5db738777ff
bzrlib/branch.py branch.py-20050309040759-e4baf4e0d046576e
bzrlib/remote.py remote.py-20060720103555-yeeg2x51vn0rbtdp-1
bzrlib/tests/branch_implementations/test_update.py test_update.py-20060305010612-e68efbcbb1baa69f
-------------- next part --------------
=== modified file 'NEWS'
--- a/NEWS 2008-05-21 10:41:34 +0000
+++ b/NEWS 2008-05-22 22:56:34 +0000
@@ -38,6 +38,11 @@
``Graph.find_differences`` to determine missing revisions without having
to search the whole ancestry. (John Arbash Meinel, #174625)
+ * ``bzr branch/push/pull -r XXX`` now have a helper function for finding
+ the revno of the new revision (``Graph.find_distance_to_null``). This
+ should make something like ``bzr branch -r -100`` in a shared, no-trees
+ repository much snappier. (John Arbash Meinel)
+
BUGFIXES:
* Correctly track the base URL of a smart medium when using bzr+http://
@@ -80,6 +85,11 @@
API CHANGES:
+ * ``Branch.update_revisions`` now takes an optional ``Graph``
+ object. This can be used by ``update_revisions`` when it is
+ checking ancestry, and allows callers to prefer request to go to a
+ local branch. (John Arbash Meinel)
+
* ``bzr missing --mine-only`` will return status code 0 if you have no
new revisions, but the remote does. Similarly for ``--theirs-only``.
The new code only checks one side, so it doesn't know if the other
=== modified file 'bzrlib/branch.py'
--- a/bzrlib/branch.py 2008-05-08 04:33:38 +0000
+++ b/bzrlib/branch.py 2008-05-22 22:56:34 +0000
@@ -1500,16 +1500,20 @@
last_rev, other_branch))
@needs_write_lock
- def update_revisions(self, other, stop_revision=None, overwrite=False):
+ def update_revisions(self, other, stop_revision=None, overwrite=False,
+ graph=None):
"""See Branch.update_revisions."""
other.lock_read()
try:
- other_last_revno, other_last_revision = other.last_revision_info()
+ other_revno, other_last_revision = other.last_revision_info()
+ stop_revno = None # unknown
if stop_revision is None:
stop_revision = other_last_revision
if _mod_revision.is_null(stop_revision):
# if there are no commits, we're done.
return
+ stop_revno = other_revno
+
# whats the current last revision, before we fetch [and change it
# possibly]
last_rev = _mod_revision.ensure_null(self.last_revision())
@@ -1520,8 +1524,9 @@
self.fetch(other, stop_revision)
# Check to see if one is an ancestor of the other
if not overwrite:
- heads = self.repository.get_graph().heads([stop_revision,
- last_rev])
+ if graph is None:
+ graph = self.repository.get_graph()
+ heads = graph.heads([stop_revision, last_rev])
if heads == set([last_rev]):
# The current revision is a decendent of the target,
# nothing to do
@@ -1531,17 +1536,14 @@
raise errors.DivergedBranches(self, other)
elif heads != set([stop_revision]):
raise AssertionError("invalid heads: %r" % heads)
- if other_last_revision == stop_revision:
- self.set_last_revision_info(other_last_revno,
- other_last_revision)
- else:
- # TODO: jam 2007-11-29 Is there a way to determine the
- # revno without searching all of history??
- if overwrite:
- self.generate_revision_history(stop_revision)
- else:
- self.generate_revision_history(stop_revision,
- last_rev=last_rev, other_branch=other)
+ if stop_revno is None:
+ if graph is None:
+ graph = self.repository.get_graph()
+ this_revno, this_last_revision = self.last_revision_info()
+ stop_revno = graph.find_distance_to_null(stop_revision,
+ [(other_last_revision, other_revno),
+ (this_last_revision, this_revno)])
+ self.set_last_revision_info(stop_revno, stop_revision)
finally:
other.unlock()
=== modified file 'bzrlib/remote.py'
--- a/bzrlib/remote.py 2008-05-20 07:16:50 +0000
+++ b/bzrlib/remote.py 2008-05-22 22:56:34 +0000
@@ -44,6 +44,7 @@
from bzrlib.revision import ensure_null, NULL_REVISION
from bzrlib.trace import mutter, note, warning
+
# Note: RemoteBzrDirFormat is in bzrdir.py
class RemoteBzrDir(BzrDir):
@@ -1553,10 +1554,11 @@
self._ensure_real()
return self._real_branch.set_push_location(location)
- def update_revisions(self, other, stop_revision=None, overwrite=False):
+ def update_revisions(self, other, stop_revision=None, overwrite=False, graph=None):
self._ensure_real()
return self._real_branch.update_revisions(
- other, stop_revision=stop_revision, overwrite=overwrite)
+ other, stop_revision=stop_revision, overwrite=overwrite,
+ graph=graph)
def _extract_tar(tar, to_dir):
=== modified file 'bzrlib/tests/branch_implementations/test_update.py'
--- a/bzrlib/tests/branch_implementations/test_update.py 2007-07-11 19:44:51 +0000
+++ b/bzrlib/tests/branch_implementations/test_update.py 2008-05-22 22:56:34 +0000
@@ -67,3 +67,51 @@
master_tree.commit('bar', rev_id='bar', allow_pointless=True)
self.assertEqual('foo', child_tree.branch.update())
self.assertEqual(['bar'], child_tree.branch.revision_history())
+
+
+class TestUpdateRevisions(TestCaseWithBranch):
+
+ def test_accepts_graph(self):
+ # An implementation may not use it, but it should allow a 'graph' to be
+ # supplied
+ tree1 = self.make_branch_and_tree('tree1')
+ rev1 = tree1.commit('one')
+ tree2 = tree1.bzrdir.sprout('tree2').open_workingtree()
+ rev2 = tree2.commit('two')
+
+ tree1.lock_write()
+ self.addCleanup(tree1.unlock)
+ tree2.lock_read()
+ self.addCleanup(tree2.unlock)
+ graph = tree2.branch.repository.get_graph(tree1.branch.repository)
+
+ tree1.branch.update_revisions(tree2.branch, graph=graph)
+ self.assertEqual((2, rev2), tree1.branch.last_revision_info())
+
+ def test_overwrite_ignores_diverged(self):
+ tree1 = self.make_branch_and_tree('tree1')
+ rev1 = tree1.commit('one')
+ tree2 = tree1.bzrdir.sprout('tree2').open_workingtree()
+ rev2 = tree1.commit('two')
+ rev2b = tree2.commit('alt two')
+
+ self.assertRaises(errors.DivergedBranches,
+ tree1.branch.update_revisions,
+ tree2.branch, overwrite=False)
+ # However, the revision should be copied into the repository
+ self.assertTrue(tree1.branch.repository.has_revision(rev2b))
+
+ tree1.branch.update_revisions(tree2.branch, overwrite=True)
+ self.assertEqual((2, rev2b), tree1.branch.last_revision_info())
+
+ def test_ignores_older(self):
+ tree1 = self.make_branch_and_tree('tree1')
+ rev1 = tree1.commit('one')
+ tree2 = tree1.bzrdir.sprout('tree2').open_workingtree()
+ rev2 = tree1.commit('two')
+
+ tree1.branch.update_revisions(tree2.branch)
+ self.assertEqual((2, rev2), tree1.branch.last_revision_info())
+
+ tree1.branch.update_revisions(tree2.branch, overwrite=True)
+ self.assertEqual((1, rev1), tree1.branch.last_revision_info())
More information about the bazaar-commits
mailing list