kpdecker / jsdiff

A javascript text differencing implementation.
BSD 3-Clause "New" or "Revised" License
7.75k stars 491 forks source link

applyPatch with a `fuzzFactor` will happily delete an entirely different line to the one shown in the diff #468

Closed ExplodingCabbage closed 1 week ago

ExplodingCabbage commented 6 months ago

Surely these behaviours can't be intended?

> text1 = 'foo\nbar\nbaz\nqux\n'
'foo\nbar\nbaz\nqux\n'
> text2 = 'foo\nbaz\nqux\n'
'foo\nbaz\nqux\n'
> patch = diff.createPatch('foo.txt', text1, text2)
'Index: foo.txt\n' +
  '===================================================================\n' +
  '--- foo.txt\n' +
  '+++ foo.txt\n' +
  '@@ -1,4 +1,3 @@\n' +
  ' foo\n' +
  '-bar\n' +
  ' baz\n' +
  ' qux\n'
> diff.applyPatch('foo\nSOMETHING ENTIRELY DIFFERENT\nbaz\nqux\n', patch, {fuzzFactor: 1})
'foo\nbaz\nqux\n'
> diff.applyPatch(text2, patch, {fuzzFactor: 3})
'foo\nqux\n'

Git and GNU patch would both never do this (even with patch --fuzz 99999999999999). It seems straightforwardly wrong to me that a patch line that says -bar could ever delete a line whose content is anything other than bar.

ExplodingCabbage commented 6 months ago

As part of fixing this issue, we should document exactly how fuzzFactor works in the README.