@@ -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
3234func 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
0 commit comments