comparison mercurial/mdiff.py @ 15525:935bf2e7dbc5

mdiff: extract blocks whitespace normalization in diffblocks() We want to reuse it in annotate for whitespace normalization.
author Patrick Mezard <pmezard@gmail.com>
date Fri, 18 Nov 2011 11:53:38 +0100
parents 646759147717
children e6519c628454
comparison
equal deleted inserted replaced
15524:e7119b091809 15525:935bf2e7dbc5
72 text = re.sub('[ \t\r]+', ' ', text) 72 text = re.sub('[ \t\r]+', ' ', text)
73 text = text.replace(' \n', '\n') 73 text = text.replace(' \n', '\n')
74 if blank and opts.ignoreblanklines: 74 if blank and opts.ignoreblanklines:
75 text = re.sub('\n+', '\n', text).strip('\n') 75 text = re.sub('\n+', '\n', text).strip('\n')
76 return text 76 return text
77
78 def diffblocks(text1, text2, opts=None, lines1=None, lines2=None):
79 """Return changed blocks between text1 and text2, the blocks in-between
80 those emitted by bdiff.blocks. Take in account the whitespace normalization
81 rules defined by opts.
82 line1 and line2 are text1 and text2 split with splitnewlines() if they are
83 already available.
84 """
85 if opts is None:
86 opts = defaultopts
87 if lines1 is None:
88 lines1 = splitnewlines(text1)
89 if lines2 is None:
90 lines2 = splitnewlines(text2)
91 if opts.ignorews or opts.ignorewsamount:
92 text1 = wsclean(opts, text1, False)
93 text2 = wsclean(opts, text2, False)
94 diff = bdiff.blocks(text1, text2)
95 for i, s1 in enumerate(diff):
96 # The first match is special.
97 # we've either found a match starting at line 0 or a match later
98 # in the file. If it starts later, old and new below will both be
99 # empty and we'll continue to the next match.
100 if i > 0:
101 s = diff[i - 1]
102 else:
103 s = [0, 0, 0, 0]
104 s = [s[1], s1[0], s[3], s1[2]]
105 old = lines1[s[0]:s[1]]
106 new = lines2[s[2]:s[3]]
107
108 # bdiff sometimes gives huge matches past eof, this check eats them,
109 # and deals with the special first match case described above
110 if not old and not new:
111 continue
112
113 if opts.ignoreblanklines:
114 if wsclean(opts, "".join(old)) == wsclean(opts, "".join(new)):
115 continue
116 yield s
77 117
78 def diffline(revs, a, b, opts): 118 def diffline(revs, a, b, opts):
79 parts = ['diff'] 119 parts = ['diff']
80 if opts.git: 120 if opts.git:
81 parts.append('--git') 121 parts.append('--git')
198 238
199 # bdiff.blocks gives us the matching sequences in the files. The loop 239 # bdiff.blocks gives us the matching sequences in the files. The loop
200 # below finds the spaces between those matching sequences and translates 240 # below finds the spaces between those matching sequences and translates
201 # them into diff output. 241 # them into diff output.
202 # 242 #
203 if opts.ignorews or opts.ignorewsamount:
204 t1 = wsclean(opts, t1, False)
205 t2 = wsclean(opts, t2, False)
206
207 diff = bdiff.blocks(t1, t2)
208 hunk = None 243 hunk = None
209 for i, s1 in enumerate(diff): 244 for s in diffblocks(t1, t2, opts, l1, l2):
210 # The first match is special.
211 # we've either found a match starting at line 0 or a match later
212 # in the file. If it starts later, old and new below will both be
213 # empty and we'll continue to the next match.
214 if i > 0:
215 s = diff[i - 1]
216 else:
217 s = [0, 0, 0, 0]
218 delta = [] 245 delta = []
219 a1 = s[1] 246 a1, a2, b1, b2 = s
220 a2 = s1[0]
221 b1 = s[3]
222 b2 = s1[2]
223
224 old = l1[a1:a2] 247 old = l1[a1:a2]
225 new = l2[b1:b2] 248 new = l2[b1:b2]
226
227 # bdiff sometimes gives huge matches past eof, this check eats them,
228 # and deals with the special first match case described above
229 if not old and not new:
230 continue
231
232 if opts.ignoreblanklines:
233 if wsclean(opts, "".join(old)) == wsclean(opts, "".join(new)):
234 continue
235 249
236 astart = contextstart(a1) 250 astart = contextstart(a1)
237 bstart = contextstart(b1) 251 bstart = contextstart(b1)
238 prev = None 252 prev = None
239 if hunk: 253 if hunk: