@@ -19,12 +19,16 @@ export function applyPatch(source, uniDiff, options = {}) {
1919
2020 compareLine = options . compareLine || ( ( lineNumber , line , operation , patchContent ) => line === patchContent ) ,
2121 errorCount = 0 ,
22- offset = 0 ,
2322 fuzzFactor = options . fuzzFactor || 0 ,
23+ minLine = 0 ,
24+ offset = 0 ,
2425
2526 removeEOFNL ,
2627 addEOFNL ;
2728
29+ /**
30+ * Checks if the hunk exactly fits on the provided location
31+ */
2832 function hunkFits ( hunk , toPos ) {
2933 for ( let j = 0 ; j < hunk . lines . length ; j ++ ) {
3034 let line = hunk . lines [ j ] ,
@@ -47,42 +51,46 @@ export function applyPatch(source, uniDiff, options = {}) {
4751 return true ;
4852 }
4953
50- // Search best fit offsets for each hunk based on the previous ones
51- for ( let i = 0 ; i < hunks . length ; i ++ ) {
54+ // Search best fit offsets for each hunk based on the previous ones
55+ for ( let i = 0 ; i < hunks . length ; i ++ ) {
5256 let hunk = hunks [ i ] ,
5357 outOfLimits = 0 ,
5458 localOffset = 0 ,
55- minLine = 0 ,
5659 toPos = offset + hunk . oldStart - 1 ;
5760
5861 for ( ; ; ) {
59- if ( toPos + localOffset + hunk . oldLines <= lines . length ) {
60- if ( hunkFits ( hunk , toPos + localOffset ) ) {
61- hunk . offset = offset += localOffset ;
62- break ;
63- }
64- } else {
62+ // Check if trying to fit beyond text length, and if not, check it fits
63+ // after offset location (or desired location on first iteration)
64+ if ( lines . length < toPos + localOffset + hunk . oldLines ) {
6565 outOfLimits ++ ;
66+ } else if ( hunkFits ( hunk , toPos + localOffset ) ) {
67+ hunk . offset = offset += localOffset ;
68+ break ;
6669 }
6770
68- // If trying to fit hunk outside both limits, return error
71+ // If we tried to fit hunk before text beginning and beyond text lenght,
72+ // then hunk can't be fit on the text so we raise an error
6973 if ( outOfLimits === 2 ) {
7074 return false ;
7175 }
7276
77+ // Reset checks of trying to fit outside text limits and increase offset
78+ // of the current hunk relative to its desired location
7379 outOfLimits = 0 ;
7480 localOffset ++ ;
7581
76- if ( minLine <= toPos - localOffset ) {
77- if ( hunkFits ( hunk , toPos - localOffset ) ) {
78- hunk . offset = offset -= localOffset ;
79- break ;
80- }
81- } else {
82+ // Check if trying to fit before text beginning, and if not, check it fits
83+ // before offset location
84+ if ( toPos - localOffset < minLine ) {
8285 outOfLimits ++ ;
86+ } else if ( hunkFits ( hunk , toPos - localOffset ) ) {
87+ hunk . offset = offset -= localOffset ;
88+ break ;
8389 }
8490 }
8591
92+ // Set lower text limit to end of the current hunk, so next ones don't try
93+ // to fit over already patched text
8694 minLine = hunk . offset + hunk . oldStart + hunk . oldLines ;
8795 }
8896
0 commit comments