Rev 5848: When WT4.set_parent_trees() is called, sometimes we can use in http://bazaar.launchpad.net/~jameinel/bzr/2.4-set-parent-trees-delta-282941
John Arbash Meinel
john at arbash-meinel.com
Tue May 10 18:09:01 UTC 2011
At http://bazaar.launchpad.net/~jameinel/bzr/2.4-set-parent-trees-delta-282941
------------------------------------------------------------
revno: 5848
revision-id: john at arbash-meinel.com-20110510180853-yo31d6ipw4csxa8d
parent: pqm at pqm.ubuntu.com-20110510102823-vf4qlngmjhgg6538
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: 2.4-set-parent-trees-delta-282941
timestamp: Tue 2011-05-10 20:08:53 +0200
message:
When WT4.set_parent_trees() is called, sometimes we can use
update_basis_by_delta instead of the full set_parent_trees call.
If there is a single new tree, and the repository supports fast deltas,
and ...
This makes 'bzr uncommit' when there are no merges drop from 15s down to
2s. It should also help pull and update, but still debugging why it
isn't triggered as expected.
-------------- next part --------------
=== modified file 'bzrlib/tests/test_workingtree_4.py'
--- a/bzrlib/tests/test_workingtree_4.py 2011-04-07 10:36:24 +0000
+++ b/bzrlib/tests/test_workingtree_4.py 2011-05-10 18:08:53 +0000
@@ -258,6 +258,42 @@
lock_and_call_current_dirstate(tree, 'lock_tree_write')
self.assertRaises(errors.ObjectNotLocked, tree.current_dirstate)
+ def test_set_parent_trees_uses_update_basis_by_delta(self):
+ builder = self.make_branch_builder('source')
+ builder.start_series()
+ self.addCleanup(builder.finish_series)
+ builder.build_snapshot('A', [], [
+ ('add', ('', 'root-id', 'directory', None)),
+ ('add', ('a', 'a-id', 'file', 'content\n'))])
+ builder.build_snapshot('B', ['A'], [
+ ('modify', ('a-id', 'new content\nfor a\n')),
+ ('add', ('b', 'b-id', 'file', 'b-content\n'))])
+ tree = self.make_workingtree('tree')
+ source_branch = builder.get_branch()
+ tree.branch.repository.fetch(source_branch.repository, 'B')
+ tree.pull(source_branch, stop_revision='A')
+ tree.lock_write()
+ self.addCleanup(tree.unlock)
+ state = tree.current_dirstate()
+ called = []
+ orig_update = state.update_basis_by_delta
+ def log_update_basis_by_delta(delta, new_revid):
+ called.append(new_revid)
+ return orig_update(delta, new_revid)
+ state.update_basis_by_delta = log_update_basis_by_delta
+ basis = tree.basis_tree()
+ self.assertEqual('a-id', basis.path2id('a'))
+ self.assertEqual(None, basis.path2id('b'))
+ def fail_set_parent_trees(trees, ghosts):
+ raise AssertionError('dirstate.set_parent_trees() was called')
+ state.set_parent_trees = fail_set_parent_trees
+ repo = tree.branch.repository
+ tree.pull(source_branch, stop_revision='B')
+ self.assertEqual(['B'], called)
+ basis = tree.basis_tree()
+ self.assertEqual('a-id', basis.path2id('a'))
+ self.assertEqual('b-id', basis.path2id('b'))
+
def test_new_dirstate_on_new_lock(self):
# until we have detection for when a dirstate can be reused, we
# want to reparse dirstate on every new lock.
=== modified file 'bzrlib/workingtree_4.py'
--- a/bzrlib/workingtree_4.py 2011-05-10 09:30:33 +0000
+++ b/bzrlib/workingtree_4.py 2011-05-10 18:08:53 +0000
@@ -1145,7 +1145,20 @@
_mod_revision.NULL_REVISION)))
ghosts.append(rev_id)
accepted_revisions.add(rev_id)
- dirstate.set_parent_trees(real_trees, ghosts=ghosts)
+ if (len(real_trees) == 1
+ and not ghosts
+ and self.branch.repository._format.fast_deltas
+ and isinstance(real_trees[0][1], revisiontree.RevisionTree)
+ and self.get_parent_ids()):
+ rev_id, rev_tree = real_trees[0]
+ basis_id = self.get_parent_ids()[0]
+ basis_tree = self.branch.repository.revision_tree(basis_id)
+ delta = rev_tree.inventory._make_delta(basis_tree.inventory)
+ trace.note('updating via delta')
+ dirstate.update_basis_by_delta(delta, rev_id)
+ else:
+ import pdb; pdb.set_trace()
+ dirstate.set_parent_trees(real_trees, ghosts=ghosts)
self._make_dirty(reset_inventory=False)
def _set_root_id(self, file_id):
More information about the bazaar-commits
mailing list