~ubuntu-branches/ubuntu/natty/moin/natty-updates

« back to all changes in this revision

Viewing changes to MoinMoin/util/diff3.py

  • Committer: Bazaar Package Importer
  • Author(s): Jonas Smedegaard
  • Date: 2008-06-22 21:17:13 UTC
  • mfrom: (0.9.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20080622211713-fpo2zrq3s5dfecxg
Tags: 1.7.0-3
Simplify /etc/moin/wikilist format: "USER URL" (drop unneeded middle
CONFIG_DIR that was wrongly advertised as DATA_DIR).  Make
moin-mass-migrate handle both formats and warn about deprecation of
the old one.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# -*- coding: iso-8859-1 -*-
2
2
"""
3
3
    MoinMoin - diff3 algorithm
4
 
    
5
 
    @copyright: 2002 by Florian Festi
 
4
 
 
5
    @copyright: 2002 Florian Festi
6
6
    @license: GNU GPL, see COPYING for details.
7
7
"""
8
8
 
9
 
def text_merge(old, other, new, allow_conflicts=1,
10
 
               marker1='<<<<<<<<<<<<<<<<<<<<<<<<<\n',
11
 
               marker2='=========================\n',
12
 
               marker3='>>>>>>>>>>>>>>>>>>>>>>>>>\n'):
 
9
default_markers = ('<<<<<<<<<<<<<<<<<<<<<<<<<\n',
 
10
                   '=========================\n',
 
11
                   '>>>>>>>>>>>>>>>>>>>>>>>>>\n')
 
12
 
 
13
def text_merge(old, other, new, allow_conflicts=1, *markers):
13
14
    """ do line by line diff3 merge with three strings """
14
15
    result = merge(old.splitlines(1), other.splitlines(1), new.splitlines(1),
15
 
                   allow_conflicts, marker1, marker2, marker3)
 
16
                   allow_conflicts, *markers)
16
17
    return ''.join(result)
17
18
 
18
 
def merge(old, other, new, allow_conflicts=1,
19
 
          marker1='<<<<<<<<<<<<<<<<<<<<<<<<<\n',
20
 
          marker2='=========================\n',
21
 
          marker3='>>>>>>>>>>>>>>>>>>>>>>>>>\n'):
 
19
def merge(old, other, new, allow_conflicts=1, *markers):
22
20
    """ do line by line diff3 merge
23
 
        input must be lists containing single lines   
 
21
        input must be lists containing single lines
24
22
    """
 
23
    if not markers:
 
24
        markers = default_markers
 
25
    marker1, marker2, marker3 = markers
 
26
 
25
27
    old_nr, other_nr, new_nr = 0, 0, 0
26
28
    old_len, other_len, new_len = len(old), len(other), len(new)
27
29
    result = []
28
 
    while old_nr < old_len and other_nr < other_len  and new_nr < new_len:
 
30
 
 
31
    while old_nr < old_len and other_nr < other_len and new_nr < new_len:
29
32
        # unchanged
30
33
        if old[old_nr] == other[other_nr] == new[new_nr]:
31
34
            result.append(old[old_nr])
33
36
            other_nr += 1
34
37
            new_nr += 1
35
38
        else:
 
39
            if allow_conflicts == 2: # experimental addition to the algorithm
 
40
                if other[other_nr] == new[new_nr]:
 
41
                    result.append(new[new_nr])
 
42
                    other_nr += 1
 
43
                    new_nr += 1
 
44
                    continue
36
45
            new_match = find_match(old, new, old_nr, new_nr)
37
46
            other_match = find_match(old, other, old_nr, other_nr)
38
47
            # new is changed
82
91
 
83
92
    # process tail
84
93
    # all finished
85
 
    if old_nr == old_len and other_nr == other_len  and new_nr == new_len:
 
94
    if old_nr == old_len and other_nr == other_len and new_nr == new_len:
86
95
        pass
87
96
    # new added lines
88
97
    elif old_nr == old_len and other_nr == other_len:
89
98
        result.extend(new[new_nr:])
90
99
    # other added lines
91
100
    elif old_nr == old_len and new_nr == new_len:
92
 
        result.extend(other[other_nr])
 
101
        result.extend(other[other_nr:])
93
102
    # new deleted lines
94
103
    elif (new_nr == new_len and (old_len - old_nr == other_len - other_nr) and
95
104
          match(old, other, old_nr, other_nr, old_len-old_nr) == old_len - old_nr):
100
109
        pass
101
110
    # conflict
102
111
    else:
103
 
        if not allow_conflicts:
104
 
            return None
105
 
        result.append(marker1)
106
 
        result.extend(other[other_nr:])
107
 
        result.append(marker2)
108
 
        result.extend(new[new_nr:])
109
 
        result.append(marker3)
 
112
        if new == other:
 
113
            result.extend(new[new_nr:])
 
114
        else:
 
115
            if not allow_conflicts:
 
116
                return None
 
117
            result.append(marker1)
 
118
            result.extend(other[other_nr:])
 
119
            result.append(marker2)
 
120
            result.extend(new[new_nr:])
 
121
            result.append(marker3)
110
122
    return result
111
123
 
112
124
def tripple_match(old, other, new, other_match, new_match):
122
134
            if match_len == difference:
123
135
                return (new_match[0], other_match[1]+difference, new_match[1])
124
136
            else:
125
 
                other_match =  find_match(old, other,
126
 
                                          other_match[0] + match_len,
127
 
                                          other_match[1] + match_len)
 
137
                other_match = find_match(old, other,
 
138
                                         other_match[0] + match_len,
 
139
                                         other_match[1] + match_len)
128
140
        # other changed more lines
129
141
        elif difference < 0:
130
142
            difference = -difference
134
146
                return (other_match[0], other_match[1],
135
147
                        new_match[0] + difference)
136
148
            else:
137
 
                new_match =  find_match(old, new,
138
 
                                        new_match[0] + match_len,
139
 
                                        new_match[1] + match_len)
 
149
                new_match = find_match(old, new,
 
150
                                       new_match[0] + match_len,
 
151
                                       new_match[1] + match_len)
140
152
        # both conflicts change same number of lines
141
153
        # or no match till the end
142
154
        else:
143
155
            return (new_match[0], other_match[1], new_match[1])
144
 
        
 
156
 
145
157
def match(list1, list2, nr1, nr2, maxcount=3):
146
158
    """ return the number matching items after the given positions
147
 
        maximum maxcount lines are are processed 
 
159
        maximum maxcount lines are are processed
148
160
    """
149
161
    i = 0
150
162
    len1 = len(list1)
176
188
                hit1 = (i, idx2)
177
189
                break
178
190
            i += 1
179
 
            
 
191
 
180
192
        i = nr2
181
193
        while i < idx2:
182
 
            hit_count = match(list1, list2, idx1, i, mincount) 
 
194
            hit_count = match(list1, list2, idx1, i, mincount)
183
195
            if hit_count >= mincount:
184
196
                hit2 = (idx1, i)
185
197
                break
255
267
 
256
268
if __name__ == '__main__':
257
269
    main()
258