From f74522a3524f6c2f99934ccf35453e7a9459bf14 Mon Sep 17 00:00:00 2001 From: Giteabot Date: Sun, 13 Aug 2023 16:00:28 +0800 Subject: [PATCH] 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 (cherry picked from commit fe1b11b639792b601ac5ba78c0378058032ec8a8) --- 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)