Rev 3529: Initial work on _entries_lca. in http://bzr.arbash-meinel.com/branches/bzr/1.6-dev/merge_lca_multi
John Arbash Meinel
john at arbash-meinel.com
Tue Jul 22 17:48:25 BST 2008
At http://bzr.arbash-meinel.com/branches/bzr/1.6-dev/merge_lca_multi
------------------------------------------------------------
revno: 3529
revision-id: john at arbash-meinel.com-20080722164720-h66kbfwehfpcpyis
parent: john at arbash-meinel.com-20080722154417-qoc7kmrv0i4orptm
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: merge_lca_multi
timestamp: Tue 2008-07-22 11:47:20 -0500
message:
Initial work on _entries_lca.
At least get the basic API working, and track when a file is modified.
I'm going to need a better test setup if I'm going to handle all the test cases in
a way that can be actually understood.
-------------- next part --------------
=== modified file 'bzrlib/merge.py'
--- a/bzrlib/merge.py 2008-07-22 15:44:17 +0000
+++ b/bzrlib/merge.py 2008-07-22 16:47:20 +0000
@@ -27,6 +27,7 @@
patiencediff,
registry,
revision as _mod_revision,
+ tree as _mod_tree,
)
from bzrlib.branch import Branch
from bzrlib.conflicts import ConflictList, Conflict
@@ -638,6 +639,50 @@
result.append((file_id, changed, parents3, names3, executable3))
return result
+ def _entries_lca(self):
+ """Gather data about files modified between multiple trees.
+
+ This compares OTHER versus all LCA trees, and for interesting entries,
+ it then compares with THIS and BASE.
+
+ For the multi-valued entries, the format will be (BASE, [lca1, lca2])
+ :return: [(file_id, changed, parents, names, executable)]
+ file_id Simple file_id of the entry
+ changed Boolean, True if the kind or contents changed
+ else False
+ parents ((base, [parent_id, in, lcas]), parent_id_other,
+ parent_id_this)
+ names ((base, [name, in, lcas]), name_in_other, name_in_this)
+ executable ((base, [exec, in, lcas]), exec_in_other, exec_in_this)
+ """
+ result = []
+ walker = _mod_tree.MultiWalker(self.other_tree,
+ self._lca_trees.values())
+
+ for path, file_id, other_ie, lca_values in walker.iter_all():
+ # Is this modified at all from any of the other trees?
+ last_rev = other_ie.revision
+ for lca_path, ie in lca_values:
+ if ie.revision != last_rev:
+ break
+ else: # Identical in all trees
+ continue
+ base_ie = self.base_tree.inventory[file_id]
+ this_ie = self.this_tree.inventory[file_id]
+ result.append((file_id, True,
+ ((base_ie.parent_id,
+ [ie.parent_id for path, ie in lca_values]),
+ other_ie.parent_id, this_ie.parent_id),
+ ((base_ie.name,
+ [ie.name for path, ie in lca_values]),
+ other_ie.name, this_ie.name),
+ ((base_ie.executable,
+ [ie.executable for path, ie in lca_values]),
+ other_ie.executable, this_ie.executable)
+ ))
+ return result
+
+
def fix_root(self):
try:
self.tt.final_kind(self.tt.root)
=== modified file 'bzrlib/tests/test_merge.py'
--- a/bzrlib/tests/test_merge.py 2008-07-22 15:44:17 +0000
+++ b/bzrlib/tests/test_merge.py 2008-07-22 16:47:20 +0000
@@ -825,3 +825,58 @@
merge_obj = merger.make_merger()
self.assertIsInstance(merge_obj, UnsupportedLCATreesMerger)
self.assertFalse('lca_trees' in merge_obj.kwargs)
+
+ def test__entries_lca_simple(self):
+ tree = self.make_branch_and_memory_tree('tree')
+ tree.lock_write()
+ self.addCleanup(tree.unlock)
+ tree.add('.')
+ tree.add(['a'], ['a-id'], ['file'])
+ tree.put_file_bytes_non_atomic('a-id', 'a\nb\nc\n')
+ tree.commit('A', rev_id='A-id')
+ tree.put_file_bytes_non_atomic('a-id', 'a\nb\nC\nc\n')
+ tree.commit('C', rev_id='C-id')
+ tree.branch.set_last_revision_info(1, 'A-id')
+ tree.set_parent_ids(['A-id'])
+ tree.put_file_bytes_non_atomic('a-id', 'a\nB\nb\nc\n')
+ tree.commit('B', rev_id='B-id')
+ tree.set_parent_ids(['B-id', 'C-id'])
+ tree.put_file_bytes_non_atomic('a-id', 'a\nB\nb\nC\nc\n')
+ tree.commit('D', rev_id='D-id')
+ tree.branch.set_last_revision_info(2, 'C-id')
+ tree.set_parent_ids(['C-id', 'B-id'])
+ tree.put_file_bytes_non_atomic('a-id', 'a\nB\nb\nC\nc\nE\n')
+ tree.commit('E', rev_id='E-id')
+ tree.branch.set_last_revision_info(2, 'D-id')
+ tree.set_parent_ids(['D-id'])
+
+ merger = _mod_merge.Merger.from_revision_ids(progress.DummyProgress(),
+ tree, 'E-id')
+ merger.merge_type = _mod_merge.Merge3Merger
+ merge_obj = merger.make_merger()
+
+ entries = list(merge_obj._entries_lca())
+ root_id = tree.path2id('')
+ self.assertEqual(['B-id', 'C-id'], sorted(merge_obj._lca_trees.keys()))
+
+ # (file_id, changed, parents, names, executable)
+ # BASE, lca1, lca2, OTHER, THIS
+ self.assertEqual([(root_id, True,
+ ((None, [None, None]), None, None),
+ ((u'', [u'', u'']), u'', u''),
+ ((False, [False, False]), False, False)),
+ ('a-id', True,
+ ((root_id, [root_id, root_id]), root_id, root_id),
+ ((u'a', [u'a', u'a']), u'a', u'a'),
+ ((False, [False, False]), False, False)),
+ ], entries)
+
+
+ # TODO: cases to test
+ # simple criss-cross LCAS identical, BASE different
+ # x-x changed from BASE but identical for all LCAs and tips
+ # x-x file not in BASE
+ # x-x file not in THIS
+ # x-x OTHER deletes the file
+ # x-x OTHER introduces the file
+ # x-x LCAs differ, one in ancestry of other for a given file
More information about the bazaar-commits
mailing list