From 6049834af3051b41f9509d18306b59f2a7bd3e0b Mon Sep 17 00:00:00 2001 From: Billy Keyes Date: Wed, 3 Sep 2025 20:16:31 -0400 Subject: [PATCH] Report short sources as conflicts during apply Previously, this returned an io.ErrUnexpectedEOF. This is not wrong, in that we did unexpectedly hit the end of the input file, but it is vague and implies a possible library bug rather than a problem with the patch or the input. This condition is really a conflict, as the changes described by the patch are not compatible with the state of the input. --- gitdiff/apply_test.go | 4 ++-- gitdiff/apply_text.go | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/gitdiff/apply_test.go b/gitdiff/apply_test.go index f19153b..05915ba 100644 --- a/gitdiff/apply_test.go +++ b/gitdiff/apply_test.go @@ -31,14 +31,14 @@ func TestApplyTextFragment(t *testing.T) { Src: "text_fragment_error.src", Patch: "text_fragment_error_short_src_before.patch", }, - Err: io.ErrUnexpectedEOF, + Err: &Conflict{}, }, "errorShortSrc": { Files: applyFiles{ Src: "text_fragment_error.src", Patch: "text_fragment_error_short_src.patch", }, - Err: io.ErrUnexpectedEOF, + Err: &Conflict{}, }, "errorContextConflict": { Files: applyFiles{ diff --git a/gitdiff/apply_text.go b/gitdiff/apply_text.go index 43af83a..8d0accb 100644 --- a/gitdiff/apply_text.go +++ b/gitdiff/apply_text.go @@ -1,6 +1,7 @@ package gitdiff import ( + "errors" "io" ) @@ -85,6 +86,11 @@ func (a *TextApplier) ApplyFragment(f *TextFragment) error { preimage := make([][]byte, fragEnd-start) n, err := a.lineSrc.ReadLinesAt(preimage, start) if err != nil { + // an EOF indicates that source file is shorter than the patch expects, + // which should be reported as a conflict rather than a generic error + if errors.Is(err, io.EOF) { + err = &Conflict{"src has fewer lines than required by fragment"} + } return applyError(err, lineNum(start+int64(n))) }