Skip to content

Commit e9db656

Browse files
committed
fix
1 parent 0fe9f93 commit e9db656

File tree

2 files changed

+27
-4
lines changed

2 files changed

+27
-4
lines changed

modules/git/grep.go

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"errors"
1111
"fmt"
1212
"os"
13+
"slices"
1314
"strconv"
1415
"strings"
1516

@@ -27,6 +28,7 @@ type GrepOptions struct {
2728
MaxResultLimit int
2829
ContextLineNumber int
2930
IsFuzzy bool
31+
MaxLineLength int // the maximum length of a line to parse, exceeding chars will be truncated
3032
}
3133

3234
func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepOptions) ([]*GrepResult, error) {
@@ -71,10 +73,20 @@ func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepO
7173
defer stdoutReader.Close()
7274

7375
isInBlock := false
74-
scanner := bufio.NewScanner(stdoutReader)
76+
rd := bufio.NewReaderSize(stdoutReader, util.IfZero(opts.MaxLineLength, 16*1024))
7577
var res *GrepResult
76-
for scanner.Scan() {
77-
line := scanner.Text()
78+
for {
79+
lineBytes, isPrefix, err := rd.ReadLine()
80+
if isPrefix {
81+
lineBytes = slices.Clone(lineBytes)
82+
for isPrefix && err == nil {
83+
_, isPrefix, err = rd.ReadLine()
84+
}
85+
}
86+
if len(lineBytes) == 0 && err != nil {
87+
break
88+
}
89+
line := string(lineBytes) // the memory of lineBytes is mutable
7890
if !isInBlock {
7991
if _ /* ref */, filename, ok := strings.Cut(line, ":"); ok {
8092
isInBlock = true
@@ -100,7 +112,7 @@ func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepO
100112
res.LineCodes = append(res.LineCodes, lineCode)
101113
}
102114
}
103-
return scanner.Err()
115+
return nil
104116
},
105117
})
106118
// git grep exits by cancel (killed), usually it is caused by the limit of results

modules/git/grep_test.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,11 +41,22 @@ func TestGrepSearch(t *testing.T) {
4141
},
4242
}, res)
4343

44+
res, err = GrepSearch(context.Background(), repo, "void", GrepOptions{MaxResultLimit: 1, MaxLineLength: 39})
45+
assert.NoError(t, err)
46+
assert.Equal(t, []*GrepResult{
47+
{
48+
Filename: "java-hello/main.java",
49+
LineNumbers: []int{3},
50+
LineCodes: []string{" public static void main(String[] arg"},
51+
},
52+
}, res)
53+
4454
res, err = GrepSearch(context.Background(), repo, "no-such-content", GrepOptions{})
4555
assert.NoError(t, err)
4656
assert.Len(t, res, 0)
4757

4858
res, err = GrepSearch(context.Background(), &Repository{Path: "no-such-git-repo"}, "no-such-content", GrepOptions{})
4959
assert.Error(t, err)
5060
assert.Len(t, res, 0)
61+
5162
}

0 commit comments

Comments
 (0)