History

Simplify how git repositories are opened (#28937)

## Purpose This is a refactor toward building an abstraction over managing git repositories. Afterwards, it does not matter anymore if they are stored on the local disk or somewhere remote. ## What this PR changes We used `git.OpenRepository` everywhere previously. Now, we should split them into two distinct functions: Firstly, there are temporary repositories which do not change: ```go git.OpenRepository(ctx, diskPath) ``` Gitea managed repositories having a record in the database in the `repository` table are moved into the new package `gitrepo`: ```go gitrepo.OpenRepository(ctx, repo_model.Repo) ``` Why is `repo_model.Repository` the second parameter instead of file path? Because then we can easily adapt our repository storage strategy. The repositories can be stored locally, however, they could just as well be stored on a remote server. ## Further changes in other PRs - A Git Command wrapper on package `gitrepo` could be created. i.e. `NewCommand(ctx, repo_model.Repository, commands...)`. `git.RunOpts{Dir: repo.RepoPath()}`, the directory should be empty before invoking this method and it can be filled in the function only. #28940 - Remove the `RepoPath()`/`WikiPath()` functions to reduce the possibility of mistakes. ---------

Lunny Xiao committed 2 years ago

Commit 5f82ead1 parent 60e4a9884 files · +426 −273Browse files

Showing the changes to modules/context (3 of 84 files). Show all

Unified · Split

3 files
  1. modules/context/api.go +4 −5
  2. modules/context/context.go +2 −2
  3. modules/context/repo.go +5 −5
modules/context/api.go+4−5
@@ -11,11 +11,11 @@ import ( · 10 unmodified lines
11 "net/url"11 "net/url"
12 "strings"12 "strings"
13 13
14 repo_model "code.gitea.io/gitea/models/repo"
15 "code.gitea.io/gitea/models/unit"14 "code.gitea.io/gitea/models/unit"
16 user_model "code.gitea.io/gitea/models/user"15 user_model "code.gitea.io/gitea/models/user"
17 mc "code.gitea.io/gitea/modules/cache"16 mc "code.gitea.io/gitea/modules/cache"
18 "code.gitea.io/gitea/modules/git"17 "code.gitea.io/gitea/modules/git"
18 "code.gitea.io/gitea/modules/gitrepo"
19 "code.gitea.io/gitea/modules/httpcache"19 "code.gitea.io/gitea/modules/httpcache"
20 "code.gitea.io/gitea/modules/log"20 "code.gitea.io/gitea/modules/log"
21 "code.gitea.io/gitea/modules/setting"21 "code.gitea.io/gitea/modules/setting"
@@ -224,7 +224,7 @@ func APIContexter() func(http.Handler) http.Handler { · 202 unmodified lines
224 defer baseCleanUp()224 defer baseCleanUp()
225 225
226 ctx.Base.AppendContextValue(apiContextKey, ctx)226 ctx.Base.AppendContextValue(apiContextKey, ctx)
227 ctx.Base.AppendContextValueFunc(git.RepositoryContextKey, func() any { return ctx.Repo.GitRepo })227 ctx.Base.AppendContextValueFunc(gitrepo.RepositoryContextKey, func() any { return ctx.Repo.GitRepo })
228 228
229 // If request sends files, parse them here otherwise the Query() can't be parsed and the CsrfToken will be invalid.229 // If request sends files, parse them here otherwise the Query() can't be parsed and the CsrfToken will be invalid.
230 if ctx.Req.Method == "POST" && strings.Contains(ctx.Req.Header.Get("Content-Type"), "multipart/form-data") {230 if ctx.Req.Method == "POST" && strings.Contains(ctx.Req.Header.Get("Content-Type"), "multipart/form-data") {
@@ -278,10 +278,9 @@ func ReferencesGitRepo(allowEmpty ...bool) func(ctx *APIContext) (cancel context · 47 unmodified lines
278 278
279 // For API calls.279 // For API calls.
280 if ctx.Repo.GitRepo == nil {280 if ctx.Repo.GitRepo == nil {
281 repoPath := repo_model.RepoPath(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)281 gitRepo, err := gitrepo.OpenRepository(ctx, ctx.Repo.Repository)
282 gitRepo, err := git.OpenRepository(ctx, repoPath)
283 if err != nil {282 if err != nil {
284 ctx.Error(http.StatusInternalServerError, "RepoRef Invalid repo "+repoPath, err)283 ctx.Error(http.StatusInternalServerError, fmt.Sprintf("Open Repository %v failed", ctx.Repo.Repository.FullName()), err)
285 return cancel284 return cancel
286 }285 }
287 ctx.Repo.GitRepo = gitRepo286 ctx.Repo.GitRepo = gitRepo
modules/context/context.go+2−2
@@ -17,7 +17,7 @@ import ( · 16 unmodified lines
17 "code.gitea.io/gitea/models/unit"17 "code.gitea.io/gitea/models/unit"
18 user_model "code.gitea.io/gitea/models/user"18 user_model "code.gitea.io/gitea/models/user"
19 mc "code.gitea.io/gitea/modules/cache"19 mc "code.gitea.io/gitea/modules/cache"
20 "code.gitea.io/gitea/modules/git"20 "code.gitea.io/gitea/modules/gitrepo"
21 "code.gitea.io/gitea/modules/httpcache"21 "code.gitea.io/gitea/modules/httpcache"
22 "code.gitea.io/gitea/modules/setting"22 "code.gitea.io/gitea/modules/setting"
23 "code.gitea.io/gitea/modules/templates"23 "code.gitea.io/gitea/modules/templates"
@@ -163,7 +163,7 @@ func Contexter() func(next http.Handler) http.Handler { · 139 unmodified lines
163 ctx.Data["PageData"] = ctx.PageData163 ctx.Data["PageData"] = ctx.PageData
164 164
165 ctx.Base.AppendContextValue(WebContextKey, ctx)165 ctx.Base.AppendContextValue(WebContextKey, ctx)
166 ctx.Base.AppendContextValueFunc(git.RepositoryContextKey, func() any { return ctx.Repo.GitRepo })166 ctx.Base.AppendContextValueFunc(gitrepo.RepositoryContextKey, func() any { return ctx.Repo.GitRepo })
167 167
168 ctx.Csrf = PrepareCSRFProtector(csrfOpts, ctx)168 ctx.Csrf = PrepareCSRFProtector(csrfOpts, ctx)
169 169
modules/context/repo.go+5−5
@@ -23,6 +23,7 @@ import ( · 22 unmodified lines
23 user_model "code.gitea.io/gitea/models/user"23 user_model "code.gitea.io/gitea/models/user"
24 "code.gitea.io/gitea/modules/cache"24 "code.gitea.io/gitea/modules/cache"
25 "code.gitea.io/gitea/modules/git"25 "code.gitea.io/gitea/modules/git"
26 "code.gitea.io/gitea/modules/gitrepo"
26 code_indexer "code.gitea.io/gitea/modules/indexer/code"27 code_indexer "code.gitea.io/gitea/modules/indexer/code"
27 "code.gitea.io/gitea/modules/log"28 "code.gitea.io/gitea/modules/log"
28 repo_module "code.gitea.io/gitea/modules/repository"29 repo_module "code.gitea.io/gitea/modules/repository"
@@ -633,7 +634,7 @@ func RepoAssignment(ctx *Context) context.CancelFunc { · 604 unmodified lines
633 return nil634 return nil
634 }635 }
635 636
636 gitRepo, err := git.OpenRepository(ctx, repo_model.RepoPath(userName, repoName))637 gitRepo, err := gitrepo.OpenRepository(ctx, repo)
637 if err != nil {638 if err != nil {
638 if strings.Contains(err.Error(), "repository does not exist") || strings.Contains(err.Error(), "no such file or directory") {639 if strings.Contains(err.Error(), "repository does not exist") || strings.Contains(err.Error(), "no such file or directory") {
639 log.Error("Repository %-v has a broken repository on the file system: %s Error: %v", ctx.Repo.Repository, ctx.Repo.Repository.RepoPath(), err)640 log.Error("Repository %-v has a broken repository on the file system: %s Error: %v", ctx.Repo.Repository, ctx.Repo.Repository.RepoPath(), err)
@@ -645,7 +646,7 @@ func RepoAssignment(ctx *Context) context.CancelFunc { · 5 unmodified lines
645 }646 }
646 return nil647 return nil
647 }648 }
648 ctx.ServerError("RepoAssignment Invalid repo "+repo_model.RepoPath(userName, repoName), err)649 ctx.ServerError("RepoAssignment Invalid repo "+repo.FullName(), err)
649 return nil650 return nil
650 }651 }
651 if ctx.Repo.GitRepo != nil {652 if ctx.Repo.GitRepo != nil {
@@ -920,10 +921,9 @@ func RepoRefByType(refType RepoRefType, ignoreNotExistErr ...bool) func(*Context · 268 unmodified lines
920 )921 )
921 922
922 if ctx.Repo.GitRepo == nil {923 if ctx.Repo.GitRepo == nil {
923 repoPath := repo_model.RepoPath(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)924 ctx.Repo.GitRepo, err = gitrepo.OpenRepository(ctx, ctx.Repo.Repository)
924 ctx.Repo.GitRepo, err = git.OpenRepository(ctx, repoPath)
925 if err != nil {925 if err != nil {
926 ctx.ServerError("RepoRef Invalid repo "+repoPath, err)926 ctx.ServerError(fmt.Sprintf("Open Repository %v failed", ctx.Repo.Repository.FullName()), err)
927 return nil927 return nil
928 }928 }
929 // We opened it, we should close it929 // We opened it, we should close it