jsdiff
jsdiff copied to clipboard
Unexpected diffLines result on a basic example
import * as Diff from 'diff'
const diff = Diff.diffLines('a\nb\nc', 'a\nb', { newlineIsToken: false })
console.log(diff)
yields:
[ { count: 1, value: 'a\n' },
{ count: 2, added: undefined, removed: true, value: 'b\nc' },
{ count: 1, added: true, removed: undefined, value: 'b' } ]
[ { count: 1, value: 'a\n' },
{ count: 2, added: undefined, removed: true, value: 'b\nc' },
{ count: 1, added: true, removed: undefined, value: 'b' } ]
I need to add a trailing \n to get the expected, simpler result.
import * as Diff from 'diff'
const diff = Diff.diffLines('a\nb\nc\n', 'a\nb\n', { newlineIsToken: false })
console.log(diff)
[ { count: 2, value: 'a\nb\n' },
{ count: 1, added: undefined, removed: true, value: 'c\n' } ]
Interesting. https://github.com/kpdecker/jsdiff/issues/254 was about the same behaviour in the context of jsdiff's patch-generation functions, and I closed it saying the behaviour is correct. I think I agree with myself with regards to patches. When it comes to change objects as returned from diffLines, though, I'm less certain, but still inclined towards the same answer - that this is how things should work. (Though I should probably note it in the docs.)
How do you reckon things ought to behave, here? It would be weird if your first example returned literally the exact same result as your second one since then it'd be adding in an extra \n character after the c that wasn't there in the original text.
The line with a "b" does not change : the newline character is a separator and should be treated at such when using diffLines.
So that second line should not be marked as being removed.
A computer doesn't care so it's not an issue if you generate patches.
But diffLines is probably targeted at humans, and as a human I don't like this 🙂.
Thinking about it, I figure it'd make sense to add an ignoreNewlineAtEof option for this. But I don't want to add that until https://github.com/kpdecker/jsdiff/pull/219 is fixed.