From 7018659a1d7ef2ec1303ae26a8925fff92898327 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Sun, 13 Aug 2023 10:11:20 +0800 Subject: [PATCH] Close stdout correctly for "git blame" (#26470) Close stdout correctly for "git blame", otherwise the failed "git blame" would case the request hanging forever. And "os.Stderr" should never (seldom) be used as git command's stderr --- modules/git/blame.go | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/modules/git/blame.go b/modules/git/blame.go index ec88accb10..4bd13dc32d 100644 --- a/modules/git/blame.go +++ b/modules/git/blame.go @@ -5,11 +5,14 @@ package git import ( "bufio" + "bytes" "context" "fmt" "io" "os" "regexp" + + "code.gitea.io/gitea/modules/log" ) // 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) 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, Dir: dir, Stdout: stdout, - Stderr: os.Stderr, - }); err == nil { - stdout.Close() - } + Stderr: &stderr, + }) 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) bufferedReader := bufio.NewReader(reader)