comparison mercurial/mdiff.py @ 36676:c6a61298ac32

mdiff: add a config option to use xdiff algorithm The `experimental.xdiff` will affect the default diffopts and make mdiff use the xdiff algorithm for better diff quality. Differential Revision: https://phab.mercurial-scm.org/D2603
author Jun Wu <quark@fb.com>
date Sat, 03 Mar 2018 12:39:14 -0800
parents 68026dd7c4f9
children b6de372b4309
comparison
equal deleted inserted replaced
36675:430fdb717549 36676:c6a61298ac32
61 'ignorewseol': False, 61 'ignorewseol': False,
62 'ignoreblanklines': False, 62 'ignoreblanklines': False,
63 'upgrade': False, 63 'upgrade': False,
64 'showsimilarity': False, 64 'showsimilarity': False,
65 'worddiff': False, 65 'worddiff': False,
66 'xdiff': False,
66 } 67 }
67 68
68 def __init__(self, **opts): 69 def __init__(self, **opts):
69 opts = pycompat.byteskwargs(opts) 70 opts = pycompat.byteskwargs(opts)
70 for k in self.defaults.keys(): 71 for k in self.defaults.keys():
186 filteredblocks.append(block) 187 filteredblocks.append(block)
187 if lba is None or uba is None or uba < lba: 188 if lba is None or uba is None or uba < lba:
188 raise error.Abort(_('line range exceeds file size')) 189 raise error.Abort(_('line range exceeds file size'))
189 return filteredblocks, (lba, uba) 190 return filteredblocks, (lba, uba)
190 191
192 def chooseblocksfunc(opts=None):
193 if (opts is None or not opts.xdiff
194 or not util.safehasattr(bdiff, 'xdiffblocks')):
195 return bdiff.blocks
196 else:
197 return bdiff.xdiffblocks
198
191 def allblocks(text1, text2, opts=None, lines1=None, lines2=None): 199 def allblocks(text1, text2, opts=None, lines1=None, lines2=None):
192 """Return (block, type) tuples, where block is an mdiff.blocks 200 """Return (block, type) tuples, where block is an mdiff.blocks
193 line entry. type is '=' for blocks matching exactly one another 201 line entry. type is '=' for blocks matching exactly one another
194 (bdiff blocks), '!' for non-matching blocks and '~' for blocks 202 (bdiff blocks), '!' for non-matching blocks and '~' for blocks
195 matching only after having filtered blank lines. 203 matching only after having filtered blank lines.
199 if opts is None: 207 if opts is None:
200 opts = defaultopts 208 opts = defaultopts
201 if opts.ignorews or opts.ignorewsamount or opts.ignorewseol: 209 if opts.ignorews or opts.ignorewsamount or opts.ignorewseol:
202 text1 = wsclean(opts, text1, False) 210 text1 = wsclean(opts, text1, False)
203 text2 = wsclean(opts, text2, False) 211 text2 = wsclean(opts, text2, False)
204 diff = bdiff.blocks(text1, text2) 212 diff = chooseblocksfunc(opts)(text1, text2)
205 for i, s1 in enumerate(diff): 213 for i, s1 in enumerate(diff):
206 # The first match is special. 214 # The first match is special.
207 # we've either found a match starting at line 0 or a match later 215 # we've either found a match starting at line 0 or a match later
208 # in the file. If it starts later, old and new below will both be 216 # in the file. If it starts later, old and new below will both be
209 # empty and we'll continue to the next match. 217 # empty and we'll continue to the next match.