Rev 3853: Branching from Remote no longer reads the full revision history. in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Tue Nov 25 19:18:15 GMT 2008


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

------------------------------------------------------------
revno: 3853
revision-id: pqm at pqm.ubuntu.com-20081125191811-pwwzoldg0s0wkze8
parent: pqm at pqm.ubuntu.com-20081125183146-g6pgo3yeyggtvh9s
parent: john at arbash-meinel.com-20081125173102-n04on0gpnqogdfm8
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Tue 2008-11-25 19:18:11 +0000
message:
  Branching from Remote no longer reads the full revision history.
  	(Andrew Bennetts, jam)
modified:
  NEWS                           NEWS-20050323055033-4e00b5db738777ff
  bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
  bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
    ------------------------------------------------------------
    revno: 3834.3.3
    revision-id: john at arbash-meinel.com-20081125173102-n04on0gpnqogdfm8
    parent: andrew.bennetts at canonical.com-20081114055531-5wtu6kx89ilt02yj
    parent: pqm at pqm.ubuntu.com-20081125152232-c22rycit2dfzm11f
    committer: John Arbash Meinel <john at arbash-meinel.com>
    branch nick: remote_revision_history
    timestamp: Tue 2008-11-25 11:31:02 -0600
    message:
      Merge bzr.dev, resolve conflict in tests.
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/__init__.py             __init__.py-20050309040759-33e65acf91bbcd5d
      bzrlib/_readdir_pyx.pyx        readdir.pyx-20060609152855-rm6v321vuaqyh9tu-1
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/builtins.py             builtins.py-20050830033751-fc01482b9ca23183
      bzrlib/commit.py               commit.py-20050511101309-79ec1a0168e0e825
      bzrlib/fetch.py                fetch.py-20050818234941-26fea6105696365d
      bzrlib/index.py                index.py-20070712131115-lolkarso50vjr64s-1
      bzrlib/knit.py                 knit.py-20051212171256-f056ac8f0fbe1bd9
      bzrlib/lockable_files.py       control_files.py-20051111201905-bb88546e799d669f
      bzrlib/option.py               option.py-20051014052914-661fb36e76e7362f
      bzrlib/plugin.py               plugin.py-20050622060424-829b654519533d69
      bzrlib/plugins/launchpad/account.py account.py-20071011033320-50y6vfftywf4yllw-1
      bzrlib/plugins/launchpad/lp_directory.py lp_indirect.py-20070126012204-de5rugwlt22c7u7e-1
      bzrlib/plugins/launchpad/test_account.py test_account.py-20071011033320-50y6vfftywf4yllw-2
      bzrlib/python-compat.h         pythoncompat.h-20080924041409-9kvi0fgtuuqp743j-1
      bzrlib/remote.py               remote.py-20060720103555-yeeg2x51vn0rbtdp-1
      bzrlib/repofmt/pack_repo.py    pack_repo.py-20070813041115-gjv5ma7ktfqwsjgn-1
      bzrlib/repofmt/weaverepo.py    presplitout.py-20070125045333-wfav3tsh73oxu3zk-1
      bzrlib/repository.py           rev_storage.py-20051111201905-119e9401e46257e3
      bzrlib/shelf_ui.py             shelver.py-20081005210102-33worgzwrtdw0yrm-1
      bzrlib/tests/__init__.py       selftest.py-20050531073622-8d0e3c8845c97a64
      bzrlib/tests/branch_implementations/test_stacking.py test_stacking.py-20080214020755-msjlkb7urobwly0f-1
      bzrlib/tests/interrepository_implementations/test_fetch.py test_fetch.py-20080425213627-j60cjh782ufm83ry-1
      bzrlib/tests/test_knit.py      test_knit.py-20051212171302-95d4c00dd5f11f2b
      bzrlib/tests/test_permissions.py test_permissions.py-20051215004520-ccf475789c80e80c
      bzrlib/tests/test_plugins.py   plugins.py-20050622075746-32002b55e5e943e9
      bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
      bzrlib/tests/test_repository.py test_repository.py-20060131075918-65c555b881612f4d
      bzrlib/tests/test_revision.py  testrevision.py-20050804210559-46f5e1eb67b01289
      bzrlib/tests/test_shelf_ui.py  test_shelf_ui.py-20081027155203-wtcuazg85wp9u4fv-1
      bzrlib/transport/remote.py     ssh.py-20060608202016-c25gvf1ob7ypbus6-1
      bzrlib/versionedfile.py        versionedfile.py-20060222045106-5039c71ee3b65490
      bzrlib/workingtree.py          workingtree.py-20050511021032-29b6ec0a681e02e3
      bzrlib/workingtree_4.py        workingtree_4.py-20070208044105-5fgpc5j3ljlh5q6c-1
    ------------------------------------------------------------
    revno: 3834.3.2
    revision-id: andrew.bennetts at canonical.com-20081114055531-5wtu6kx89ilt02yj
    parent: andrew.bennetts at canonical.com-20081113075102-lvpvgrjsavzwbg7a
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: rev-history
    timestamp: Fri 2008-11-14 15:55:31 +1000
    message:
      Preserve BzrBranch5's _synchronize_history code without affecting Branch or BzrBranch7; add effort test for RemoteBranch.copy_content_into.
    modified:
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
      bzrlib/tests/test_remote.py    test_remote.py-20060720103555-yeeg2x51vn0rbtdp-2
    ------------------------------------------------------------
    revno: 3834.3.1
    revision-id: andrew.bennetts at canonical.com-20081113075102-lvpvgrjsavzwbg7a
    parent: pqm at pqm.ubuntu.com-20081112073322-dpai0jsluo3cvpf2
    committer: Andrew Bennetts <andrew.bennetts at canonical.com>
    branch nick: rev-history
    timestamp: Thu 2008-11-13 17:51:02 +1000
    message:
      Get rid of revision_history() call during copy_content_into.
    modified:
      NEWS                           NEWS-20050323055033-4e00b5db738777ff
      bzrlib/branch.py               branch.py-20050309040759-e4baf4e0d046576e
=== modified file 'NEWS'
--- a/NEWS	2008-11-21 20:24:15 +0000
+++ b/NEWS	2008-11-25 17:31:02 +0000
@@ -20,6 +20,10 @@
 
   IMPROVEMENTS:
 
+    * ``(Remote)Branch.copy_content_into`` no longer generates the full revision
+      history just to set the last revision info.
+      (Andrew Bennetts, John Arbash Meinel)
+
     * When making a large readv() request over ``bzr+ssh``, break up the
       request into more manageable chunks. Because the RPC is not yet able
       to stream, this helps keep us from buffering too much information at

=== modified file 'bzrlib/branch.py'
--- a/bzrlib/branch.py	2008-11-15 22:12:26 +0000
+++ b/bzrlib/branch.py	2008-11-25 17:31:02 +0000
@@ -709,27 +709,31 @@
         """Synchronize last revision and revision history between branches.
 
         This version is most efficient when the destination is also a
-        BzrBranch5, but works for BzrBranch6 as long as the revision
-        history is the true lefthand parent history, and all of the revisions
-        are in the destination's repository.  If not, set_revision_history
-        will fail.
+        BzrBranch6, but works for BzrBranch5, as long as the destination's
+        repository contains all the lefthand ancestors of the intended
+        last_revision.  If not, set_last_revision_info will fail.
 
         :param destination: The branch to copy the history into
         :param revision_id: The revision-id to truncate history at.  May
           be None to copy complete history.
         """
-        if revision_id == _mod_revision.NULL_REVISION:
-            new_history = []
+        source_revno, source_revision_id = self.last_revision_info()
+        if revision_id is None:
+            revno, revision_id = source_revno, source_revision_id
+        elif source_revision_id == revision_id:
+            # we know the revno without needing to walk all of history
+            revno = source_revno
         else:
-            new_history = self.revision_history()
-        if revision_id is not None and new_history != []:
-            try:
-                new_history = new_history[:new_history.index(revision_id) + 1]
-            except ValueError:
-                rev = self.repository.get_revision(revision_id)
-                new_history = rev.get_history(self.repository)[1:]
-        destination.set_revision_history(new_history)
-
+            # To figure out the revno for a random revision, we need to build
+            # the revision history, and count its length.
+            # We don't care about the order, just how long it is.
+            # Alternatively, we could start at the current location, and count
+            # backwards. But there is no guarantee that we will find it since
+            # it may be a merged revision.
+            revno = len(list(self.repository.iter_reverse_revision_history(
+                                                                revision_id)))
+        destination.set_last_revision_info(revno, revision_id)
+    
     @needs_read_lock
     def copy_content_into(self, destination, revision_id=None):
         """Copy the content of self into destination.
@@ -1594,6 +1598,31 @@
         if Branch.hooks['post_change_branch_tip']:
             self._run_post_change_branch_tip_hooks(old_revno, old_revid)
 
+    def _synchronize_history(self, destination, revision_id):
+        """Synchronize last revision and revision history between branches.
+
+        This version is most efficient when the destination is also a
+        BzrBranch5, but works for BzrBranch6 as long as the revision
+        history is the true lefthand parent history, and all of the revisions
+        are in the destination's repository.  If not, set_revision_history
+        will fail.
+
+        :param destination: The branch to copy the history into
+        :param revision_id: The revision-id to truncate history at.  May
+          be None to copy complete history.
+        """
+        if revision_id == _mod_revision.NULL_REVISION:
+            new_history = []
+        else:
+            new_history = self.revision_history()
+        if revision_id is not None and new_history != []:
+            try:
+                new_history = new_history[:new_history.index(revision_id) + 1]
+            except ValueError:
+                rev = self.repository.get_revision(revision_id)
+                new_history = rev.get_history(self.repository)[1:]
+        destination.set_revision_history(new_history)
+
     def _run_pre_change_branch_tip_hooks(self, new_revno, new_revid):
         """Run the pre_change_branch_tip hooks."""
         hooks = Branch.hooks['pre_change_branch_tip']
@@ -2098,6 +2127,18 @@
         self._last_revision_info_cache = revno, revision_id
         self._run_post_change_branch_tip_hooks(old_revno, old_revid)
 
+    def _synchronize_history(self, destination, revision_id):
+        """Synchronize last revision and revision history between branches.
+        
+        :see: Branch._synchronize_history
+        """
+        # XXX: The base Branch has a fast implementation of this method based
+        # on set_last_revision_info, but BzrBranch/BzrBranch5 have a slower one
+        # that uses set_revision_history.  This class inherits from BzrBranch5,
+        # but wants the fast implementation, so it calls
+        # Branch._synchronize_history directly.
+        Branch._synchronize_history(self, destination, revision_id)
+
     def _check_history_violation(self, revision_id):
         last_revision = _mod_revision.ensure_null(self.last_revision())
         if _mod_revision.is_null(last_revision):
@@ -2252,35 +2293,6 @@
         value = self.get_config().get_user_option('append_revisions_only')
         return value == 'True'
 
-    def _synchronize_history(self, destination, revision_id):
-        """Synchronize last revision and revision history between branches.
-
-        This version is most efficient when the destination is also a
-        BzrBranch6, but works for BzrBranch5, as long as the destination's
-        repository contains all the lefthand ancestors of the intended
-        last_revision.  If not, set_last_revision_info will fail.
-
-        :param destination: The branch to copy the history into
-        :param revision_id: The revision-id to truncate history at.  May
-          be None to copy complete history.
-        """
-        source_revno, source_revision_id = self.last_revision_info()
-        if revision_id is None:
-            revno, revision_id = source_revno, source_revision_id
-        elif source_revision_id == revision_id:
-            # we know the revno without needing to walk all of history
-            revno = source_revno
-        else:
-            # To figure out the revno for a random revision, we need to build
-            # the revision history, and count its length.
-            # We don't care about the order, just how long it is.
-            # Alternatively, we could start at the current location, and count
-            # backwards. But there is no guarantee that we will find it since
-            # it may be a merged revision.
-            revno = len(list(self.repository.iter_reverse_revision_history(
-                                                                revision_id)))
-        destination.set_last_revision_info(revno, revision_id)
-
     def _make_tags(self):
         return BasicTags(self)
 

=== modified file 'bzrlib/tests/test_remote.py'
--- a/bzrlib/tests/test_remote.py	2008-11-20 06:17:07 +0000
+++ b/bzrlib/tests/test_remote.py	2008-11-25 17:31:02 +0000
@@ -27,6 +27,7 @@
 from cStringIO import StringIO
 
 from bzrlib import (
+    bzrdir,
     config,
     errors,
     graph,
@@ -1787,3 +1788,32 @@
         branch = self.prepare_stacked_remote_branch()
         repo = branch.repository
         self.assertEqual([], repo._get_parent_map(['rev1']).keys())
+
+
+class TestRemoteBranchEffort(tests.TestCaseWithTransport):
+
+    def setUp(self):
+        super(TestRemoteBranchEffort, self).setUp()
+        # Create a smart server that publishes whatever the backing VFS server
+        # does.
+        self.smart_server = server.SmartTCPServer_for_testing()
+        self.smart_server.setUp(self.get_server())
+        self.addCleanup(self.smart_server.tearDown)
+        # Log all HPSS calls into self.hpss_calls.
+        _SmartClient.hooks.install_named_hook(
+            'call', self.capture_hpss_call, None)
+        self.hpss_calls = []
+
+    def capture_hpss_call(self, params):
+        self.hpss_calls.append(params.method)
+
+    def test_copy_content_into_avoids_revision_history(self):
+        local = self.make_branch('local')
+        remote_backing_tree = self.make_branch_and_tree('remote')
+        remote_backing_tree.commit("Commit.")
+        remote_branch_url = self.smart_server.get_url() + 'remote'
+        remote_branch = bzrdir.BzrDir.open(remote_branch_url).open_branch()
+        local.repository.fetch(remote_branch.repository)
+        self.hpss_calls = []
+        remote_branch.copy_content_into(local)
+        self.assertFalse('Branch.revision_history' in self.hpss_calls)




More information about the bazaar-commits mailing list