@@ -59,7 +59,7 @@ static int patch_image_init_fromstr(
5959 git_pool_init (& out -> pool , sizeof (git_diff_line ));
6060
6161 for (start = in ; start < in + in_len ; start = end ) {
62- end = memchr (start , '\n' , in_len );
62+ end = memchr (start , '\n' , in_len - ( start - in ) );
6363
6464 if (end == NULL )
6565 end = in + in_len ;
@@ -199,23 +199,34 @@ static int apply_hunk(
199199
200200 for (i = 0 ; i < hunk -> line_count ; i ++ ) {
201201 size_t linenum = hunk -> line_start + i ;
202- git_diff_line * line = git_array_get (patch -> lines , linenum );
202+ git_diff_line * line = git_array_get (patch -> lines , linenum ), * prev ;
203203
204204 if (!line ) {
205205 error = apply_err ("preimage does not contain line %" PRIuZ , linenum );
206206 goto done ;
207207 }
208208
209- if (line -> origin == GIT_DIFF_LINE_CONTEXT ||
210- line -> origin == GIT_DIFF_LINE_DELETION ) {
211- if ((error = git_vector_insert (& preimage .lines , line )) < 0 )
212- goto done ;
213- }
214-
215- if (line -> origin == GIT_DIFF_LINE_CONTEXT ||
216- line -> origin == GIT_DIFF_LINE_ADDITION ) {
217- if ((error = git_vector_insert (& postimage .lines , line )) < 0 )
218- goto done ;
209+ switch (line -> origin ) {
210+ case GIT_DIFF_LINE_CONTEXT_EOFNL :
211+ case GIT_DIFF_LINE_DEL_EOFNL :
212+ case GIT_DIFF_LINE_ADD_EOFNL :
213+ prev = i ? git_array_get (patch -> lines , linenum - 1 ) : NULL ;
214+ if (prev && prev -> content [prev -> content_len - 1 ] == '\n' )
215+ prev -> content_len -= 1 ;
216+ break ;
217+ case GIT_DIFF_LINE_CONTEXT :
218+ if ((error = git_vector_insert (& preimage .lines , line )) < 0 ||
219+ (error = git_vector_insert (& postimage .lines , line )) < 0 )
220+ goto done ;
221+ break ;
222+ case GIT_DIFF_LINE_DELETION :
223+ if ((error = git_vector_insert (& preimage .lines , line )) < 0 )
224+ goto done ;
225+ break ;
226+ case GIT_DIFF_LINE_ADDITION :
227+ if ((error = git_vector_insert (& postimage .lines , line )) < 0 )
228+ goto done ;
229+ break ;
219230 }
220231 }
221232
@@ -631,9 +642,12 @@ int git_apply_to_tree(
631642 for (i = 0 ; i < git_diff_num_deltas (diff ); i ++ ) {
632643 delta = git_diff_get_delta (diff , i );
633644
634- if ((error = git_index_remove (postimage ,
635- delta -> old_file .path , 0 )) < 0 )
636- goto done ;
645+ if (delta -> status == GIT_DELTA_DELETED ||
646+ delta -> status == GIT_DELTA_RENAMED ) {
647+ if ((error = git_index_remove (postimage ,
648+ delta -> old_file .path , 0 )) < 0 )
649+ goto done ;
650+ }
637651 }
638652
639653 if ((error = apply_deltas (repo , pre_reader , NULL , post_reader , postimage , diff , & opts )) < 0 )
0 commit comments