Mercurial > public > mercurial-scm > hg
comparison mercurial/mdiff.py @ 9827:4fe9ca519637
mdiff: fix diff -b/B/w on mixed whitespace hunks (issue127)
Previous code was computing hunks then checking if these hunks could be ignored
when taking whitespace/blank-lines options in accounts. This approach is simple
but fails with hunks containing both whitespace and non-whitespace changes, the
whole hunk is emitted while it can be mostly made of whitespace. The new
version normalize the whitespaces before hunk generation, and test for
blank-lines afterwards.
author | Patrick Mezard <pmezard@gmail.com> |
---|---|
date | Wed, 11 Nov 2009 18:31:42 +0100 |
parents | 9e055cfdd620 |
children | 7637fe4f525d |
comparison
equal
deleted
inserted
replaced
9826:d768614578dd | 9827:4fe9ca519637 |
---|---|
55 raise util.Abort(_('diff context lines count must be ' | 55 raise util.Abort(_('diff context lines count must be ' |
56 'an integer, not %r') % self.context) | 56 'an integer, not %r') % self.context) |
57 | 57 |
58 defaultopts = diffopts() | 58 defaultopts = diffopts() |
59 | 59 |
60 def wsclean(opts, text): | 60 def wsclean(opts, text, blank=True): |
61 if opts.ignorews: | 61 if opts.ignorews: |
62 text = re.sub('[ \t]+', '', text) | 62 text = re.sub('[ \t]+', '', text) |
63 elif opts.ignorewsamount: | 63 elif opts.ignorewsamount: |
64 text = re.sub('[ \t]+', ' ', text) | 64 text = re.sub('[ \t]+', ' ', text) |
65 text = re.sub('[ \t]+\n', '\n', text) | 65 text = re.sub('[ \t]+\n', '\n', text) |
66 if opts.ignoreblanklines: | 66 if blank and opts.ignoreblanklines: |
67 text = re.sub('\n+', '', text) | 67 text = re.sub('\n+', '', text) |
68 return text | 68 return text |
69 | 69 |
70 def diffline(revs, a, b, opts): | 70 def diffline(revs, a, b, opts): |
71 parts = ['diff'] | 71 parts = ['diff'] |
181 | 181 |
182 # bdiff.blocks gives us the matching sequences in the files. The loop | 182 # bdiff.blocks gives us the matching sequences in the files. The loop |
183 # below finds the spaces between those matching sequences and translates | 183 # below finds the spaces between those matching sequences and translates |
184 # them into diff output. | 184 # them into diff output. |
185 # | 185 # |
186 if opts.ignorews or opts.ignorewsamount: | |
187 t1 = wsclean(opts, t1, False) | |
188 t2 = wsclean(opts, t2, False) | |
189 | |
186 diff = bdiff.blocks(t1, t2) | 190 diff = bdiff.blocks(t1, t2) |
187 hunk = None | 191 hunk = None |
188 for i, s1 in enumerate(diff): | 192 for i, s1 in enumerate(diff): |
189 # The first match is special. | 193 # The first match is special. |
190 # we've either found a match starting at line 0 or a match later | 194 # we've either found a match starting at line 0 or a match later |
206 # bdiff sometimes gives huge matches past eof, this check eats them, | 210 # bdiff sometimes gives huge matches past eof, this check eats them, |
207 # and deals with the special first match case described above | 211 # and deals with the special first match case described above |
208 if not old and not new: | 212 if not old and not new: |
209 continue | 213 continue |
210 | 214 |
211 if opts.ignorews or opts.ignorewsamount or opts.ignoreblanklines: | 215 if opts.ignoreblanklines: |
212 if wsclean(opts, "".join(old)) == wsclean(opts, "".join(new)): | 216 if wsclean(opts, "".join(old)) == wsclean(opts, "".join(new)): |
213 continue | 217 continue |
214 | 218 |
215 astart = contextstart(a1) | 219 astart = contextstart(a1) |
216 bstart = contextstart(b1) | 220 bstart = contextstart(b1) |