handle no trailing EOL git message

This commit is contained in:
Marko Gaćeša 2023-05-23 15:28:52 +02:00
parent 3710c82b43
commit 56e0c642bd
2 changed files with 111 additions and 12 deletions

View File

@ -103,16 +103,16 @@ func DiffCut(r io.Reader, params types.DiffCutParams) (types.HunkHeader, types.H
linesBefore = linesBeforeBuf.lines()
if !errors.Is(err, io.EOF) {
for i := 0; i < params.AfterLines && scanner.Scan(); i++ {
line := scanner.Text()
for i := 0; i < params.AfterLines; i++ {
line, _, err := scanHunkLine(scanner)
if err != nil {
return types.HunkHeader{}, types.Hunk{}, err
}
if line == "" {
break
}
linesAfter = append(linesAfter, line)
}
if err = scanner.Err(); err != nil {
return types.HunkHeader{}, types.Hunk{}, err
}
}
diffCutHeaderLines := diffCutHeader
@ -185,22 +185,34 @@ const (
actionAdded diffAction = '+'
)
func scanHunkLine(scan *bufio.Scanner) (string, diffAction, error) {
func scanHunkLine(scan *bufio.Scanner) (line string, action diffAction, err error) {
again:
action = actionUnchanged
if !scan.Scan() {
return "", actionUnchanged, scan.Err()
err = scan.Err()
return
}
line := scan.Text()
line = scan.Text()
if line == "" {
return "", actionUnchanged, types.ErrHunkNotFound // should not happen: empty line in diff output
err = types.ErrHunkNotFound // should not happen: empty line in diff output
return
}
action = diffAction(line[0])
if action == '\\' { // handle the "\ No newline at end of file" line
goto again
}
action := diffAction(line[0])
if action != actionRemoved && action != actionAdded && action != actionUnchanged {
return "", actionUnchanged, nil
// treat this as the end of hunk
line = ""
action = actionUnchanged
return
}
return line, action, nil
return
}
type strCircBuf struct {

View File

@ -142,6 +142,93 @@ func TestDiffCut(t *testing.T) {
}
}
func TestDiffCutNoEOLInOld(t *testing.T) {
const input = `diff --git a/test.txt b/test.txt
index 541cb64f..047d7ee2 100644
--- a/test.txt
+++ b/test.txt
@@ -1 +1,4 @@
-test
\ No newline at end of file
+123
+456
+789
`
hh, h, err := DiffCut(
strings.NewReader(input),
types.DiffCutParams{
LineStart: 3,
LineStartNew: true,
LineEnd: 3,
LineEndNew: true,
BeforeLines: 1,
AfterLines: 1,
LineLimit: 100,
},
)
if err != nil {
t.Errorf("got error: %v", err)
return
}
expectedHH := types.HunkHeader{OldLine: 2, OldSpan: 0, NewLine: 3, NewSpan: 1}
if expectedHH != hh {
t.Errorf("expected hunk header: %+v, but got: %+v", expectedHH, hh)
}
expectedHunkLines := types.Hunk{
HunkHeader: types.HunkHeader{OldLine: 2, OldSpan: 0, NewLine: 2, NewSpan: 2},
Lines: []string{"+456", "+789"},
}
if !reflect.DeepEqual(expectedHunkLines, h) {
t.Errorf("expected hunk header: %+v, but got: %+v", expectedHunkLines, h)
}
}
func TestDiffCutNoEOLInNew(t *testing.T) {
const input = `diff --git a/test.txt b/test.txt
index af7864ba..541cb64f 100644
--- a/test.txt
+++ b/test.txt
@@ -1,3 +1 @@
-123
-456
-789
+test
\ No newline at end of file
`
hh, h, err := DiffCut(
strings.NewReader(input),
types.DiffCutParams{
LineStart: 1,
LineStartNew: true,
LineEnd: 1,
LineEndNew: true,
BeforeLines: 0,
AfterLines: 0,
LineLimit: 100,
},
)
if err != nil {
t.Errorf("got error: %v", err)
return
}
expectedHH := types.HunkHeader{OldLine: 1, OldSpan: 3, NewLine: 1, NewSpan: 1}
if expectedHH != hh {
t.Errorf("expected hunk header: %+v, but got: %+v", expectedHH, hh)
}
expectedHunkLines := types.Hunk{
HunkHeader: types.HunkHeader{OldLine: 1, OldSpan: 3, NewLine: 1, NewSpan: 1},
Lines: []string{"-123", "-456", "-789", "+test"},
}
if !reflect.DeepEqual(expectedHunkLines, h) {
t.Errorf("expected hunk header: %+v, but got: %+v", expectedHunkLines, h)
}
}
func TestStrCircBuf(t *testing.T) {
tests := []struct {
name string