aboutsummaryrefslogtreecommitdiffstats
path: root/modules/gitrepo
diff options
context:
space:
mode:
authorwxiaoguang <wxiaoguang@gmail.com>2024-12-24 11:43:57 +0800
committerGitHub <noreply@github.com>2024-12-24 11:43:57 +0800
commit6d5aa9218e78ac500b21fb3f36674284118a7c78 (patch)
treeb715679f96f126958457b6e6c42d0d26aebcb58a /modules/gitrepo
parent781c6df40fcd8c8a112d048b4beb079d0b9a7f2b (diff)
downloadgitea-6d5aa9218e78ac500b21fb3f36674284118a7c78.tar.gz
gitea-6d5aa9218e78ac500b21fb3f36674284118a7c78.zip
Refactor request context (#32956)
Introduce RequestContext: is a short-lived context that is used to store request-specific data. RequestContext could be used to clean form tmp files, close context git repo, and do some tracing in the future. Then a lot of legacy code could be removed or improved. For example: most `ctx.Repo.GitRepo.Close()` could be removed because the git repo could be closed when the request is done.
Diffstat (limited to 'modules/gitrepo')
-rw-r--r--modules/gitrepo/gitrepo.go66
-rw-r--r--modules/gitrepo/walk_gogit.go12
2 files changed, 22 insertions, 56 deletions
diff --git a/modules/gitrepo/gitrepo.go b/modules/gitrepo/gitrepo.go
index 14d809aedb..831b9d7bb7 100644
--- a/modules/gitrepo/gitrepo.go
+++ b/modules/gitrepo/gitrepo.go
@@ -10,6 +10,7 @@ import (
"strings"
"code.gitea.io/gitea/modules/git"
+ "code.gitea.io/gitea/modules/reqctx"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/util"
)
@@ -38,63 +39,32 @@ func OpenWikiRepository(ctx context.Context, repo Repository) (*git.Repository,
// contextKey is a value for use with context.WithValue.
type contextKey struct {
- name string
-}
-
-// RepositoryContextKey is a context key. It is used with context.Value() to get the current Repository for the context
-var RepositoryContextKey = &contextKey{"repository"}
-
-// RepositoryFromContext attempts to get the repository from the context
-func repositoryFromContext(ctx context.Context, repo Repository) *git.Repository {
- value := ctx.Value(RepositoryContextKey)
- if value == nil {
- return nil
- }
-
- if gitRepo, ok := value.(*git.Repository); ok && gitRepo != nil {
- if gitRepo.Path == repoPath(repo) {
- return gitRepo
- }
- }
-
- return nil
+ repoPath string
}
// RepositoryFromContextOrOpen attempts to get the repository from the context or just opens it
func RepositoryFromContextOrOpen(ctx context.Context, repo Repository) (*git.Repository, io.Closer, error) {
- gitRepo := repositoryFromContext(ctx, repo)
- if gitRepo != nil {
- return gitRepo, util.NopCloser{}, nil
+ ds := reqctx.GetRequestDataStore(ctx)
+ if ds != nil {
+ gitRepo, err := RepositoryFromRequestContextOrOpen(ctx, ds, repo)
+ return gitRepo, util.NopCloser{}, err
}
-
gitRepo, err := OpenRepository(ctx, repo)
return gitRepo, gitRepo, err
}
-// repositoryFromContextPath attempts to get the repository from the context
-func repositoryFromContextPath(ctx context.Context, path string) *git.Repository {
- value := ctx.Value(RepositoryContextKey)
- if value == nil {
- return nil
+// RepositoryFromRequestContextOrOpen opens the repository at the given relative path in the provided request context
+// The repo will be automatically closed when the request context is done
+func RepositoryFromRequestContextOrOpen(ctx context.Context, ds reqctx.RequestDataStore, repo Repository) (*git.Repository, error) {
+ ck := contextKey{repoPath: repoPath(repo)}
+ if gitRepo, ok := ctx.Value(ck).(*git.Repository); ok {
+ return gitRepo, nil
}
-
- if repo, ok := value.(*git.Repository); ok && repo != nil {
- if repo.Path == path {
- return repo
- }
+ gitRepo, err := git.OpenRepository(ctx, ck.repoPath)
+ if err != nil {
+ return nil, err
}
-
- return nil
-}
-
-// RepositoryFromContextOrOpenPath attempts to get the repository from the context or just opens it
-// Deprecated: Use RepositoryFromContextOrOpen instead
-func RepositoryFromContextOrOpenPath(ctx context.Context, path string) (*git.Repository, io.Closer, error) {
- gitRepo := repositoryFromContextPath(ctx, path)
- if gitRepo != nil {
- return gitRepo, util.NopCloser{}, nil
- }
-
- gitRepo, err := git.OpenRepository(ctx, path)
- return gitRepo, gitRepo, err
+ ds.AddCloser(gitRepo)
+ ds.SetContextValue(ck, gitRepo)
+ return gitRepo, nil
}
diff --git a/modules/gitrepo/walk_gogit.go b/modules/gitrepo/walk_gogit.go
index 6370faf08e..709897ba0c 100644
--- a/modules/gitrepo/walk_gogit.go
+++ b/modules/gitrepo/walk_gogit.go
@@ -14,15 +14,11 @@ import (
// WalkReferences walks all the references from the repository
// refname is empty, ObjectTag or ObjectBranch. All other values should be treated as equivalent to empty.
func WalkReferences(ctx context.Context, repo Repository, walkfn func(sha1, refname string) error) (int, error) {
- gitRepo := repositoryFromContext(ctx, repo)
- if gitRepo == nil {
- var err error
- gitRepo, err = OpenRepository(ctx, repo)
- if err != nil {
- return 0, err
- }
- defer gitRepo.Close()
+ gitRepo, closer, err := RepositoryFromContextOrOpen(ctx, repo)
+ if err != nil {
+ return 0, err
}
+ defer closer.Close()
i := 0
iter, err := gitRepo.GoGitRepo().References()