/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
821 by Martin Pool
- start code for built-in diff3-style resolve
1
# Copyright (C) 2004, 2005 by Canonical Ltd
2
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.
7
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.
12
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
15
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
16
17
18
19
def intersect(ra, rb):
20
    """Given two ranges return the range where they intersect or None.
21
22
    >>> intersect((0, 10), (0, 6))
23
    (0, 6)
24
    >>> intersect((0, 10), (5, 15))
25
    (5, 10)
26
    >>> intersect((0, 10), (10, 15))
27
    >>> intersect((0, 9), (10, 15))
28
    >>> intersect((0, 9), (7, 15))
29
    (7, 9)
30
    """
31
    assert ra[0] <= ra[1]
32
    assert rb[0] <= rb[1]
33
    
34
    sa = max(ra[0], rb[0])
35
    sb = min(ra[1], rb[1])
36
    if sa < sb:
37
        return sa, sb
38
    else:
39
        return None
40
41
42
class Merge3(object):
43
    """3-way merge of texts.
44
45
    Given BASE, OTHER, THIS, tries to produce a combined text
46
    incorporating the changes from both BASE->OTHER and BASE->THIS.
47
    All three will typically be sequences of lines."""
48
    def __init__(self, base, a, b):
49
        self.base = base
50
        self.a = a
51
        self.b = b
52
53
        #from difflib import SequenceMatcher
54
55
        #self.a_ops = SequenceMatcher(None, self.base, self.a).get_opcodes()
56
        #self.b_ops = SequenceMatcher(None, self.base, self.b).get_opcodes()
57
58
        
59
    def find_conflicts(self):
60
        """Return a list of conflict regions.
61
62
        Each entry is given as (base1, base2, a1, a2, b1, b2).
63
64
        This indicates that the range [base1,base2] can be replaced by either
65
        [a1,a2] or [b1,b2].
66
        """
67
68
69
    def find_unconflicted(self):
70
        """Return a list of ranges in base that are not conflicted."""
71
        from difflib import SequenceMatcher
72
        am = SequenceMatcher(None, self.base, self.a).get_matching_blocks()
73
        bm = SequenceMatcher(None, self.base, self.b).get_matching_blocks()
74
75
        unc = []
76
77
        while am and bm:
78
            # there is an unconflicted block at i; how long does it
79
            # extend?  until whichever one ends earlier.
80
            a1 = am[0][0]
81
            a2 = a1 + am[0][2]
82
            b1 = bm[0][0]
83
            b2 = b1 + bm[0][2]
84
            i = intersect((a1, a2), (b1, b2))
85
            if i:
86
                unc.append(i)
87
88
            if a2 < b2:
89
                del am[0]
90
            else:
91
                del bm[0]
92
                
93
        return unc