75 @return a generator yielding lines of differences |
75 @return a generator yielding lines of differences |
76 """ |
76 """ |
77 started = False |
77 started = False |
78 for group in SequenceMatcher(None,a,b).get_grouped_opcodes(n): |
78 for group in SequenceMatcher(None,a,b).get_grouped_opcodes(n): |
79 if not started: |
79 if not started: |
80 yield '--- %s\t%s%s' % (fromfile, fromfiledate, lineterm) |
80 yield '--- {0}\t{1}{2}'.format(fromfile, fromfiledate, lineterm) |
81 yield '+++ %s\t%s%s' % (tofile, tofiledate, lineterm) |
81 yield '+++ {0}\t{1}{2}'.format(tofile, tofiledate, lineterm) |
82 started = True |
82 started = True |
83 i1, i2, j1, j2 = group[0][1], group[-1][2], group[0][3], group[-1][4] |
83 i1, i2, j1, j2 = group[0][1], group[-1][2], group[0][3], group[-1][4] |
84 yield "@@ -%d,%d +%d,%d @@%s" % (i1+1, i2-i1, j1+1, j2-j1, lineterm) |
84 yield "@@ -{0:d},{1:d} +{2:d},{3:d} @@{4}".format( |
|
85 i1+1, i2-i1, j1+1, j2-j1, lineterm) |
85 for tag, i1, i2, j1, j2 in group: |
86 for tag, i1, i2, j1, j2 in group: |
86 if tag == 'equal': |
87 if tag == 'equal': |
87 for line in a[i1:i2]: |
88 for line in a[i1:i2]: |
88 yield ' ' + line |
89 yield ' ' + line |
89 continue |
90 continue |
154 |
155 |
155 started = False |
156 started = False |
156 prefixmap = {'insert':'+ ', 'delete':'- ', 'replace':'! ', 'equal':' '} |
157 prefixmap = {'insert':'+ ', 'delete':'- ', 'replace':'! ', 'equal':' '} |
157 for group in SequenceMatcher(None,a,b).get_grouped_opcodes(n): |
158 for group in SequenceMatcher(None,a,b).get_grouped_opcodes(n): |
158 if not started: |
159 if not started: |
159 yield '*** %s\t%s%s' % (fromfile, fromfiledate, lineterm) |
160 yield '*** {0}\t{1}{2}'.format(fromfile, fromfiledate, lineterm) |
160 yield '--- %s\t%s%s' % (tofile, tofiledate, lineterm) |
161 yield '--- {0}\t{1}{2}'.format(tofile, tofiledate, lineterm) |
161 started = True |
162 started = True |
162 |
163 |
163 yield '***************%s' % (lineterm,) |
164 yield '***************{0}'.format(lineterm) |
164 if group[-1][2] - group[0][1] >= 2: |
165 if group[-1][2] - group[0][1] >= 2: |
165 yield '*** %d,%d ****%s' % (group[0][1]+1, group[-1][2], lineterm) |
166 yield '*** {0:d},{1:d} ****{2}'.format(group[0][1]+1, group[-1][2], lineterm) |
166 else: |
167 else: |
167 yield '*** %d ****%s' % (group[-1][2], lineterm) |
168 yield '*** {0:d} ****{1}'.format(group[-1][2], lineterm) |
168 visiblechanges = [e for e in group if e[0] in ('replace', 'delete')] |
169 visiblechanges = [e for e in group if e[0] in ('replace', 'delete')] |
169 if visiblechanges: |
170 if visiblechanges: |
170 for tag, i1, i2, _, _ in group: |
171 for tag, i1, i2, _, _ in group: |
171 if tag != 'insert': |
172 if tag != 'insert': |
172 for line in a[i1:i2]: |
173 for line in a[i1:i2]: |
173 yield prefixmap[tag] + line |
174 yield prefixmap[tag] + line |
174 |
175 |
175 if group[-1][4] - group[0][3] >= 2: |
176 if group[-1][4] - group[0][3] >= 2: |
176 yield '--- %d,%d ----%s' % (group[0][3]+1, group[-1][4], lineterm) |
177 yield '--- {0:d},{1:d} ----{2}'.format(group[0][3]+1, group[-1][4], lineterm) |
177 else: |
178 else: |
178 yield '--- %d ----%s' % (group[-1][4], lineterm) |
179 yield '--- {0:d} ----{1}'.format(group[-1][4], lineterm) |
179 visiblechanges = [e for e in group if e[0] in ('replace', 'insert')] |
180 visiblechanges = [e for e in group if e[0] in ('replace', 'insert')] |
180 if visiblechanges: |
181 if visiblechanges: |
181 for tag, _, _, j1, j2 in group: |
182 for tag, _, _, j1, j2 in group: |
182 if tag != 'delete': |
183 if tag != 'delete': |
183 for line in b[j1:j2]: |
184 for line in b[j1:j2]: |