53
#from difflib import SequenceMatcher
55
#self.a_ops = SequenceMatcher(None, self.base, self.a).get_opcodes()
56
#self.b_ops = SequenceMatcher(None, self.base, self.b).get_opcodes()
62
from difflib import SequenceMatcher
63
self.a_ops = SequenceMatcher(None, base, a).get_opcodes()
64
self.b_ops = SequenceMatcher(None, base, b).get_opcodes()
68
"""Return sequences of matching and conflicting regions.
72
The two sequences align only on regions which match the base
73
and both descendents. These are found by doing a two-way diff
74
of each one against the base, and then finding the
75
intersections between those regions. These "sync regions"
76
are by definition unchanged in both and easily dealt with.
78
The regions in between can be in any of three cases:
79
conflicted, or changed on only one side.
59
def find_conflicts(self):
60
"""Return a list of conflict regions.
62
Each entry is given as (base1, base2, a1, a2, b1, b2).
64
This indicates that the range [base1,base2] can be replaced by either
83
def find_sync_regions(self):
84
"""Return a list of sync regions, where both descendents match the base.
86
Generates a list of ((base1, base2), (a1, a2), (b1, b2)).
88
from difflib import SequenceMatcher
89
aiter = iter(SequenceMatcher(None, self.base, self.a).get_matching_blocks())
90
biter = iter(SequenceMatcher(None, self.base, self.b).get_matching_blocks())
92
abase, amatch, alen = aiter.next()
93
bbase, bmatch, blen = biter.next()
95
while aiter and biter:
96
# there is an unconflicted block at i; how long does it
97
# extend? until whichever one ends earlier.
98
i = intersect((abase, abase+alen), (bbase, bbase+blen))
102
intlen = intend - intbase
104
# found a match of base[i[0], i[1]]; this may be less than
105
# the region that matches in either one
106
assert intlen <= alen
107
assert intlen <= blen
108
assert abase <= intbase
109
assert bbase <= intbase
111
asub = amatch + (intbase - abase)
112
bsub = bmatch + (intbase - bbase)
116
assert self.base[intbase:intend] == self.a[asub:aend], \
117
(self.base[intbase:intend], self.a[asub:aend])
119
assert self.base[intbase:intend] == self.b[bsub:bend]
121
yield ((intbase, intend),
125
# advance whichever one ends first in the base text
126
if (abase + alen) < (bbase + blen):
127
abase, amatch, alen = aiter.next()
129
bbase, bmatch, blen = biter.next()
69
133
def find_unconflicted(self):