35 KiB
Release Notes
8.0.2
- #616 Restored compatibility of
diffSentenceswith old Safari versions. This was broken in 8.0.0 by the introduction of a regex with a lookbehind assertion; these weren't supported in Safari prior to version 16.4. - #612 Improved tree shakeability by marking the built CJS and ESM packages with
sideEffects: false.
8.0.1
- #610 Fixes types for
diffJsonwhich were broken by 8.0.0. The new bundled types in 8.0.0 only alloweddiffJsonto be passed string arguments, but it should've been possible to pass either strings or objects (and now is). Thanks to Josh Kelley for the fix.
8.0.0
- #580 Multiple tweaks to
diffSentences:- tokenization no longer takes quadratic time on pathological inputs (reported as a ReDOS vulnerability by Snyk); is now linear instead
- the final sentence in the string is now handled the same by the tokenizer regardless of whether it has a trailing punctuation mark or not. (Previously, "foo. bar." tokenized to
["foo.", " ", "bar."]but "foo. bar" tokenized to["foo.", " bar"]- i.e. whether the space between sentences was treated as a separate token depended upon whether the final sentence had trailing punctuation or not. This was arbitrary and surprising; it is no longer the case.) - in a string that starts with a sentence end, like "! hello.", the "!" is now treated as a separate sentence
- the README now correctly documents the tokenization behaviour (it was wrong before)
- #581 - fixed some regex operations used for tokenization in
diffWordstaking O(n^2) time in pathological cases - #595 - fixed a crash in patch creation functions when handling a single hunk consisting of a very large number (e.g. >130k) of lines. (This was caused by spreading indefinitely-large arrays to
.push()using.applyor the spread operator and hitting the JS-implementation-specific limit on the maximum number of arguments to a function, as shown at https://stackoverflow.com/a/56809779/1709587; thus the exact threshold to hit the error will depend on the environment in which you were running JsDiff.) - #596 - removed the
mergefunction. Previously JsDiff included an undocumented function calledmergethat was meant to, in some sense, merge patches. It had at least a couple of serious bugs that could lead to it returning unambiguously wrong results, and it was difficult to simply "fix" because it was unclear precisely what it was meant to do. For now, the fix is to remove it entirely. - #591 - JsDiff's source code has been rewritten in TypeScript. This change entails the following changes for end users:
-
the
diffpackage on npm now includes its own TypeScript type definitions. Users who previously used the@types/diffnpm package from DefinitelyTyped should remove that dependency when upgrading JsDiff to v8.Note that the transition from the DefinitelyTyped types to JsDiff's own type definitions includes multiple fixes and also removes many exported types previously used for
optionsarguments to diffing and patch-generation functions. (There are now different exported options types for abortable calls - ones with atimeoutormaxEditLengththat may give a result ofundefined- and non-abortable calls.) See the TypeScript section of the README for some usage tips. -
The
Diffobject is now a class. Custom extensions ofDiff, as described in the "Defining custom diffing behaviors" section of the README, can therefore now be done by writing aclass CustomDiff extends Diffand overriding methods, instead of the old way based on prototype inheritance. (I think code that did things the old way should still work, though!) -
diff/lib/index.es6.jsanddiff/lib/index.mjsno longer exist, and the ESM version of the library is no longer bundled into a single file. -
The
ignoreWhitespaceoption fordiffWordsis no longer included in the type declarations. The effect of passingignoreWhitespace: truehas always been to makediffWordsjust calldiffWordsWithSpaceinstead, which was confusing, because that behaviour doesn't seem properly described as "ignoring" whitespace at all. The property remains available to non-TypeScript applications for the sake of backwards compatability, but TypeScript applications will now see a type error if they try to passignoreWhitespace: truetodiffWordsand should change their code to calldiffWordsWithSpaceinstead. -
JsDiff no longer purports to support ES3 environments. (I'm pretty sure it never truly did, despite claiming to in its README, since even the 1.0.0 release used
Array.mapwhich was added in ES5.)
-
- #601 -
diffJson'sstringifyReplaceroption behaves more likeJSON.stringify'sreplacerargument now. In particular:- Each key/value pair now gets passed through the replacer once instead of twice
- The
keypassed to the replacer when the top-level object is passed in asvalueis now""(previously, wasundefined), and thekeypassed with an array element is the array index as a string, like"0"or"1"(previously was whatever the key for the entire array was). Both the new behaviours match that ofJSON.stringify.
- #602 - diffing functions now consistently return
undefinedwhen called in async mode (i.e. with a callback). Previously, there was an odd quirk where they would returntrueif the strings being diffed were equal andundefinedotherwise.
7.0.0
Just a single (breaking) bugfix, undoing a behaviour change introduced accidentally in 6.0.0:
- #554
diffWordstreats numbers and underscores as word characters again. This behaviour was broken in v6.0.0.
6.0.0
This is a release containing many, many breaking changes. The objective of this release was to carry out a mass fix, in one go, of all the open bugs and design problems that required breaking changes to fix. A substantial, but exhaustive, changelog is below.
-
#497
diffWordsbehavior has been radically changed. Previously, even withignoreWhitespace: true, runs of whitespace were tokens, which led to unhelpful and unintuitive diffing behavior in typical texts. Specifically, even when two texts contained overlapping passages,diffWordswould sometimes choose to delete all the words from the old text and insert them anew in their new positions in order to avoid having to delete or insert whitespace tokens. Whitespace sequences are no longer tokens as of this release, which affects both the generated diffs and thecounts.Runs of whitespace are still tokens in
diffWordsWithSpace.As part of the changes to
diffWords, a new.postProcessmethod has been added on the baseDifftype, which can be overridden in customDiffimplementations.diffLineswithignoreWhitespace: truewill no longer ignore the insertion or deletion of entire extra lines of whitespace at the end of the text. Previously, these would not show up as insertions or deletions, as a side effect of a hack in the base diffing algorithm meant to help ignore whitespace indiffWords. More generally, the undocumented special handling in the core algorithm for ignored terminals has been removed entirely. (This special case behavior used to rewrite the final two change objects in a scenario where the final change object was an addition or deletion and itsvaluewas treated as equal to the empty string when compared using the diff object's.equalsmethod.) -
#500
diffCharsnow diffs Unicode code points instead of UTF-16 code units. -
#508
parsePatchnow always runs in what was previously "strict" mode; the undocumentedstrictoption has been removed. Previously, by default,parsePatch(and other patch functions that use it under the hood to parse patches) would accept a patch where the line counts in the headers were inconsistent with the actual patch content - e.g. where a hunk started with the header@@ -1,3 +1,6 @@, indicating that the content below spanned 3 lines in the old file and 6 lines in the new file, but then the actual content below the header consisted of some different number of lines, say 10 lines of context, 5 deletions, and 1 insertion. Actually trying to work with these patches usingapplyPatchormerge, however, would produce incorrect results instead of just ignoring the incorrect headers, making this "feature" more of a trap than something actually useful. It's been ripped out, and now we are always "strict" and will reject patches where the line counts in the headers aren't consistent with the actual patch content. -
#435 Fix
parsePatchhandling of control characters.parsePatchused to interpret various unusual control characters - namely vertical tabs, form feeds, lone carriage returns without a line feed, and EBCDIC NELs - as line breaks when parsing a patch file. This was inconsistent with the behavior of both JsDiff's owndiffLinesmethod and also the Unixdiffandpatchutils, which all simply treat those control characters as ordinary characters. The result of this discrepancy was that some well-formed patches - produced either bydiffor by JsDiff itself and handled properly by thepatchutil - would be wrongly parsed byparsePatch, with the effect that it would disregard the remainder of a hunk after encountering one of these control characters. -
#439 Prefer diffs that order deletions before insertions. When faced with a choice between two diffs with an equal total edit distance, the Myers diff algorithm generally prefers one that does deletions before insertions rather than insertions before deletions. For instance, when diffing
abcdagainstacbd, it will prefer a diff that says to delete theband then insert a newbafter thec, over a diff that says to insert acbefore theband then delete the existingc. JsDiff deviated from the published Myers algorithm in a way that led to it having the opposite preference in many cases, including that example. This is now fixed, meaning diffs output by JsDiff will more accurately reflect what the published Myers diff algorithm would output. -
#455 The
addedandremovedproperties of change objects are now guaranteed to be set to a boolean value. (Previously, they would be set toundefinedor omitted entirely instead of setting them to false.) -
#464 Specifying
{maxEditLength: 0}now sets a max edit length of 0 instead of no maximum. -
#460 Added
oneChangePerTokenoption. -
#467 Consistent ordering of arguments to
comparator(left, right). Values from the old array will now consistently be passed as the first argument (left) and values from the new array as the second argument (right). Previously this was almost (but not quite) always the other way round. -
#480 Passing
maxEditLengthtocreatePatch&createTwoFilesPatchnow works properly (i.e. returns undefined if the max edit distance is exceeded; previous behavior was to crash with aTypeErrorif the edit distance was exceeded). -
#486 The
ignoreWhitespaceoption ofdiffLinesbehaves more sensibly now.values in returned change objects now include leading/trailing whitespace even whenignoreWhitespaceis used, just like how withignoreCasethevalues still reflect the case of one of the original texts instead of being all-lowercase.ignoreWhitespaceis also now compatible withnewlineIsToken. Finally,diffTrimmedLinesis deprecated (and removed from the docs) in favour of usingdiffLineswithignoreWhitespace: true; the two are, and always have been, equivalent. -
#490 When calling diffing functions in async mode by passing a
callbackoption, the diff result will now be passed as the first argument to the callback instead of the second. (Previously, the first argument was never used at all and would always have valueundefined.) -
#489
this.optionsno longer exists onDiffobjects. Instead,optionsis now passed as an argument to methods that rely on options, likeequals(left, right, options). This fixes a race condition in async mode, where diffing behaviour could be changed mid-execution if a concurrent usage of the sameDiffinstances overwrote itsoptions. -
#518
linedelimitersno longer exists on patch objects; instead, when a patch with Windows-style CRLF line endings is parsed, the lines inlineswill end with\r. There is now a newautoConvertLineEndingsoption, on by default, which makes it so that when a patch with Windows-style line endings is applied to a source file with Unix style line endings, the patch gets autoconverted to use Unix-style line endings, and when a patch with Unix-style line endings is applied to a source file with Windows-style line endings, it gets autoconverted to use Windows-style line endings. -
#521 the
callbackoption is now supported bystructuredPatch,createPatch, andcreateTwoFilesPatch -
#529
parsePatchcan now parse patches where lines starting with--or++are deleted/inserted; previously, there were edge cases where the parser would choke on valid patches or give wrong results. -
#530 Added
ignoreNewlineAtEofoption todiffLines -
#533
applyPatchuses an entirely new algorithm for fuzzy matching. Differences between the old and new algorithm are as follows:- The
fuzzFactornow indicates the maximum Levenshtein distance that there can be between the context shown in a hunk and the actual file content at a location where we try to apply the hunk. (Previously, it represented a maximum Hamming distance, meaning that a single insertion or deletion in the source file could stop a hunk from applying even with a highfuzzFactor.) - A hunk containing a deletion can now only be applied in a context where the line to be deleted actually appears verbatim. (Previously, as long as enough context lines in the hunk matched,
applyPatchwould apply the hunk anyway and delete a completely different line.) - The context line immediately before and immediately after an insertion must match exactly between the hunk and the file for a hunk to apply. (Previously this was not required.)
- The
-
#535 A bug in patch generation functions is now fixed that would sometimes previously cause
\ No newline at end of fileto appear in the wrong place in the generated patch, resulting in the patch being invalid. These invalid patches can also no longer be applied successfully withapplyPatch. (It was already the case that tools other than jsdiff, like GNUpatch, would consider them malformed and refuse to apply them; versions of jsdiff with this fix now do the same thing if you ask them to apply a malformed patch emitted by jsdiff v5.) -
#535 Passing
newlineIsToken: trueto patch-generation functions is no longer allowed. (Passing it todiffLinesis still supported - it's only functions likecreatePatchwhere passingnewlineIsTokenis now an error.) Allowing it to be passed never really made sense, since in cases where the option had any effect on the output at all, the effect tended to be causing a garbled patch to be created that couldn't actually be applied to the source file. -
#539
diffWordsnow takes an optionalintlSegmenteroption which should be anIntl.Segmenterwith word-level granularity. This provides better tokenization of text into words than the default behaviour, even for English but especially for some other languages for which the default behaviour is poor.
v5.2.0
- #411 Big performance improvement. Previously an O(n) array-copying operation inside the innermost loop of jsdiff's base diffing code increased the overall worst-case time complexity of computing a diff from O(n²) to O(n³). This is now fixed, bringing the worst-case time complexity down to what it theoretically should be for a Myers diff implementation.
- #448 Performance improvement. Diagonals whose furthest-reaching D-path would go off the edge of the edit graph are now skipped, rather than being pointlessly considered as called for by the original Myers diff algorithm. This dramatically speeds up computing diffs where the new text just appends or truncates content at the end of the old text.
- #351 Importing from the lib folder - e.g.
require("diff/lib/diff/word.js")- will work again now. This had been broken for users on the latest version of Node since Node 17.5.0, which changed how Node interprets theexportsproperty in jsdiff'spackage.jsonfile. - #344
diffLines,createTwoFilesPatch, and other patch-creation methods now take an optionalstripTrailingCr: trueoption which causes Windows-style\r\nline endings to be replaced with Unix-style\nline endings before calculating the diff, just like GNUdiff's--strip-trailing-crflag. - #451 Added
diff.formatPatch. - #450 Added
diff.reversePatch. - #478 Added
timeoutoption.
v5.1.0
- #365 Allow early termination to limit execution time with degenerate cases
v5.0.0
- Breaking: UMD export renamed from
JsDifftoDiff. - Breaking: Newlines separated into separate tokens for word diff.
- Breaking: Unified diffs now match "quirks"
v4.0.1 - January 6th, 2019
- Fix main reference path - b826104
v4.0.0 - January 5th, 2019
- #94 - Missing "No newline at end of file" when comparing two texts that do not end in newlines (@federicotdn)
- #227 - Licence
- #199 - Import statement for jsdiff
- #159 - applyPatch affecting wrong line number with with new lines
- #8 - A new state "replace"
- Drop ie9 from karma targets - 79c31bd
- Upgrade deps. Convert from webpack to rollup - 2c1a29c
- Make ()[]"' as word boundaries between each other - f27b899
- jsdiff: Replaced phantomJS by chrome - ec3114e
- Add yarn.lock to .npmignore - 29466d8
Compatibility notes:
- Bower and Component packages no longer supported
v3.5.0 - March 4th, 2018
- Omit redundant slice in join method of diffArrays - 1023590
- Support patches with empty lines - fb0f208
- Accept a custom JSON replacer function for JSON diffing - 69c7f0a
- Optimize parch header parser - 2aec429
- Fix typos - e89c832
v3.4.0 - October 7th, 2017
- #183 - Feature request: ability to specify a custom equality checker for
diffArrays - #173 - Bug: diffArrays gives wrong result on array of booleans
- #158 - diffArrays will not compare the empty string in array?
- comparator for custom equality checks - 30e141e
- count oldLines and newLines when there are conflicts - 53bf384
- Fix: diffArrays can compare falsey items - 9e24284
- Docs: Replace grunt with npm test - 00e2f94
v3.3.1 - September 3rd, 2017
- #141 - Cannot apply patch because my file delimiter is "/r/n" instead of "/n"
- #192 - Fix: Bad merge when adding new files (#189)
- correct spelling mistake - 21fa478
v3.3.0 - July 5th, 2017
- #114 - /patch/merge not exported
- Gracefully accept invalid newStart in hunks, same as patch(1) does. - d8a3635
- Use regex rather than starts/ends with for parsePatch - 6cab62c
- Add browser flag - e64f674
- refactor: simplified code a bit more - 8f8e0f2
- refactor: simplified code a bit - b094a6f
- fix: some corrections re ignoreCase option - 3c78fd0
- ignoreCase option - 3cbfbb5
- Sanitize filename while parsing patches - 2fe8129
- Added better installation methods - aced50b
- Simple export of functionality - 8690f31
v3.2.0 - December 26th, 2016
- #156 - Add
undefinedReplacementoption todiffJson(@ewnd9) - #154 - Add
examplesandimagesto.npmignore. (@wtgtybhertgeghgtwtg) - #153 - feat(structuredPatch): Pass options to diffLines (@Kiougar)
v3.1.0 - November 27th, 2016
- #146 - JsDiff.diffArrays to compare arrays (@wvanderdeijl)
- #144 - Split file using all possible line delimiter instead of hard-coded "/n" and join lines back using the original delimiters (@soulbeing)
v3.0.1 - October 9th, 2016
- #139 - Make README.md look nicer in npmjs.com (@takenspc)
- #135 - parsePatch combines patches from multiple files into a single IUniDiff when there is no "Index" line (@ramya-rao-a)
- #124 - IE7/IE8 failure since 2.0.0 (@boneskull)
v3.0.0 - August 23rd, 2016
- #130 - Add callback argument to applyPatches
patchedoption (@piranna) - #120 - Correctly handle file names containing spaces (@adius)
- #119 - Do single reflow (@wifiextender)
- #117 - Make more usable with long strings. (@abnbgist)
Compatibility notes:
- applyPatches patch callback now is async and requires the callback be called to continue operation
v2.2.3 - May 31st, 2016
- #118 - Add a fix for applying 0-length destination patches (@chaaz)
- #115 - Fixed grammar in README (@krizalys)
- #113 - fix typo (@vmazare)
v2.2.2 - March 13th, 2016
- #102 - diffJson with dates, returns empty curly braces (@dr-dimitru)
- #97 - Whitespaces & diffWords (@faiwer)
- #92 - Fixes typo in the readme (@bg451)
v2.2.1 - November 12th, 2015
- #89 - add in display selector to readme (@FranDias)
- #88 - Split diffs based on file headers instead of 'Index:' metadata (@piranna)
v2.2.0 - October 29th, 2015
- #80 - Fix a typo: applyPath -> applyPatch (@fluxxu)
- #83 - Add basic fuzzy matching to applyPatch (@piranna) Commits
v2.2.0 - October 29th, 2015
- #80 - Fix a typo: applyPath -> applyPatch (@fluxxu)
- #83 - Add basic fuzzy matching to applyPatch (@piranna) Commits
v2.1.3 - September 30th, 2015
- #78 - fix: error throwing when apply patch to empty string (@21paradox)
v2.1.2 - September 23rd, 2015
v2.1.1 - September 9th, 2015
- #73 - Is applyPatches() exposed in the API? (@davidparsson)
v2.1.0 - August 27th, 2015
- #72 - Consider using options object API for flag permutations (@kpdecker)
- #70 - diffWords treats \n at the end as significant whitespace (@nesQuick)
- #69 - Missing count (@wfalkwallace)
- #68 - diffLines seems broken (@wfalkwallace)
- #60 - Support multiple diff hunks (@piranna)
- #54 - Feature Request: 3-way merge (@mog422)
- #42 - Fuzz factor for applyPatch (@stuartpb)
- Move whitespace ignore out of equals method - 542063c
- Include source maps in babel output - 7f7ab21
- Merge diff/line and diff/patch implementations - 1597705
- Drop map utility method - 1ddc939
- Documentation for parsePatch and applyPatches - 27c4b77
Compatibility notes:
- The undocumented ignoreWhitespace flag has been removed from the Diff equality check directly. This implementation may be copied to diff utilities if dependencies existed on this functionality.
v2.0.2 - August 8th, 2015
- #67 - cannot require from npm module in node (@commenthol)
- Convert to chai since we don’t support IE8 - a96bbad
v2.0.1 - August 7th, 2015
- Add release build at proper step - 57542fd
v2.0.0 - August 7th, 2015
- #66 - Add karma and sauce tests (@kpdecker)
- #65 - Create component repository for bower (@kpdecker)
- #64 - Automatically call removeEmpty for all tokenizer calls (@kpdecker)
- #62 - Allow access to structured object representation of patch data (@bittrance)
- #61 - Use svg instead of png to get better image quality (@PeterDaveHello)
- #29 - word tokenizer works only for 7 bit ascii (@plasmagunman)
Compatibility notes:
this.removeEmptyis now called automatically for all instances. If this is not desired, this may be overridden on a per instance basis.- The library has been refactored to use some ES6 features. The external APIs should remain the same, but bower projects that directly referenced the repository will now have to point to the components/jsdiff repository.
v1.4.0 - May 6th, 2015
- #57 - createPatch -> applyPatch failed. (@mog422)
- #56 - Two files patch (@rgeissert)
- #14 - Flip added and removed order? (@jakesandlund)
v1.3.2 - March 30th, 2015
- #53 - Updated README.MD with Bower installation instructions (@ofbriggs)
- #49 - Cannot read property 'oldlines' of undefined (@nwtn)
- #44 - invalid-meta jsdiff is missing "main" entry in bower.json
v1.3.1 - March 13th, 2015
- #52 - Fix for #51 Wrong result of JsDiff.diffLines (@felicienfrancois)
v1.3.0 - March 2nd, 2015
- #47 - Adding Diff Trimmed Lines (@JamesGould123)
v1.2.2 - January 26th, 2015
- #45 - Fix AMD module loading (@pedrocarrico)
- #43 - added a bower file (@nbrustein)
v1.2.1 - December 26th, 2014
v1.2.0 - November 29th, 2014
- #37 - Add support for sentences. (@vmariano)
- #28 - Implemented diffJson (@papandreou)
- #27 - Slow to execute over diffs with a large number of changes (@termi)
- Allow for optional async diffing - 19385b9
- Fix diffChars implementation - eaa44ed
v1.1.0 - November 25th, 2014
- #33 - AMD and global exports (@ovcharik)
- #32 - Add support for component (@vmariano)
- #31 - Don't rely on Array.prototype.map (@papandreou)
v1.0.8 - December 22nd, 2013
- #24 - Handle windows newlines on non windows machines. (@benogle)
- #23 - Prettied up the API formatting a little, and added basic node and web examples (@airportyh)
v1.0.7 - September 11th, 2013
-
#22 - Added variant of WordDiff that doesn't ignore whitespace differences (@papandreou
-
Add 0.10 to travis tests - 243a526
v1.0.6 - August 30th, 2013
- #19 - Explicitly define contents of npm package (@sindresorhus