/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
4597.9.8 by Vincent Ladeuil
Merge bzr.dev into cleanup
1
# Copyright (C) 2005-2010 Canonical Ltd
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
2
#
821 by Martin Pool
- start code for built-in diff3-style resolve
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
7
#
821 by Martin Pool
- start code for built-in diff3-style resolve
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
1887.1.1 by Adeodato Simó
Do not separate paragraphs in the copyright statement with blank lines,
12
#
821 by Martin Pool
- start code for built-in diff3-style resolve
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
821 by Martin Pool
- start code for built-in diff3-style resolve
16
6379.6.3 by Jelmer Vernooij
Use absolute_import.
17
from __future__ import absolute_import
821 by Martin Pool
- start code for built-in diff3-style resolve
18
823 by Martin Pool
quote
19
# mbp: "you know that thing where cvs gives you conflict markers?"
20
# s: "i hate that."
21
7290.14.1 by Jelmer Vernooij
Use external patiencediff.
22
import patiencediff
23
24
6624 by Jelmer Vernooij
Merge Python3 porting work ('py3 pokes')
25
from . import (
5184.1.1 by Vincent Ladeuil
Random cleanups to catch up with copyright updates in trunk.
26
    errors,
27
    textfile,
28
    )
821 by Martin Pool
- start code for built-in diff3-style resolve
29
1711.2.11 by John Arbash Meinel
Rename patiencediff.SequenceMatcher => PatienceSequenceMatcher and knit.SequenceMatcher => KnitSequenceMatcher
30
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
31
class CantReprocessAndShowBase(errors.BzrError):
32
33
    _fmt = ("Can't reprocess and show base, because reprocessing obscures "
7143.15.2 by Jelmer Vernooij
Run autopep8.
34
            "the relationship of conflicting lines to the base")
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
35
36
821 by Martin Pool
- start code for built-in diff3-style resolve
37
def intersect(ra, rb):
38
    """Given two ranges return the range where they intersect or None.
39
40
    >>> intersect((0, 10), (0, 6))
41
    (0, 6)
42
    >>> intersect((0, 10), (5, 15))
43
    (5, 10)
44
    >>> intersect((0, 10), (10, 15))
45
    >>> intersect((0, 9), (10, 15))
46
    >>> intersect((0, 9), (7, 15))
47
    (7, 9)
48
    """
3376.2.9 by Martin Pool
Restore some assertions as comments
49
    # preconditions: (ra[0] <= ra[1]) and (rb[0] <= rb[1])
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
50
821 by Martin Pool
- start code for built-in diff3-style resolve
51
    sa = max(ra[0], rb[0])
52
    sb = min(ra[1], rb[1])
53
    if sa < sb:
54
        return sa, sb
55
    else:
56
        return None
57
58
839 by Martin Pool
- avoid copying string lists when handling unmatched regions
59
def compare_range(a, astart, aend, b, bstart, bend):
60
    """Compare a[astart:aend] == b[bstart:bend], without slicing.
61
    """
7143.15.2 by Jelmer Vernooij
Run autopep8.
62
    if (aend - astart) != (bend - bstart):
839 by Martin Pool
- avoid copying string lists when handling unmatched regions
63
        return False
6651.2.2 by Martin
Apply 2to3 xrange fix and fix up with sixish range
64
    for ia, ib in zip(range(astart, aend), range(bstart, bend)):
839 by Martin Pool
- avoid copying string lists when handling unmatched regions
65
        if a[ia] != b[ib]:
66
            return False
67
    else:
68
        return True
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
69
839 by Martin Pool
- avoid copying string lists when handling unmatched regions
70
821 by Martin Pool
- start code for built-in diff3-style resolve
71
class Merge3(object):
72
    """3-way merge of texts.
73
74
    Given BASE, OTHER, THIS, tries to produce a combined text
75
    incorporating the changes from both BASE->OTHER and BASE->THIS.
76
    All three will typically be sequences of lines."""
5158.5.1 by Andrew Bennetts
Allow Merge3 to work with objects, not just lists of strs. This removes a lot of cruft from news_merge.
77
78
    def __init__(self, base, a, b, is_cherrypick=False, allow_objects=False):
79
        """Constructor.
80
81
        :param base: lines in BASE
82
        :param a: lines in A
83
        :param b: lines in B
84
        :param is_cherrypick: flag indicating if this merge is a cherrypick.
85
            When cherrypicking b => a, matches with b and base do not conflict.
86
        :param allow_objects: if True, do not require that base, a and b are
87
            plain Python strs.  Also prevents BinaryFile from being raised.
88
            Lines can be any sequence of comparable and hashable Python
89
            objects.
90
        """
91
        if not allow_objects:
5184.1.1 by Vincent Ladeuil
Random cleanups to catch up with copyright updates in trunk.
92
            textfile.check_text_lines(base)
93
            textfile.check_text_lines(a)
94
            textfile.check_text_lines(b)
821 by Martin Pool
- start code for built-in diff3-style resolve
95
        self.base = base
96
        self.a = a
97
        self.b = b
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
98
        self.is_cherrypick = is_cherrypick
827 by Martin Pool
- new Merge3.merge_groups feeds back the merged lines
99
828 by Martin Pool
- code to represent merges in regular text conflict form
100
    def merge_lines(self,
829 by Martin Pool
- More merge3 cvs-form stuff
101
                    name_a=None,
102
                    name_b=None,
1185.18.1 by Aaron Bentley
Added --show-base to merge
103
                    name_base=None,
6973.6.1 by Jelmer Vernooij
More bees.
104
                    start_marker=b'<<<<<<<',
105
                    mid_marker=b'=======',
106
                    end_marker=b'>>>>>>>',
1185.24.1 by Aaron Bentley
Got reprocessing working
107
                    base_marker=None,
108
                    reprocess=False):
828 by Martin Pool
- code to represent merges in regular text conflict form
109
        """Return merge in cvs-like form.
110
        """
6973.6.1 by Jelmer Vernooij
More bees.
111
        newline = b'\n'
1551.10.38 by Aaron Bentley
merge3 auto-detects line endings for conflict markers
112
        if len(self.a) > 0:
6973.6.1 by Jelmer Vernooij
More bees.
113
            if self.a[0].endswith(b'\r\n'):
114
                newline = b'\r\n'
115
            elif self.a[0].endswith(b'\r'):
116
                newline = b'\r'
1185.24.1 by Aaron Bentley
Got reprocessing working
117
        if base_marker and reprocess:
7029.4.1 by Jelmer Vernooij
Fix a bunch of merge tests.
118
            raise CantReprocessAndShowBase()
829 by Martin Pool
- More merge3 cvs-form stuff
119
        if name_a:
6973.6.1 by Jelmer Vernooij
More bees.
120
            start_marker = start_marker + b' ' + name_a
829 by Martin Pool
- More merge3 cvs-form stuff
121
        if name_b:
6973.6.1 by Jelmer Vernooij
More bees.
122
            end_marker = end_marker + b' ' + name_b
1185.18.1 by Aaron Bentley
Added --show-base to merge
123
        if name_base and base_marker:
6973.6.1 by Jelmer Vernooij
More bees.
124
            base_marker = base_marker + b' ' + name_base
1185.24.1 by Aaron Bentley
Got reprocessing working
125
        merge_regions = self.merge_regions()
126
        if reprocess is True:
127
            merge_regions = self.reprocess_merge_regions(merge_regions)
128
        for t in merge_regions:
828 by Martin Pool
- code to represent merges in regular text conflict form
129
            what = t[0]
130
            if what == 'unchanged':
131
                for i in range(t[1], t[2]):
132
                    yield self.base[i]
830 by Martin Pool
- handle chunks which differ from the base but agree
133
            elif what == 'a' or what == 'same':
828 by Martin Pool
- code to represent merges in regular text conflict form
134
                for i in range(t[1], t[2]):
135
                    yield self.a[i]
136
            elif what == 'b':
137
                for i in range(t[1], t[2]):
138
                    yield self.b[i]
139
            elif what == 'conflict':
1551.10.38 by Aaron Bentley
merge3 auto-detects line endings for conflict markers
140
                yield start_marker + newline
828 by Martin Pool
- code to represent merges in regular text conflict form
141
                for i in range(t[3], t[4]):
142
                    yield self.a[i]
1185.18.1 by Aaron Bentley
Added --show-base to merge
143
                if base_marker is not None:
1551.10.38 by Aaron Bentley
merge3 auto-detects line endings for conflict markers
144
                    yield base_marker + newline
1185.18.1 by Aaron Bentley
Added --show-base to merge
145
                    for i in range(t[1], t[2]):
146
                        yield self.base[i]
1551.10.38 by Aaron Bentley
merge3 auto-detects line endings for conflict markers
147
                yield mid_marker + newline
828 by Martin Pool
- code to represent merges in regular text conflict form
148
                for i in range(t[5], t[6]):
149
                    yield self.b[i]
1551.10.38 by Aaron Bentley
merge3 auto-detects line endings for conflict markers
150
                yield end_marker + newline
828 by Martin Pool
- code to represent merges in regular text conflict form
151
            else:
152
                raise ValueError(what)
153
832 by Martin Pool
- New Merge3.merge_annotated method for debugging.
154
    def merge_annotated(self):
155
        """Return merge with conflicts, showing origin of lines.
156
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
157
        Most useful for debugging merge.
832 by Martin Pool
- New Merge3.merge_annotated method for debugging.
158
        """
159
        for t in self.merge_regions():
160
            what = t[0]
161
            if what == 'unchanged':
162
                for i in range(t[1], t[2]):
163
                    yield 'u | ' + self.base[i]
164
            elif what == 'a' or what == 'same':
165
                for i in range(t[1], t[2]):
166
                    yield what[0] + ' | ' + self.a[i]
167
            elif what == 'b':
168
                for i in range(t[1], t[2]):
169
                    yield 'b | ' + self.b[i]
170
            elif what == 'conflict':
171
                yield '<<<<\n'
172
                for i in range(t[3], t[4]):
173
                    yield 'A | ' + self.a[i]
174
                yield '----\n'
175
                for i in range(t[5], t[6]):
176
                    yield 'B | ' + self.b[i]
177
                yield '>>>>\n'
178
            else:
179
                raise ValueError(what)
180
827 by Martin Pool
- new Merge3.merge_groups feeds back the merged lines
181
    def merge_groups(self):
182
        """Yield sequence of line groups.  Each one is a tuple:
183
184
        'unchanged', lines
185
             Lines unchanged from base
186
187
        'a', lines
188
             Lines taken from a
189
830 by Martin Pool
- handle chunks which differ from the base but agree
190
        'same', lines
191
             Lines taken from a (and equal to b)
192
827 by Martin Pool
- new Merge3.merge_groups feeds back the merged lines
193
        'b', lines
194
             Lines taken from b
195
196
        'conflict', base_lines, a_lines, b_lines
197
             Lines from base were changed to either a or b and conflict.
198
        """
199
        for t in self.merge_regions():
200
            what = t[0]
201
            if what == 'unchanged':
202
                yield what, self.base[t[1]:t[2]]
830 by Martin Pool
- handle chunks which differ from the base but agree
203
            elif what == 'a' or what == 'same':
827 by Martin Pool
- new Merge3.merge_groups feeds back the merged lines
204
                yield what, self.a[t[1]:t[2]]
205
            elif what == 'b':
206
                yield what, self.b[t[1]:t[2]]
207
            elif what == 'conflict':
208
                yield (what,
209
                       self.base[t[1]:t[2]],
210
                       self.a[t[3]:t[4]],
211
                       self.b[t[5]:t[6]])
212
            else:
213
                raise ValueError(what)
214
825 by Martin Pool
- Merge3.find_sync_regions always returns a zero-length sentinal at the end to
215
    def merge_regions(self):
822 by Martin Pool
- Renamed merge3 test suite for easier access.
216
        """Return sequences of matching and conflicting regions.
217
825 by Martin Pool
- Merge3.find_sync_regions always returns a zero-length sentinal at the end to
218
        This returns tuples, where the first value says what kind we
219
        have:
220
221
        'unchanged', start, end
222
             Take a region of base[start:end]
223
830 by Martin Pool
- handle chunks which differ from the base but agree
224
        'same', astart, aend
225
             b and a are different from base but give the same result
226
825 by Martin Pool
- Merge3.find_sync_regions always returns a zero-length sentinal at the end to
227
        'a', start, end
228
             Non-clashing insertion from a[start:end]
229
822 by Martin Pool
- Renamed merge3 test suite for easier access.
230
        Method is as follows:
231
232
        The two sequences align only on regions which match the base
233
        and both descendents.  These are found by doing a two-way diff
234
        of each one against the base, and then finding the
235
        intersections between those regions.  These "sync regions"
236
        are by definition unchanged in both and easily dealt with.
237
238
        The regions in between can be in any of three cases:
239
        conflicted, or changed on only one side.
240
        """
825 by Martin Pool
- Merge3.find_sync_regions always returns a zero-length sentinal at the end to
241
242
        # section a[0:ia] has been disposed of, etc
243
        iz = ia = ib = 0
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
244
825 by Martin Pool
- Merge3.find_sync_regions always returns a zero-length sentinal at the end to
245
        for zmatch, zend, amatch, aend, bmatch, bend in self.find_sync_regions():
246
            matchlen = zend - zmatch
3376.2.9 by Martin Pool
Restore some assertions as comments
247
            # invariants:
248
            #   matchlen >= 0
249
            #   matchlen == (aend - amatch)
250
            #   matchlen == (bend - bmatch)
826 by Martin Pool
- Actually merge unsynchronized regions. Woot!
251
            len_a = amatch - ia
252
            len_b = bmatch - ib
3376.2.9 by Martin Pool
Restore some assertions as comments
253
            # invariants:
254
            # assert len_a >= 0
255
            # assert len_b >= 0
256
7143.15.2 by Jelmer Vernooij
Run autopep8.
257
            # print 'unmatched a=%d, b=%d' % (len_a, len_b)
838 by Martin Pool
- Merge3.find_sync_regions() - avoid problems with iters on python2.3 by
258
826 by Martin Pool
- Actually merge unsynchronized regions. Woot!
259
            if len_a or len_b:
839 by Martin Pool
- avoid copying string lists when handling unmatched regions
260
                # try to avoid actually slicing the lists
261
                same = compare_range(self.a, ia, amatch,
262
                                     self.b, ib, bmatch)
826 by Martin Pool
- Actually merge unsynchronized regions. Woot!
263
830 by Martin Pool
- handle chunks which differ from the base but agree
264
                if same:
265
                    yield 'same', ia, amatch
826 by Martin Pool
- Actually merge unsynchronized regions. Woot!
266
                else:
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
267
                    equal_a = compare_range(self.a, ia, amatch,
268
                                            self.base, iz, zmatch)
269
                    equal_b = compare_range(self.b, ib, bmatch,
270
                                            self.base, iz, zmatch)
271
                    if equal_a and not equal_b:
272
                        yield 'b', ib, bmatch
273
                    elif equal_b and not equal_a:
274
                        yield 'a', ia, amatch
275
                    elif not equal_a and not equal_b:
276
                        if self.is_cherrypick:
277
                            for node in self._refine_cherrypick_conflict(
7143.15.2 by Jelmer Vernooij
Run autopep8.
278
                                    iz, zmatch, ia, amatch,
279
                                    ib, bmatch):
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
280
                                yield node
281
                        else:
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
282
                            yield ('conflict', iz, zmatch, ia, amatch, ib,
283
                                   bmatch)
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
284
                    else:
7143.15.2 by Jelmer Vernooij
Run autopep8.
285
                        raise AssertionError(
286
                            "can't handle a=b=base but unmatched")
826 by Martin Pool
- Actually merge unsynchronized regions. Woot!
287
825 by Martin Pool
- Merge3.find_sync_regions always returns a zero-length sentinal at the end to
288
                ia = amatch
826 by Martin Pool
- Actually merge unsynchronized regions. Woot!
289
                ib = bmatch
290
            iz = zmatch
291
292
            # if the same part of the base was deleted on both sides
293
            # that's OK, we can just skip it.
825 by Martin Pool
- Merge3.find_sync_regions always returns a zero-length sentinal at the end to
294
295
            if matchlen > 0:
3376.2.9 by Martin Pool
Restore some assertions as comments
296
                # invariants:
297
                # assert ia == amatch
298
                # assert ib == bmatch
299
                # assert iz == zmatch
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
300
825 by Martin Pool
- Merge3.find_sync_regions always returns a zero-length sentinal at the end to
301
                yield 'unchanged', zmatch, zend
302
                iz = zend
303
                ia = aend
304
                ib = bend
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
305
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
306
    def _refine_cherrypick_conflict(self, zstart, zend, astart, aend, bstart,
307
                                    bend):
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
308
        """When cherrypicking b => a, ignore matches with b and base."""
309
        # Do not emit regions which match, only regions which do not match
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
310
        matches = patiencediff.PatienceSequenceMatcher(
311
            None, self.base[zstart:zend], self.b[bstart:bend]
312
            ).get_matching_blocks()
3249.3.2 by John Arbash Meinel
review feedback from Robert
313
        last_base_idx = 0
314
        last_b_idx = 0
315
        last_b_idx = 0
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
316
        yielded_a = False
3249.3.2 by John Arbash Meinel
review feedback from Robert
317
        for base_idx, b_idx, match_len in matches:
318
            conflict_b_len = b_idx - last_b_idx
7260.1.2 by Jelmer Vernooij
Fix flake8 issues.
319
            if conflict_b_len == 0:
320
                # There are no lines in b which conflict, so skip it
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
321
                pass
322
            else:
323
                if yielded_a:
3249.3.2 by John Arbash Meinel
review feedback from Robert
324
                    yield ('conflict',
325
                           zstart + last_base_idx, zstart + base_idx,
326
                           aend, aend, bstart + last_b_idx, bstart + b_idx)
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
327
                else:
328
                    # The first conflict gets the a-range
329
                    yielded_a = True
3249.3.2 by John Arbash Meinel
review feedback from Robert
330
                    yield ('conflict', zstart + last_base_idx, zstart +
7143.15.2 by Jelmer Vernooij
Run autopep8.
331
                           base_idx,
3249.3.2 by John Arbash Meinel
review feedback from Robert
332
                           astart, aend, bstart + last_b_idx, bstart + b_idx)
333
            last_base_idx = base_idx + match_len
334
            last_b_idx = b_idx + match_len
335
        if last_base_idx != zend - zstart or last_b_idx != bend - bstart:
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
336
            if yielded_a:
3249.3.2 by John Arbash Meinel
review feedback from Robert
337
                yield ('conflict', zstart + last_base_idx, zstart + base_idx,
338
                       aend, aend, bstart + last_b_idx, bstart + b_idx)
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
339
            else:
340
                # The first conflict gets the a-range
341
                yielded_a = True
3249.3.2 by John Arbash Meinel
review feedback from Robert
342
                yield ('conflict', zstart + last_base_idx, zstart + base_idx,
343
                       astart, aend, bstart + last_b_idx, bstart + b_idx)
3249.3.1 by John Arbash Meinel
Implement cherrypick support for Merge3
344
        if not yielded_a:
345
            yield ('conflict', zstart, zend, astart, aend, bstart, bend)
1185.24.1 by Aaron Bentley
Got reprocessing working
346
347
    def reprocess_merge_regions(self, merge_regions):
1185.33.62 by Martin Pool
doc
348
        """Where there are conflict regions, remove the agreed lines.
349
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
350
        Lines where both A and B have made the same changes are
1185.33.62 by Martin Pool
doc
351
        eliminated.
352
        """
1185.24.1 by Aaron Bentley
Got reprocessing working
353
        for region in merge_regions:
354
            if region[0] != "conflict":
355
                yield region
356
                continue
357
            type, iz, zmatch, ia, amatch, ib, bmatch = region
358
            a_region = self.a[ia:amatch]
359
            b_region = self.b[ib:bmatch]
5184.1.1 by Vincent Ladeuil
Random cleanups to catch up with copyright updates in trunk.
360
            matches = patiencediff.PatienceSequenceMatcher(
7143.15.2 by Jelmer Vernooij
Run autopep8.
361
                None, a_region, b_region).get_matching_blocks()
1185.24.1 by Aaron Bentley
Got reprocessing working
362
            next_a = ia
363
            next_b = ib
364
            for region_ia, region_ib, region_len in matches[:-1]:
365
                region_ia += ia
366
                region_ib += ib
367
                reg = self.mismatch_region(next_a, region_ia, next_b,
368
                                           region_ib)
369
                if reg is not None:
370
                    yield reg
7143.15.2 by Jelmer Vernooij
Run autopep8.
371
                yield 'same', region_ia, region_len + region_ia
1185.24.1 by Aaron Bentley
Got reprocessing working
372
                next_a = region_ia + region_len
373
                next_b = region_ib + region_len
374
            reg = self.mismatch_region(next_a, amatch, next_b, bmatch)
375
            if reg is not None:
376
                yield reg
377
378
    @staticmethod
7143.15.2 by Jelmer Vernooij
Run autopep8.
379
    def mismatch_region(next_a, region_ia, next_b, region_ib):
1185.24.1 by Aaron Bentley
Got reprocessing working
380
        if next_a < region_ia or next_b < region_ib:
381
            return 'conflict', None, None, next_a, region_ia, next_b, region_ib
382
822 by Martin Pool
- Renamed merge3 test suite for easier access.
383
    def find_sync_regions(self):
384
        """Return a list of sync regions, where both descendents match the base.
385
825 by Martin Pool
- Merge3.find_sync_regions always returns a zero-length sentinal at the end to
386
        Generates a list of (base1, base2, a1, a2, b1, b2).  There is
387
        always a zero-length sync region at the end of all the files.
821 by Martin Pool
- start code for built-in diff3-style resolve
388
        """
838 by Martin Pool
- Merge3.find_sync_regions() - avoid problems with iters on python2.3 by
389
390
        ia = ib = 0
5184.1.1 by Vincent Ladeuil
Random cleanups to catch up with copyright updates in trunk.
391
        amatches = patiencediff.PatienceSequenceMatcher(
7143.15.2 by Jelmer Vernooij
Run autopep8.
392
            None, self.base, self.a).get_matching_blocks()
5184.1.1 by Vincent Ladeuil
Random cleanups to catch up with copyright updates in trunk.
393
        bmatches = patiencediff.PatienceSequenceMatcher(
7143.15.2 by Jelmer Vernooij
Run autopep8.
394
            None, self.base, self.b).get_matching_blocks()
838 by Martin Pool
- Merge3.find_sync_regions() - avoid problems with iters on python2.3 by
395
        len_a = len(amatches)
396
        len_b = len(bmatches)
397
398
        sl = []
399
400
        while ia < len_a and ib < len_b:
401
            abase, amatch, alen = amatches[ia]
402
            bbase, bmatch, blen = bmatches[ib]
403
822 by Martin Pool
- Renamed merge3 test suite for easier access.
404
            # there is an unconflicted block at i; how long does it
405
            # extend?  until whichever one ends earlier.
7143.15.2 by Jelmer Vernooij
Run autopep8.
406
            i = intersect((abase, abase + alen), (bbase, bbase + blen))
822 by Martin Pool
- Renamed merge3 test suite for easier access.
407
            if i:
408
                intbase = i[0]
409
                intend = i[1]
410
                intlen = intend - intbase
3376.2.9 by Martin Pool
Restore some assertions as comments
411
412
                # found a match of base[i[0], i[1]]; this may be less than
413
                # the region that matches in either one
414
                # assert intlen <= alen
415
                # assert intlen <= blen
416
                # assert abase <= intbase
417
                # assert bbase <= intbase
418
822 by Martin Pool
- Renamed merge3 test suite for easier access.
419
                asub = amatch + (intbase - abase)
420
                bsub = bmatch + (intbase - bbase)
421
                aend = asub + intlen
422
                bend = bsub + intlen
3376.2.9 by Martin Pool
Restore some assertions as comments
423
424
                # assert self.base[intbase:intend] == self.a[asub:aend], \
425
                #       (self.base[intbase:intend], self.a[asub:aend])
426
                # assert self.base[intbase:intend] == self.b[bsub:bend]
427
838 by Martin Pool
- Merge3.find_sync_regions() - avoid problems with iters on python2.3 by
428
                sl.append((intbase, intend,
429
                           asub, aend,
430
                           bsub, bend))
822 by Martin Pool
- Renamed merge3 test suite for easier access.
431
            # advance whichever one ends first in the base text
432
            if (abase + alen) < (bbase + blen):
838 by Martin Pool
- Merge3.find_sync_regions() - avoid problems with iters on python2.3 by
433
                ia += 1
822 by Martin Pool
- Renamed merge3 test suite for easier access.
434
            else:
838 by Martin Pool
- Merge3.find_sync_regions() - avoid problems with iters on python2.3 by
435
                ib += 1
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
436
825 by Martin Pool
- Merge3.find_sync_regions always returns a zero-length sentinal at the end to
437
        intbase = len(self.base)
438
        abase = len(self.a)
439
        bbase = len(self.b)
838 by Martin Pool
- Merge3.find_sync_regions() - avoid problems with iters on python2.3 by
440
        sl.append((intbase, intbase, abase, abase, bbase, bbase))
441
442
        return sl
825 by Martin Pool
- Merge3.find_sync_regions always returns a zero-length sentinal at the end to
443
821 by Martin Pool
- start code for built-in diff3-style resolve
444
    def find_unconflicted(self):
445
        """Return a list of ranges in base that are not conflicted."""
5184.1.1 by Vincent Ladeuil
Random cleanups to catch up with copyright updates in trunk.
446
        am = patiencediff.PatienceSequenceMatcher(
7143.15.2 by Jelmer Vernooij
Run autopep8.
447
            None, self.base, self.a).get_matching_blocks()
5184.1.1 by Vincent Ladeuil
Random cleanups to catch up with copyright updates in trunk.
448
        bm = patiencediff.PatienceSequenceMatcher(
7143.15.2 by Jelmer Vernooij
Run autopep8.
449
            None, self.base, self.b).get_matching_blocks()
821 by Martin Pool
- start code for built-in diff3-style resolve
450
451
        unc = []
452
453
        while am and bm:
454
            # there is an unconflicted block at i; how long does it
455
            # extend?  until whichever one ends earlier.
456
            a1 = am[0][0]
457
            a2 = a1 + am[0][2]
458
            b1 = bm[0][0]
459
            b2 = b1 + bm[0][2]
460
            i = intersect((a1, a2), (b1, b2))
461
            if i:
462
                unc.append(i)
463
464
            if a2 < b2:
465
                del am[0]
466
            else:
467
                del bm[0]
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
468
821 by Martin Pool
- start code for built-in diff3-style resolve
469
        return unc
829 by Martin Pool
- More merge3 cvs-form stuff
470
471
472
def main(argv):
830 by Martin Pool
- handle chunks which differ from the base but agree
473
    # as for diff3 and meld the syntax is "MINE BASE OTHER"
6973.7.5 by Jelmer Vernooij
s/file/open.
474
    with open(argv[1], 'rt') as f:
475
        a = f.readlines()
476
    with open(argv[2], 'rt') as f:
477
        base = f.readlines()
478
    with open(argv[3], 'rt') as f:
479
        b = f.readlines()
829 by Martin Pool
- More merge3 cvs-form stuff
480
481
    m3 = Merge3(base, a, b)
482
7143.15.2 by Jelmer Vernooij
Run autopep8.
483
    # for sr in m3.find_sync_regions():
838 by Martin Pool
- Merge3.find_sync_regions() - avoid problems with iters on python2.3 by
484
    #    print sr
485
832 by Martin Pool
- New Merge3.merge_annotated method for debugging.
486
    # sys.stdout.writelines(m3.merge_lines(name_a=argv[1], name_b=argv[3]))
487
    sys.stdout.writelines(m3.merge_annotated())
829 by Martin Pool
- More merge3 cvs-form stuff
488
489
490
if __name__ == '__main__':
491
    import sys
492
    sys.exit(main(sys.argv))