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