Close stdout correctly for "git blame" (#26470) (#26473)

Backport #26470 by @wxiaoguang

Close stdout correctly for "git blame", otherwise the failed "git blame"
would cause the request hanging forever.

And "os.Stderr" should never (seldom) be used as git command's stderr
(there seems some similar problems in code, they could be fixed later).

Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
Giteabot 2023-08-13 16:00:28 +08:00 committed by GitHub
parent 80d7288ea4
commit fe1b11b639
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -5,11 +5,14 @@ package git
import ( import (
"bufio" "bufio"
"bytes"
"context" "context"
"fmt" "fmt"
"io" "io"
"os" "os"
"regexp" "regexp"
"code.gitea.io/gitea/modules/log"
) )
// BlamePart represents block of blame - continuous lines with one sha // BlamePart represents block of blame - continuous lines with one sha
@ -115,15 +118,19 @@ func CreateBlameReader(ctx context.Context, repoPath, commitID, file string) (*B
done := make(chan error, 1) done := make(chan error, 1)
go func(cmd *Command, dir string, stdout io.WriteCloser, done chan error) { go func(cmd *Command, dir string, stdout io.WriteCloser, done chan error) {
if err := cmd.Run(&RunOpts{ stderr := bytes.Buffer{}
// TODO: it doesn't work for directories (the directories shouldn't be "blamed"), and the "err" should be returned by "Read" but not by "Close"
err := cmd.Run(&RunOpts{
UseContextTimeout: true, UseContextTimeout: true,
Dir: dir, Dir: dir,
Stdout: stdout, Stdout: stdout,
Stderr: os.Stderr, Stderr: &stderr,
}); err == nil { })
stdout.Close()
}
done <- err done <- err
_ = stdout.Close()
if err != nil {
log.Error("Error running git blame (dir: %v): %v, stderr: %v", repoPath, err, stderr.String())
}
}(cmd, repoPath, stdout, done) }(cmd, repoPath, stdout, done)
bufferedReader := bufio.NewReader(reader) bufferedReader := bufio.NewReader(reader)