mirror of
https://github.com/mhagger/git-imerge.git
synced 2024-09-21 12:39:56 +03:00
Handle vertex merges more carefully.
When autofilling the vertex of a block, it is possible to do the merge three ways: 1. Using the commits directly above and to the left as parents 2. Using the commits at [i1,0] and [i1-1,i2] as parents (i.e., as a continuation of the bottom edge) 3. Using the commits at [i1,i2-1] and [0,i2] as parents (i.e., as a continuation of the right edge) We want the final history to be *as if* the parents were as in (1). Formerly we were doing (1) and simply using the result. This is incorrect because the neighboring commits do not have correct histories. Therefore, the merge base for this merge is [0,0], and the merge can have unnecessary conflicts. Change to trying both (2) and (3). If both of those commits succeed *and* if they give identical trees, then create a synthetic commit with the parents as in (1) and use that; otherwise, fail.
This commit is contained in:
parent
43c96036be
commit
8d283e9658
42
git-imerge
42
git-imerge
@ -1241,19 +1241,18 @@ class Block(object):
|
||||
# of them permanently.
|
||||
merges = []
|
||||
|
||||
def do_merge(i1, commit1, i2, commit2):
|
||||
def do_merge(i1, commit1, i2, commit2, msg='Autofilling %d-%d...', record=True):
|
||||
if (i1, i2) in self:
|
||||
return self[i1,i2].sha1
|
||||
try:
|
||||
sys.stderr.write(
|
||||
'Autofilling %d-%d...' % self.get_original_indexes(i1, i2)
|
||||
)
|
||||
sys.stderr.write(msg % self.get_original_indexes(i1, i2))
|
||||
merge = automerge(commit1, commit2)
|
||||
sys.stderr.write('success.\n')
|
||||
except AutomaticMergeFailed, e:
|
||||
sys.stderr.write('unexpected conflict. Backtracking...\n')
|
||||
raise UnexpectedMergeFailure(str(e), i1, i2)
|
||||
merges.append((i1, i2, merge))
|
||||
if record:
|
||||
merges.append((i1, i2, merge))
|
||||
return merge
|
||||
|
||||
i2 = self.len2 - 1
|
||||
@ -1266,10 +1265,39 @@ class Block(object):
|
||||
for i2 in range(1, self.len2 - 1):
|
||||
above = do_merge(i1, above, i2, self[0,i2].sha1)
|
||||
|
||||
# We will compare two ways of doing the final "vertex" merge:
|
||||
# as a continuation of the bottom edge, or as a continuation
|
||||
# of the right edge. We only accept it if both approaches
|
||||
# succeed and give identical trees.
|
||||
i1, i2 = self.len1 - 1, self.len2 - 1
|
||||
do_merge(i1, above, i2, left)
|
||||
vertex_v1 = do_merge(
|
||||
i1, self[i1,0].sha1, i2, left,
|
||||
msg='Autofilling %d-%d (first way)...',
|
||||
record=False,
|
||||
)
|
||||
vertex_v2 = do_merge(
|
||||
i1, above, i2, self[0,i2].sha1,
|
||||
msg='Autofilling %d-%d (second way)...',
|
||||
record=False,
|
||||
)
|
||||
if get_tree(vertex_v1) == get_tree(vertex_v2):
|
||||
sys.stderr.write(
|
||||
'The two ways of autofilling %d-%d agree.\n'
|
||||
% self.get_original_indexes(i1, i2)
|
||||
)
|
||||
else:
|
||||
sys.stderr.write(
|
||||
'The two ways of autofilling %d-%d do not agree. Backtracking...\n'
|
||||
% self.get_original_indexes(i1, i2)
|
||||
)
|
||||
raise UnexpectedMergeFailure('Inconsistent vertex merges', i1, i2)
|
||||
|
||||
# Success! Now we can record the results:
|
||||
# Everything is OK. Now reparent the actual vertex merge to
|
||||
# have above and left as its parents:
|
||||
merges.append((i1, i2, reparent(vertex_v1, [above, left])))
|
||||
|
||||
# Done! Now we can record the results:
|
||||
sys.stderr.write('Recording autofilled block %s.\n' % (self,))
|
||||
for (i1, i2, merge) in merges:
|
||||
self[i1, i2].record_merge(merge, MergeRecord.NEW_AUTO)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user