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