Rev 3525: Update the lca_multi_way logic so that it can handle when bases supersede eachother for a given entry. in http://bzr.arbash-meinel.com/branches/bzr/1.6-dev/merge3_per_file
John Arbash Meinel
john at arbash-meinel.com
Mon Jun 30 19:19:47 BST 2008
At http://bzr.arbash-meinel.com/branches/bzr/1.6-dev/merge3_per_file
------------------------------------------------------------
revno: 3525
revision-id: john at arbash-meinel.com-20080630181914-tbo6tazaxj50185c
parent: john at arbash-meinel.com-20080626235243-d1sli6ayrssk7bym
committer: John Arbash Meinel <john at arbash-meinel.com>
branch nick: merge3_per_file
timestamp: Mon 2008-06-30 13:19:14 -0500
message:
Update the lca_multi_way logic so that it can handle when bases supersede eachother for a given entry.
-------------- next part --------------
=== modified file 'bzrlib/merge.py'
--- a/bzrlib/merge.py 2008-06-26 23:52:43 +0000
+++ b/bzrlib/merge.py 2008-06-30 18:19:14 +0000
@@ -640,7 +640,7 @@
changed boolean indicating whether the file contents
or kind were changed versus any base
parents parent ids for ([bases], other, this)
- names names for ([bases], other, this)
+ names names for ((unique_lca_base, [lca_bases]), other, this)
executable execute-bit values for ([bases], other, this)
"""
bases_values = {}
@@ -706,18 +706,25 @@
# Now we should have an entry in each base tree, and an entry for this
# and other
result = []
+ unique_lca_inventory = self.base_tree.inventory
assert not all_file_ids.symmetric_difference(file_id_ordering)
for file_id in file_id_ordering:
+ unique_lca_base = get_info_from_inventory(file_id,
+ unique_lca_inventory)
+ try:
+ unique_lca_base_ie = self.base_tree.inventory[file_id]
+ except errors.NoSuchId:
+ unique_lca_base_ie = None
base_tuples = [base[file_id] for base in bases_values.itervalues()]
changed = all_changed.get(file_id, False)
this_tuple = this_values[file_id]
other_tuple = other_values[file_id]
- parents = ([b[0] for b in base_tuples], other_tuple[0],
- this_tuple[0])
- names = ([b[1] for b in base_tuples], other_tuple[1],
- this_tuple[1])
- executable = ([b[2] for b in base_tuples], other_tuple[2],
- this_tuple[2])
+ parents = ((unique_lca_base[0], [b[0] for b in base_tuples]),
+ other_tuple[0], this_tuple[0])
+ names = ((unique_lca_base[1], [b[1] for b in base_tuples]),
+ other_tuple[1], this_tuple[1])
+ executable = ((unique_lca_base[2], [b[2] for b in base_tuples]),
+ other_tuple[2], this_tuple[2])
result.append((file_id, changed, parents, names, executable))
return result
@@ -821,25 +828,38 @@
:return: One of 'this', 'conflict', or 'other'
indicating which one should be taken, or that there was a conflict.
"""
- base_first = bases[0]
- for base in bases[1:]:
- # XXX: This is not technically correct. A value does not always
- # supersede None. Sometimes you get None because someone
- # deleted an object. The correct resolution would probably be
- # to recurse back into the LCA of these bases until we get
- # some sort of convergance. (Eventually you always reach NULL
- # where everything is None). That would let us know if this
- # None is a "didn't exist yet" or a "deleted".
- if base is not None and base_first != base:
- break
- else: # All the bases are identical, we can just use 3-way
- return Merge3Merger._three_way(base_first, other, this)
+ # Either nothing changed or "Ambiguous clean merge" -- both sides have
+ # made the same change. Either way, nothing to merge.
+ if other == this:
+ return "this"
+ unique_lca_base_value, lca_bases_value = bases
+
+ # Check if the lca's agree, so that we can just use standard 3-way
+ # merge logic.
+ # TODO: This is a shortcut for figuring out if one of the LCA values
+ # supercedes another. However, it is using a shortcut based on
+ # unique_lca. It is possible that a value should supersede even
+ # though it isn't available here.
+ interesting_values = []
+ for base_value in lca_bases_value:
+ if (base_value != unique_lca_base_value
+ and base_value not in interesting_values):
+ interesting_values.append(base_value)
+
+ if len(interesting_values) == 0:
+ import pdb; pdb.set_trace()
+ # All of them == the value in the unique base, just use it.
+ return Merge3Merger._three_way(unique_lca_base_value, other, this)
+ elif len(interesting_values) == 1:
+ import pdb; pdb.set_trace()
+ # There was only 1 interesting value (not equal to unique base)
+ # So again we can collapse
+ return Merge3Merger._three_way(interesting_values[0], other, this)
+ import pdb; pdb.set_trace()
+
# If we got this far, we have variation in what the common ancestors
# think is the correct value for this path.
- # "Ambiguous clean merge" -- both sides have made the same change.
- if other == this:
- return "this"
# Punt at this point, we might be able to work something out, but for
# now, just conflict
# TODO: Consider the ramifications of something like:
@@ -849,6 +869,7 @@
# return "other"
# Also, if *both* are in 'bases' is this a conflict? Arguably
# both sides have chosen to supersede the base value.
+ # This could be seen as a "annotation" merge for scalars
return "conflict"
@staticmethod
@@ -1585,7 +1606,7 @@
break
elif len(next_lcas) > 2:
# Fall back to grabbing all of the ancestry for this entry
- warning('Found more than to Least Common Ancestors'
+ warning('Found more than two Least Common Ancestors'
' falling back to full ancestry. For %s',
self.vf)
cur_lcas = next_lcas
More information about the bazaar-commits
mailing list