refactor: decouple git.Repository(ctx) from git.Commit & git.Tree (#38464)

1. Storing "ctx" in a long-living object is wrong
2. Make the commit & tree cacheable (for the future performance
optimization)
3. Also fix some bad designs like `// FIXME: bad design, this field can
be nil if the commit is from "last commit cache"`

ref:
* #33893
This commit is contained in:
wxiaoguang
2026-07-16 01:30:01 +08:00
committed by GitHub
parent ed678b9d45
commit 82edc3da01
115 changed files with 732 additions and 864 deletions
+1 -1
View File
@@ -68,7 +68,7 @@ func PullRequestCodeOwnersReview(ctx context.Context, pr *issues_model.PullReque
var data string
for _, file := range codeOwnerFiles {
if blob, err := commit.GetBlobByPath(file); err == nil {
if blob, err := commit.GetBlobByPath(ctx, repo, file); err == nil {
data, err = blob.GetBlobContent(setting.UI.MaxDisplayFileSize)
if err == nil {
break
+16 -15
View File
@@ -4,6 +4,7 @@
package issue
import (
"context"
"fmt"
"net/url"
"path"
@@ -47,17 +48,17 @@ func GetDefaultTemplateConfig() api.IssueConfig {
// GetTemplateConfig loads the given issue config file.
// It never returns a nil config.
func GetTemplateConfig(gitRepo *git.Repository, path string, commit *git.Commit) (api.IssueConfig, error) {
func GetTemplateConfig(ctx context.Context, gitRepo *git.Repository, path string, commit *git.Commit) (api.IssueConfig, error) {
if gitRepo == nil {
return GetDefaultTemplateConfig(), nil
}
treeEntry, err := commit.GetTreeEntryByPath(path)
treeEntry, err := commit.GetTreeEntryByPath(ctx, gitRepo, path)
if err != nil {
return GetDefaultTemplateConfig(), err
}
reader, err := treeEntry.Blob().DataAsync()
reader, err := treeEntry.Blob(gitRepo).DataAsync()
if err != nil {
log.Debug("DataAsync: %v", err)
return GetDefaultTemplateConfig(), nil
@@ -109,7 +110,7 @@ func IsTemplateConfig(path string) bool {
// ParseTemplatesFromDefaultBranch parses the issue templates in the repo's default branch,
// returns valid templates and the errors of invalid template files (the errors map is guaranteed to be non-nil).
func ParseTemplatesFromDefaultBranch(repo *repo.Repository, gitRepo *git.Repository) (ret struct {
func ParseTemplatesFromDefaultBranch(ctx context.Context, repo *repo.Repository, gitRepo *git.Repository) (ret struct {
IssueTemplates []*api.IssueTemplate
TemplateErrors map[string]error
},
@@ -125,12 +126,12 @@ func ParseTemplatesFromDefaultBranch(repo *repo.Repository, gitRepo *git.Reposit
}
for _, dirName := range templateDirCandidates {
tree, err := commit.SubTree(dirName)
tree, err := commit.SubTree(ctx, gitRepo, dirName)
if err != nil {
log.Debug("get sub tree of %s: %v", dirName, err)
continue
}
entries, err := tree.ListEntries()
entries, err := tree.ListEntries(ctx, gitRepo)
if err != nil {
log.Debug("list entries in %s: %v", dirName, err)
return ret
@@ -140,7 +141,7 @@ func ParseTemplatesFromDefaultBranch(repo *repo.Repository, gitRepo *git.Reposit
continue
}
fullName := path.Join(dirName, entry.Name())
if it, err := template.UnmarshalFromEntry(entry, dirName); err != nil {
if it, err := template.UnmarshalFromEntry(gitRepo, entry, dirName); err != nil {
ret.TemplateErrors[fullName] = err
} else {
if !strings.HasPrefix(it.Ref, "refs/") { // Assume that the ref intended is always a branch - for tags users should use refs/tags/<ref>
@@ -155,7 +156,7 @@ func ParseTemplatesFromDefaultBranch(repo *repo.Repository, gitRepo *git.Reposit
// GetTemplateConfigFromDefaultBranch returns the issue config for this repo.
// It never returns a nil config.
func GetTemplateConfigFromDefaultBranch(repo *repo.Repository, gitRepo *git.Repository) (api.IssueConfig, error) {
func GetTemplateConfigFromDefaultBranch(ctx context.Context, repo *repo.Repository, gitRepo *git.Repository) (api.IssueConfig, error) {
if repo.IsEmpty {
return GetDefaultTemplateConfig(), nil
}
@@ -166,24 +167,24 @@ func GetTemplateConfigFromDefaultBranch(repo *repo.Repository, gitRepo *git.Repo
}
for _, configName := range templateConfigCandidates {
if _, err := commit.GetTreeEntryByPath(configName + ".yaml"); err == nil {
return GetTemplateConfig(gitRepo, configName+".yaml", commit)
if _, err := commit.GetTreeEntryByPath(ctx, gitRepo, configName+".yaml"); err == nil {
return GetTemplateConfig(ctx, gitRepo, configName+".yaml", commit)
}
if _, err := commit.GetTreeEntryByPath(configName + ".yml"); err == nil {
return GetTemplateConfig(gitRepo, configName+".yml", commit)
if _, err := commit.GetTreeEntryByPath(ctx, gitRepo, configName+".yml"); err == nil {
return GetTemplateConfig(ctx, gitRepo, configName+".yml", commit)
}
}
return GetDefaultTemplateConfig(), nil
}
func HasTemplatesOrContactLinks(repo *repo.Repository, gitRepo *git.Repository) bool {
ret := ParseTemplatesFromDefaultBranch(repo, gitRepo)
func HasTemplatesOrContactLinks(ctx context.Context, repo *repo.Repository, gitRepo *git.Repository) bool {
ret := ParseTemplatesFromDefaultBranch(ctx, repo, gitRepo)
if len(ret.IssueTemplates) > 0 {
return true
}
issueConfig, _ := GetTemplateConfigFromDefaultBranch(repo, gitRepo)
issueConfig, _ := GetTemplateConfigFromDefaultBranch(ctx, repo, gitRepo)
return len(issueConfig.ContactLinks) > 0
}