@@ -10,6 +10,7 @@ import (
10
10
"errors"
11
11
"fmt"
12
12
"os"
13
+ "slices"
13
14
"strconv"
14
15
"strings"
15
16
@@ -27,6 +28,7 @@ type GrepOptions struct {
27
28
MaxResultLimit int
28
29
ContextLineNumber int
29
30
IsFuzzy bool
31
+ MaxLineLength int // the maximum length of a line to parse, exceeding chars will be truncated
30
32
}
31
33
32
34
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
71
73
defer stdoutReader .Close ()
72
74
73
75
isInBlock := false
74
- scanner := bufio .NewScanner (stdoutReader )
76
+ rd := bufio .NewReaderSize (stdoutReader , util . IfZero ( opts . MaxLineLength , 16 * 1024 ) )
75
77
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
78
90
if ! isInBlock {
79
91
if _ /* ref */ , filename , ok := strings .Cut (line , ":" ); ok {
80
92
isInBlock = true
@@ -100,7 +112,7 @@ func GrepSearch(ctx context.Context, repo *Repository, search string, opts GrepO
100
112
res .LineCodes = append (res .LineCodes , lineCode )
101
113
}
102
114
}
103
- return scanner . Err ()
115
+ return nil
104
116
},
105
117
})
106
118
// git grep exits by cancel (killed), usually it is caused by the limit of results
0 commit comments