Rev 5786: (jameinel) Make 'bzr merge' much faster by not walking unchanged entries. in file:///home/pqm/archives/thelove/bzr/%2Btrunk/

Canonical.com Patch Queue Manager pqm at pqm.ubuntu.com
Fri Apr 15 08:12:47 UTC 2011


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

------------------------------------------------------------
revno: 5786 [merge]
revision-id: pqm at pqm.ubuntu.com-20110415081233-mqfd5six3sqmi1sn
parent: pqm at pqm.ubuntu.com-20110414122541-7taevmis2q3cjcur
parent: john at arbash-meinel.com-20110415070506-0h8qhb3vmttd264t
committer: Canonical.com Patch Queue Manager <pqm at pqm.ubuntu.com>
branch nick: +trunk
timestamp: Fri 2011-04-15 08:12:33 +0000
message:
  (jameinel) Make 'bzr merge' much faster by not walking unchanged entries.
   (John A Meinel)
modified:
  bzrlib/merge.py                merge.py-20050513021216-953b65a438527106
  bzrlib/tests/per_workingtree/test_merge_from_branch.py test_merge_from_bran-20060904034200-12jxyk2zlhpufxe1-1
  bzrlib/transform.py            transform.py-20060105172343-dd99e54394d91687
  doc/en/release-notes/bzr-2.4.txt bzr2.4.txt-20110114053217-k7ym9jfz243fddjm-1
=== modified file 'bzrlib/merge.py'
--- a/bzrlib/merge.py	2011-04-07 10:36:24 +0000
+++ b/bzrlib/merge.py	2011-04-13 14:47:11 +0000
@@ -911,7 +911,7 @@
         """
         result = []
         iterator = self.other_tree.iter_changes(self.base_tree,
-                include_unchanged=True, specific_files=self.interesting_files,
+                specific_files=self.interesting_files,
                 extra_trees=[self.this_tree])
         this_entries = dict((e.file_id, e) for p, e in
                             self.this_tree.iter_entries_by_dir(
@@ -1126,7 +1126,7 @@
         # 'other_tree.inventory.root' is not present in this tree. We are
         # calling adjust_path for children which *want* to be present with a
         # correct place to go.
-        for thing, child in self.other_tree.inventory.root.children.iteritems():
+        for _, child in self.other_tree.inventory.root.children.iteritems():
             trans_id = self.tt.trans_id_file_id(child.file_id)
             if not other_root_is_present:
                 if self.tt.final_kind(trans_id) is not None:
@@ -1134,8 +1134,12 @@
                     # to go already.
                     continue
             # Move the item into the root
-            self.tt.adjust_path(self.tt.final_name(trans_id),
-                                self.tt.root, trans_id)
+            try:
+                final_name = self.tt.final_name(trans_id)
+            except errors.NoFinalPath:
+                # This file is not present anymore, ignore it.
+                continue
+            self.tt.adjust_path(final_name, self.tt.root, trans_id)
         if other_root_is_present:
             self.tt.cancel_creation(other_root)
             self.tt.cancel_versioning(other_root)

=== modified file 'bzrlib/tests/per_workingtree/test_merge_from_branch.py'
--- a/bzrlib/tests/per_workingtree/test_merge_from_branch.py	2010-09-06 14:36:02 +0000
+++ b/bzrlib/tests/per_workingtree/test_merge_from_branch.py	2011-04-13 14:33:56 +0000
@@ -20,8 +20,9 @@
 import os
 
 from bzrlib import (
+    conflicts,
     errors,
-    merge
+    merge,
     )
 from bzrlib.tests import per_workingtree
 
@@ -129,6 +130,12 @@
              ('add', ('file3', 'file3-id', 'file', 'file3 content\n')),
              ])
         bld_inner.build_snapshot(
+            '4', ['1'],
+            [('add', ('file4', 'file4-id', 'file', 'file4 content\n'))
+             ])
+        bld_inner.build_snapshot(
+            '5', ['4'], [('rename', ('file4', 'dir/file4'))])
+        bld_inner.build_snapshot(
             '3', ['1'], [('modify', ('file3-id', 'new file3 contents\n')),])
         bld_inner.build_snapshot(
             '2', ['1'],
@@ -207,3 +214,39 @@
                                'foo'],
                               outer)
 
+    def test_file4_added_in_root(self):
+        outer, inner = self.make_outer_tree()
+        nb_conflicts = outer.merge_from_branch(inner, to_revision='4')
+        # file4 could not be added to its original root, so it gets added to
+        # the new root with a conflict.
+        self.assertEqual(1, nb_conflicts)
+        self.assertTreeLayout(['dir-outer',
+                               'dir-outer/dir',
+                               'dir-outer/dir/file1',
+                               'dir-outer/file3',
+                               'file4',
+                               'foo'],
+                              outer)
+
+    def test_file4_added_then_renamed(self):
+        outer, inner = self.make_outer_tree()
+        # 1 conflict, because file4 can't be put into the old root
+        self.assertEqual(1, outer.merge_from_branch(inner, to_revision='4'))
+        try:
+            outer.set_conflicts(conflicts.ConflictList())
+        except errors.UnsupportedOperation:
+            # WT2 doesn't have a separate list of conflicts to clear. It
+            # actually says there is a conflict, but happily forgets all about
+            # it.
+            pass
+        outer.commit('added file4')
+        # And now file4 gets renamed into an existing dir
+        nb_conflicts = outer.merge_from_branch(inner, to_revision='5')
+        self.assertEqual(1, nb_conflicts)
+        self.assertTreeLayout(['dir-outer',
+                               'dir-outer/dir',
+                               'dir-outer/dir/file1',
+                               'dir-outer/dir/file4',
+                               'dir-outer/file3',
+                               'foo'],
+                              outer)

=== modified file 'bzrlib/transform.py'
--- a/bzrlib/transform.py	2011-04-09 20:17:43 +0000
+++ b/bzrlib/transform.py	2011-04-15 07:05:06 +0000
@@ -3039,7 +3039,8 @@
                         file_id = tt.final_file_id(trans_id)
                         if file_id is None:
                             file_id = tt.inactive_file_id(trans_id)
-                        entry = path_tree.inventory[file_id]
+                        _, entry = path_tree.iter_entries_by_dir(
+                            [file_id]).next()
                         # special-case the other tree root (move its
                         # children to current root)
                         if entry.parent_id is None:

=== modified file 'doc/en/release-notes/bzr-2.4.txt'
--- a/doc/en/release-notes/bzr-2.4.txt	2011-04-11 09:56:15 +0000
+++ b/doc/en/release-notes/bzr-2.4.txt	2011-04-14 17:34:17 +0000
@@ -26,11 +26,9 @@
 .. Improvements to existing commands, especially improved performance 
    or memory usage, or better results.
 
-* When building a new WorkingTree (such as during ``bzr co`` or
-  ``bzr branch``) we now properly store the stat and hash of files that
-  are old enough. This saves a fair amount of time on the first
-  ``bzr status`` (on a 500MB tree, it saves about 30+s).
-  (John Arbash Meinel, #740932)
+* ``bzr merge`` in large trees is now significantly faster. On a 70k entry
+  tree, the time went from ~3min down to 30s.
+  (John Arbash Meinel, #759091)
 
 * Resolve ``lp:FOO`` urls locally rather than doing an XMLRPC request if
   the user has done ``bzr launchpad-login``. The bzr+ssh URLs were already
@@ -42,6 +40,13 @@
   call as much as 2s from Sydney. You can test the local logic by using
   ``-Dlaunchpad``.  (John Arbash Meinel, #397739)
 
+* When building a new WorkingTree (such as during ``bzr co`` or
+  ``bzr branch``) we now properly store the stat and hash of files that
+  are old enough. This saves a fair amount of time on the first
+  ``bzr status`` (on a 500MB tree, it saves about 30+s).
+  (John Arbash Meinel, #740932)
+
+
 Bug Fixes
 *********
 
@@ -58,6 +63,15 @@
 
 * Lazy hooks are now reset between test runs. (Jelmer Vernooij, #745566)
 
+* ``bzrlib.merge.Merge`` now calls ``iter_changes`` without
+  ``include_unversioned=True``. This makes it significantly faster in many
+  cases, because it only looks at modified files, rather than building
+  information about all files. This can cause failures in other
+  TreeTransform code, because it had been expecting to know the names of
+  things which had not changed (such as parent directories). All cases we
+  know about so far have been fixed, but there may be fallout for edge
+  cases that we are missing. (John Arbash Meinel, #759091)
+
 * Standalone bzr.exe installation on Windows: user can put additional python 
   libraries into ``site-packages`` subdirectory of the installation directory,
   this might be required for "installing" extra dependencies for some plugins.




More information about the bazaar-commits mailing list