Fix blame view missing lines (#22826)

Creating a new buffered reader for every part of the blame can miss
lines, as it will read and buffer bytes that the next buffered reader
will not get.

Co-authored-by: Lunny Xiao <xiaolunwen@gmail.com>
This commit is contained in:
Brecht Van Lommel 2023-02-09 04:51:02 +01:00 committed by GitHub
parent 4dd7d61ac8
commit 87261f3fb9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 18 additions and 15 deletions

View file

@ -20,11 +20,12 @@ type BlamePart struct {
// BlameReader returns part of file blame one by one // BlameReader returns part of file blame one by one
type BlameReader struct { type BlameReader struct {
cmd *Command cmd *Command
output io.WriteCloser output io.WriteCloser
reader io.ReadCloser reader io.ReadCloser
done chan error bufferedReader *bufio.Reader
lastSha *string done chan error
lastSha *string
} }
var shaLineRegex = regexp.MustCompile("^([a-z0-9]{40})") var shaLineRegex = regexp.MustCompile("^([a-z0-9]{40})")
@ -33,8 +34,6 @@ var shaLineRegex = regexp.MustCompile("^([a-z0-9]{40})")
func (r *BlameReader) NextPart() (*BlamePart, error) { func (r *BlameReader) NextPart() (*BlamePart, error) {
var blamePart *BlamePart var blamePart *BlamePart
reader := bufio.NewReader(r.reader)
if r.lastSha != nil { if r.lastSha != nil {
blamePart = &BlamePart{*r.lastSha, make([]string, 0)} blamePart = &BlamePart{*r.lastSha, make([]string, 0)}
} }
@ -44,7 +43,7 @@ func (r *BlameReader) NextPart() (*BlamePart, error) {
var err error var err error
for err != io.EOF { for err != io.EOF {
line, isPrefix, err = reader.ReadLine() line, isPrefix, err = r.bufferedReader.ReadLine()
if err != nil && err != io.EOF { if err != nil && err != io.EOF {
return blamePart, err return blamePart, err
} }
@ -66,7 +65,7 @@ func (r *BlameReader) NextPart() (*BlamePart, error) {
r.lastSha = &sha1 r.lastSha = &sha1
// need to munch to end of line... // need to munch to end of line...
for isPrefix { for isPrefix {
_, isPrefix, err = reader.ReadLine() _, isPrefix, err = r.bufferedReader.ReadLine()
if err != nil && err != io.EOF { if err != nil && err != io.EOF {
return blamePart, err return blamePart, err
} }
@ -81,7 +80,7 @@ func (r *BlameReader) NextPart() (*BlamePart, error) {
// need to munch to end of line... // need to munch to end of line...
for isPrefix { for isPrefix {
_, isPrefix, err = reader.ReadLine() _, isPrefix, err = r.bufferedReader.ReadLine()
if err != nil && err != io.EOF { if err != nil && err != io.EOF {
return blamePart, err return blamePart, err
} }
@ -96,6 +95,7 @@ func (r *BlameReader) NextPart() (*BlamePart, error) {
// Close BlameReader - don't run NextPart after invoking that // Close BlameReader - don't run NextPart after invoking that
func (r *BlameReader) Close() error { func (r *BlameReader) Close() error {
err := <-r.done err := <-r.done
r.bufferedReader = nil
_ = r.reader.Close() _ = r.reader.Close()
_ = r.output.Close() _ = r.output.Close()
return err return err
@ -126,10 +126,13 @@ func CreateBlameReader(ctx context.Context, repoPath, commitID, file string) (*B
done <- err done <- err
}(cmd, repoPath, stdout, done) }(cmd, repoPath, stdout, done)
bufferedReader := bufio.NewReader(reader)
return &BlameReader{ return &BlameReader{
cmd: cmd, cmd: cmd,
output: stdout, output: stdout,
reader: reader, reader: reader,
done: done, bufferedReader: bufferedReader,
done: done,
}, nil }, nil
} }

View file

@ -28,7 +28,7 @@ func TestReadingBlameOutput(t *testing.T) {
}, },
{ {
"f32b0a9dfd09a60f616f29158f772cedd89942d2", "f32b0a9dfd09a60f616f29158f772cedd89942d2",
[]string{}, []string{"", "Do not make any changes to this repo it is used for unit testing"},
}, },
} }