1
1
mirror of https://github.com/go-gitea/gitea synced 2025-07-22 18:28:37 +00:00

Propagate context and ensure git commands run in request context (#17868)

This PR continues the work in #17125 by progressively ensuring that git
commands run within the request context.

This now means that the if there is a git repo already open in the context it will be used instead of reopening it.

Signed-off-by: Andrew Thornton <art27@cantab.net>
This commit is contained in:
zeripath
2022-01-19 23:26:57 +00:00
committed by GitHub
parent 4563148a61
commit 5cb0c9aa0d
193 changed files with 1264 additions and 1154 deletions

View File

@@ -12,7 +12,6 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
gitea_context "code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/private"
)
@@ -34,38 +33,18 @@ func SetDefaultBranch(ctx *gitea_context.PrivateContext) {
ownerName := ctx.Params(":owner")
repoName := ctx.Params(":repo")
branch := ctx.Params(":branch")
repo, err := repo_model.GetRepositoryByOwnerAndName(ownerName, repoName)
if err != nil {
log.Error("Failed to get repository: %s/%s Error: %v", ownerName, repoName, err)
ctx.JSON(http.StatusInternalServerError, private.Response{
Err: fmt.Sprintf("Failed to get repository: %s/%s Error: %v", ownerName, repoName, err),
})
return
}
if repo.OwnerName == "" {
repo.OwnerName = ownerName
}
repo.DefaultBranch = branch
gitRepo, err := git.OpenRepository(repo.RepoPath())
if err != nil {
ctx.JSON(http.StatusInternalServerError, private.Response{
Err: fmt.Sprintf("Failed to get git repository: %s/%s Error: %v", ownerName, repoName, err),
})
return
}
if err := gitRepo.SetDefaultBranch(repo.DefaultBranch); err != nil {
ctx.Repo.Repository.DefaultBranch = branch
if err := ctx.Repo.GitRepo.SetDefaultBranch(ctx.Repo.Repository.DefaultBranch); err != nil {
if !git.IsErrUnsupportedVersion(err) {
gitRepo.Close()
ctx.JSON(http.StatusInternalServerError, private.Response{
Err: fmt.Sprintf("Unable to set default branch on repository: %s/%s Error: %v", ownerName, repoName, err),
})
return
}
}
gitRepo.Close()
if err := repo_model.UpdateDefaultBranch(repo); err != nil {
if err := repo_model.UpdateDefaultBranch(ctx.Repo.Repository); err != nil {
ctx.JSON(http.StatusInternalServerError, private.Response{
Err: fmt.Sprintf("Unable to set default branch on repository: %s/%s Error: %v", ownerName, repoName, err),
})

View File

@@ -183,7 +183,7 @@ func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID, refFullN
// 2. Disallow force pushes to protected branches
if git.EmptySHA != oldCommitID {
output, err := git.NewCommand("rev-list", "--max-count=1", oldCommitID, "^"+newCommitID).RunInDirWithEnv(repo.RepoPath(), ctx.env)
output, err := git.NewCommandContext(ctx, "rev-list", "--max-count=1", oldCommitID, "^"+newCommitID).RunInDirWithEnv(repo.RepoPath(), ctx.env)
if err != nil {
log.Error("Unable to detect force push between: %s and %s in %-v Error: %v", oldCommitID, newCommitID, repo, err)
ctx.JSON(http.StatusInternalServerError, private.Response{
@@ -228,7 +228,7 @@ func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID, refFullN
globs := protectBranch.GetProtectedFilePatterns()
if len(globs) > 0 {
_, err := pull_service.CheckFileProtection(oldCommitID, newCommitID, globs, 1, ctx.env, gitRepo)
_, err := pull_service.CheckFileProtection(gitRepo, oldCommitID, newCommitID, globs, 1, ctx.env)
if err != nil {
if !models.IsErrFilePathProtected(err) {
log.Error("Unable to check file protection for commits from %s to %s in %-v: %v", oldCommitID, newCommitID, repo, err)
@@ -270,7 +270,7 @@ func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID, refFullN
// Allow commits that only touch unprotected files
globs := protectBranch.GetUnprotectedFilePatterns()
if len(globs) > 0 {
unprotectedFilesOnly, err := pull_service.CheckUnprotectedFiles(oldCommitID, newCommitID, globs, ctx.env, gitRepo)
unprotectedFilesOnly, err := pull_service.CheckUnprotectedFiles(gitRepo, oldCommitID, newCommitID, globs, ctx.env)
if err != nil {
log.Error("Unable to check file protection for commits from %s to %s in %-v: %v", oldCommitID, newCommitID, repo, err)
ctx.JSON(http.StatusInternalServerError, private.Response{
@@ -337,7 +337,7 @@ func preReceiveBranch(ctx *preReceiveContext, oldCommitID, newCommitID, refFullN
}
// Check all status checks and reviews are ok
if err := pull_service.CheckPRReadyToMerge(pr, true); err != nil {
if err := pull_service.CheckPRReadyToMerge(ctx, pr, true); err != nil {
if models.IsErrNotAllowedToMerge(err) {
log.Warn("Forbidden: User %d is not allowed push to protected branch %s in %-v and pr #%d is not ready to be merged: %s", ctx.opts.UserID, branchName, repo, pr.Index, err.Error())
ctx.JSON(http.StatusForbidden, private.Response{

View File

@@ -44,7 +44,7 @@ func verifyCommits(oldCommitID, newCommitID string, repo *git.Repository, env []
}()
// This is safe as force pushes are already forbidden
err = git.NewCommand("rev-list", oldCommitID+"..."+newCommitID).
err = git.NewCommandContext(repo.Ctx, "rev-list", oldCommitID+"..."+newCommitID).
RunInDirTimeoutEnvFullPipelineFunc(env, -1, repo.Path,
stdoutWriter, nil, nil,
func(ctx context.Context, cancel context.CancelFunc) error {
@@ -88,7 +88,7 @@ func readAndVerifyCommit(sha string, repo *git.Repository, env []string) error {
}()
hash := git.MustIDFromString(sha)
return git.NewCommand("cat-file", "commit", sha).
return git.NewCommandContext(repo.Ctx, "cat-file", "commit", sha).
RunInDirTimeoutEnvFullPipelineFunc(env, -1, repo.Path,
stdoutWriter, nil, nil,
func(ctx context.Context, cancel context.CancelFunc) error {

View File

@@ -57,8 +57,8 @@ func Routes() *web.Route {
r.Post("/ssh/{id}/update/{repoid}", UpdatePublicKeyInRepo)
r.Post("/ssh/log", bind(private.SSHLogOption{}), SSHLog)
r.Post("/hook/pre-receive/{owner}/{repo}", RepoAssignment, bind(private.HookOptions{}), HookPreReceive)
r.Post("/hook/post-receive/{owner}/{repo}", bind(private.HookOptions{}), HookPostReceive)
r.Post("/hook/proc-receive/{owner}/{repo}", RepoAssignment, bind(private.HookOptions{}), HookProcReceive)
r.Post("/hook/post-receive/{owner}/{repo}", context.OverrideContext, bind(private.HookOptions{}), HookPostReceive)
r.Post("/hook/proc-receive/{owner}/{repo}", context.OverrideContext, RepoAssignment, bind(private.HookOptions{}), HookProcReceive)
r.Post("/hook/set-default-branch/{owner}/{repo}/{branch}", RepoAssignment, SetDefaultBranch)
r.Get("/serv/none/{keyid}", ServNoCommand)
r.Get("/serv/command/{keyid}/{owner}/{repo}", ServCommand)

View File

@@ -43,7 +43,7 @@ func RepoAssignment(ctx *gitea_context.PrivateContext) context.CancelFunc {
return nil
}
gitRepo, err := git.OpenRepository(repo.RepoPath())
gitRepo, err := git.OpenRepositoryCtx(ctx, repo.RepoPath())
if err != nil {
log.Error("Failed to open repository: %s/%s Error: %v", ownerName, repoName, err)
ctx.JSON(http.StatusInternalServerError, map[string]interface{}{

View File

@@ -401,7 +401,7 @@ func ServCommand(ctx *context.PrivateContext) {
}
// Finally if we're trying to touch the wiki we should init it
if err = wiki_service.InitWiki(repo); err != nil {
if err = wiki_service.InitWiki(ctx, repo); err != nil {
log.Error("Failed to initialize the wiki in %-v Error: %v", repo, err)
ctx.JSON(http.StatusInternalServerError, private.ErrServCommand{
Results: results,