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:
@@ -5,6 +5,7 @@
|
||||
package files
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"code.gitea.io/gitea/models"
|
||||
@@ -18,14 +19,16 @@ import (
|
||||
// CreateCommitStatus creates a new CommitStatus given a bunch of parameters
|
||||
// NOTE: All text-values will be trimmed from whitespaces.
|
||||
// Requires: Repo, Creator, SHA
|
||||
func CreateCommitStatus(repo *repo_model.Repository, creator *user_model.User, sha string, status *models.CommitStatus) error {
|
||||
func CreateCommitStatus(ctx context.Context, repo *repo_model.Repository, creator *user_model.User, sha string, status *models.CommitStatus) error {
|
||||
repoPath := repo.RepoPath()
|
||||
|
||||
// confirm that commit is exist
|
||||
gitRepo, err := git.OpenRepository(repoPath)
|
||||
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath())
|
||||
if err != nil {
|
||||
return fmt.Errorf("OpenRepository[%s]: %v", repoPath, err)
|
||||
}
|
||||
defer closer.Close()
|
||||
|
||||
if _, err := gitRepo.GetCommit(sha); err != nil {
|
||||
gitRepo.Close()
|
||||
return fmt.Errorf("GetCommit[%s]: %v", sha, err)
|
||||
@@ -45,8 +48,8 @@ func CreateCommitStatus(repo *repo_model.Repository, creator *user_model.User, s
|
||||
}
|
||||
|
||||
// CountDivergingCommits determines how many commits a branch is ahead or behind the repository's base branch
|
||||
func CountDivergingCommits(repo *repo_model.Repository, branch string) (*git.DivergeObject, error) {
|
||||
divergence, err := git.GetDivergingCommits(repo.RepoPath(), repo.DefaultBranch, branch)
|
||||
func CountDivergingCommits(ctx context.Context, repo *repo_model.Repository, branch string) (*git.DivergeObject, error) {
|
||||
divergence, err := git.GetDivergingCommits(ctx, repo.RepoPath(), repo.DefaultBranch, branch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -5,6 +5,7 @@
|
||||
package files
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"path"
|
||||
@@ -39,7 +40,7 @@ func (ct *ContentType) String() string {
|
||||
|
||||
// GetContentsOrList gets the meta data of a file's contents (*ContentsResponse) if treePath not a tree
|
||||
// directory, otherwise a listing of file contents ([]*ContentsResponse). Ref can be a branch, commit or tag
|
||||
func GetContentsOrList(repo *repo_model.Repository, treePath, ref string) (interface{}, error) {
|
||||
func GetContentsOrList(ctx context.Context, repo *repo_model.Repository, treePath, ref string) (interface{}, error) {
|
||||
if repo.IsEmpty {
|
||||
return make([]interface{}, 0), nil
|
||||
}
|
||||
@@ -57,11 +58,11 @@ func GetContentsOrList(repo *repo_model.Repository, treePath, ref string) (inter
|
||||
}
|
||||
treePath = cleanTreePath
|
||||
|
||||
gitRepo, err := git.OpenRepository(repo.RepoPath())
|
||||
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer gitRepo.Close()
|
||||
defer closer.Close()
|
||||
|
||||
// Get the commit object for the ref
|
||||
commit, err := gitRepo.GetCommit(ref)
|
||||
@@ -75,7 +76,7 @@ func GetContentsOrList(repo *repo_model.Repository, treePath, ref string) (inter
|
||||
}
|
||||
|
||||
if entry.Type() != "tree" {
|
||||
return GetContents(repo, treePath, origRef, false)
|
||||
return GetContents(ctx, repo, treePath, origRef, false)
|
||||
}
|
||||
|
||||
// We are in a directory, so we return a list of FileContentResponse objects
|
||||
@@ -91,7 +92,7 @@ func GetContentsOrList(repo *repo_model.Repository, treePath, ref string) (inter
|
||||
}
|
||||
for _, e := range entries {
|
||||
subTreePath := path.Join(treePath, e.Name())
|
||||
fileContentResponse, err := GetContents(repo, subTreePath, origRef, true)
|
||||
fileContentResponse, err := GetContents(ctx, repo, subTreePath, origRef, true)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -101,7 +102,7 @@ func GetContentsOrList(repo *repo_model.Repository, treePath, ref string) (inter
|
||||
}
|
||||
|
||||
// GetContents gets the meta data on a file's contents. Ref can be a branch, commit or tag
|
||||
func GetContents(repo *repo_model.Repository, treePath, ref string, forList bool) (*api.ContentsResponse, error) {
|
||||
func GetContents(ctx context.Context, repo *repo_model.Repository, treePath, ref string, forList bool) (*api.ContentsResponse, error) {
|
||||
if ref == "" {
|
||||
ref = repo.DefaultBranch
|
||||
}
|
||||
@@ -116,11 +117,11 @@ func GetContents(repo *repo_model.Repository, treePath, ref string, forList bool
|
||||
}
|
||||
treePath = cleanTreePath
|
||||
|
||||
gitRepo, err := git.OpenRepository(repo.RepoPath())
|
||||
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer gitRepo.Close()
|
||||
defer closer.Close()
|
||||
|
||||
// Get the commit object for the ref
|
||||
commit, err := gitRepo.GetCommit(ref)
|
||||
@@ -163,7 +164,7 @@ func GetContents(repo *repo_model.Repository, treePath, ref string, forList bool
|
||||
// Now populate the rest of the ContentsResponse based on entry type
|
||||
if entry.IsRegular() || entry.IsExecutable() {
|
||||
contentsResponse.Type = string(ContentTypeRegular)
|
||||
if blobResponse, err := GetBlobBySHA(repo, entry.ID.String()); err != nil {
|
||||
if blobResponse, err := GetBlobBySHA(ctx, repo, entry.ID.String()); err != nil {
|
||||
return nil, err
|
||||
} else if !forList {
|
||||
// We don't show the content if we are getting a list of FileContentResponses
|
||||
@@ -219,12 +220,12 @@ func GetContents(repo *repo_model.Repository, treePath, ref string, forList bool
|
||||
}
|
||||
|
||||
// GetBlobBySHA get the GitBlobResponse of a repository using a sha hash.
|
||||
func GetBlobBySHA(repo *repo_model.Repository, sha string) (*api.GitBlobResponse, error) {
|
||||
gitRepo, err := git.OpenRepository(repo.RepoPath())
|
||||
func GetBlobBySHA(ctx context.Context, repo *repo_model.Repository, sha string) (*api.GitBlobResponse, error) {
|
||||
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer gitRepo.Close()
|
||||
defer closer.Close()
|
||||
gitBlob, err := gitRepo.GetBlob(sha)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@@ -63,14 +63,14 @@ func TestGetContents(t *testing.T) {
|
||||
|
||||
expectedContentsResponse := getExpectedReadmeContentsResponse()
|
||||
|
||||
t.Run("Get README.md contents with GetContents()", func(t *testing.T) {
|
||||
fileContentResponse, err := GetContents(ctx.Repo.Repository, treePath, ref, false)
|
||||
t.Run("Get README.md contents with GetContents(ctx, )", func(t *testing.T) {
|
||||
fileContentResponse, err := GetContents(ctx, ctx.Repo.Repository, treePath, ref, false)
|
||||
assert.EqualValues(t, expectedContentsResponse, fileContentResponse)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("Get README.md contents with ref as empty string (should then use the repo's default branch) with GetContents()", func(t *testing.T) {
|
||||
fileContentResponse, err := GetContents(ctx.Repo.Repository, treePath, "", false)
|
||||
t.Run("Get README.md contents with ref as empty string (should then use the repo's default branch) with GetContents(ctx, )", func(t *testing.T) {
|
||||
fileContentResponse, err := GetContents(ctx, ctx.Repo.Repository, treePath, "", false)
|
||||
assert.EqualValues(t, expectedContentsResponse, fileContentResponse)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
@@ -98,14 +98,14 @@ func TestGetContentsOrListForDir(t *testing.T) {
|
||||
readmeContentsResponse,
|
||||
}
|
||||
|
||||
t.Run("Get root dir contents with GetContentsOrList()", func(t *testing.T) {
|
||||
fileContentResponse, err := GetContentsOrList(ctx.Repo.Repository, treePath, ref)
|
||||
t.Run("Get root dir contents with GetContentsOrList(ctx, )", func(t *testing.T) {
|
||||
fileContentResponse, err := GetContentsOrList(ctx, ctx.Repo.Repository, treePath, ref)
|
||||
assert.EqualValues(t, expectedContentsListResponse, fileContentResponse)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("Get root dir contents with ref as empty string (should then use the repo's default branch) with GetContentsOrList()", func(t *testing.T) {
|
||||
fileContentResponse, err := GetContentsOrList(ctx.Repo.Repository, treePath, "")
|
||||
t.Run("Get root dir contents with ref as empty string (should then use the repo's default branch) with GetContentsOrList(ctx, )", func(t *testing.T) {
|
||||
fileContentResponse, err := GetContentsOrList(ctx, ctx.Repo.Repository, treePath, "")
|
||||
assert.EqualValues(t, expectedContentsListResponse, fileContentResponse)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
@@ -126,14 +126,14 @@ func TestGetContentsOrListForFile(t *testing.T) {
|
||||
|
||||
expectedContentsResponse := getExpectedReadmeContentsResponse()
|
||||
|
||||
t.Run("Get README.md contents with GetContentsOrList()", func(t *testing.T) {
|
||||
fileContentResponse, err := GetContentsOrList(ctx.Repo.Repository, treePath, ref)
|
||||
t.Run("Get README.md contents with GetContentsOrList(ctx, )", func(t *testing.T) {
|
||||
fileContentResponse, err := GetContentsOrList(ctx, ctx.Repo.Repository, treePath, ref)
|
||||
assert.EqualValues(t, expectedContentsResponse, fileContentResponse)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("Get README.md contents with ref as empty string (should then use the repo's default branch) with GetContentsOrList()", func(t *testing.T) {
|
||||
fileContentResponse, err := GetContentsOrList(ctx.Repo.Repository, treePath, "")
|
||||
t.Run("Get README.md contents with ref as empty string (should then use the repo's default branch) with GetContentsOrList(ctx, )", func(t *testing.T) {
|
||||
fileContentResponse, err := GetContentsOrList(ctx, ctx.Repo.Repository, treePath, "")
|
||||
assert.EqualValues(t, expectedContentsResponse, fileContentResponse)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
@@ -155,7 +155,7 @@ func TestGetContentsErrors(t *testing.T) {
|
||||
|
||||
t.Run("bad treePath", func(t *testing.T) {
|
||||
badTreePath := "bad/tree.md"
|
||||
fileContentResponse, err := GetContents(repo, badTreePath, ref, false)
|
||||
fileContentResponse, err := GetContents(ctx, repo, badTreePath, ref, false)
|
||||
assert.Error(t, err)
|
||||
assert.EqualError(t, err, "object does not exist [id: , rel_path: bad]")
|
||||
assert.Nil(t, fileContentResponse)
|
||||
@@ -163,7 +163,7 @@ func TestGetContentsErrors(t *testing.T) {
|
||||
|
||||
t.Run("bad ref", func(t *testing.T) {
|
||||
badRef := "bad_ref"
|
||||
fileContentResponse, err := GetContents(repo, treePath, badRef, false)
|
||||
fileContentResponse, err := GetContents(ctx, repo, treePath, badRef, false)
|
||||
assert.Error(t, err)
|
||||
assert.EqualError(t, err, "object does not exist [id: "+badRef+", rel_path: ]")
|
||||
assert.Nil(t, fileContentResponse)
|
||||
@@ -186,7 +186,7 @@ func TestGetContentsOrListErrors(t *testing.T) {
|
||||
|
||||
t.Run("bad treePath", func(t *testing.T) {
|
||||
badTreePath := "bad/tree.md"
|
||||
fileContentResponse, err := GetContentsOrList(repo, badTreePath, ref)
|
||||
fileContentResponse, err := GetContentsOrList(ctx, repo, badTreePath, ref)
|
||||
assert.Error(t, err)
|
||||
assert.EqualError(t, err, "object does not exist [id: , rel_path: bad]")
|
||||
assert.Nil(t, fileContentResponse)
|
||||
@@ -194,7 +194,7 @@ func TestGetContentsOrListErrors(t *testing.T) {
|
||||
|
||||
t.Run("bad ref", func(t *testing.T) {
|
||||
badRef := "bad_ref"
|
||||
fileContentResponse, err := GetContentsOrList(repo, treePath, badRef)
|
||||
fileContentResponse, err := GetContentsOrList(ctx, repo, treePath, badRef)
|
||||
assert.Error(t, err)
|
||||
assert.EqualError(t, err, "object does not exist [id: "+badRef+", rel_path: ]")
|
||||
assert.Nil(t, fileContentResponse)
|
||||
@@ -213,7 +213,7 @@ func TestGetContentsOrListOfEmptyRepos(t *testing.T) {
|
||||
repo := ctx.Repo.Repository
|
||||
|
||||
t.Run("empty repo", func(t *testing.T) {
|
||||
contents, err := GetContentsOrList(repo, "", "")
|
||||
contents, err := GetContentsOrList(ctx, repo, "", "")
|
||||
assert.NoError(t, err)
|
||||
assert.Empty(t, contents)
|
||||
})
|
||||
@@ -232,7 +232,7 @@ func TestGetBlobBySHA(t *testing.T) {
|
||||
ctx.SetParams(":id", "1")
|
||||
ctx.SetParams(":sha", sha)
|
||||
|
||||
gbr, err := GetBlobBySHA(ctx.Repo.Repository, ctx.Params(":sha"))
|
||||
gbr, err := GetBlobBySHA(ctx, ctx.Repo.Repository, ctx.Params(":sha"))
|
||||
expectedGBR := &api.GitBlobResponse{
|
||||
Content: "dHJlZSAyYTJmMWQ0NjcwNzI4YTJlMTAwNDllMzQ1YmQ3YTI3NjQ2OGJlYWI2CmF1dGhvciB1c2VyMSA8YWRkcmVzczFAZXhhbXBsZS5jb20+IDE0ODk5NTY0NzkgLTA0MDAKY29tbWl0dGVyIEV0aGFuIEtvZW5pZyA8ZXRoYW50a29lbmlnQGdtYWlsLmNvbT4gMTQ4OTk1NjQ3OSAtMDQwMAoKSW5pdGlhbCBjb21taXQK",
|
||||
Encoding: "base64",
|
||||
|
@@ -5,6 +5,7 @@
|
||||
package files
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
@@ -13,7 +14,6 @@ import (
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
repo_service "code.gitea.io/gitea/services/repository"
|
||||
)
|
||||
|
||||
// DeleteRepoFileOptions holds the repository delete file options
|
||||
@@ -31,7 +31,7 @@ type DeleteRepoFileOptions struct {
|
||||
}
|
||||
|
||||
// DeleteRepoFile deletes a file in the given repository
|
||||
func DeleteRepoFile(repo *repo_model.Repository, doer *user_model.User, opts *DeleteRepoFileOptions) (*api.FileResponse, error) {
|
||||
func DeleteRepoFile(ctx context.Context, repo *repo_model.Repository, doer *user_model.User, opts *DeleteRepoFileOptions) (*api.FileResponse, error) {
|
||||
// If no branch name is set, assume the repo's default branch
|
||||
if opts.OldBranch == "" {
|
||||
opts.OldBranch = repo.DefaultBranch
|
||||
@@ -40,8 +40,14 @@ func DeleteRepoFile(repo *repo_model.Repository, doer *user_model.User, opts *De
|
||||
opts.NewBranch = opts.OldBranch
|
||||
}
|
||||
|
||||
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer closer.Close()
|
||||
|
||||
// oldBranch must exist for this operation
|
||||
if _, err := repo_service.GetBranch(repo, opts.OldBranch); err != nil {
|
||||
if _, err := gitRepo.GetBranch(opts.OldBranch); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -49,7 +55,7 @@ func DeleteRepoFile(repo *repo_model.Repository, doer *user_model.User, opts *De
|
||||
// Check to make sure the branch does not already exist, otherwise we can't proceed.
|
||||
// If we aren't branching to a new branch, make sure user can commit to the given branch
|
||||
if opts.NewBranch != opts.OldBranch {
|
||||
newBranch, err := repo_service.GetBranch(repo, opts.NewBranch)
|
||||
newBranch, err := gitRepo.GetBranch(opts.NewBranch)
|
||||
if err != nil && !git.IsErrBranchNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
@@ -58,7 +64,7 @@ func DeleteRepoFile(repo *repo_model.Repository, doer *user_model.User, opts *De
|
||||
BranchName: opts.NewBranch,
|
||||
}
|
||||
}
|
||||
} else if err := VerifyBranchProtection(repo, doer, opts.OldBranch, opts.TreePath); err != nil {
|
||||
} else if err := VerifyBranchProtection(ctx, repo, doer, opts.OldBranch, opts.TreePath); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -74,7 +80,7 @@ func DeleteRepoFile(repo *repo_model.Repository, doer *user_model.User, opts *De
|
||||
|
||||
author, committer := GetAuthorAndCommitterUsers(opts.Author, opts.Committer, doer)
|
||||
|
||||
t, err := NewTemporaryUploadRepository(repo)
|
||||
t, err := NewTemporaryUploadRepository(ctx, repo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -191,7 +197,7 @@ func DeleteRepoFile(repo *repo_model.Repository, doer *user_model.User, opts *De
|
||||
return nil, err
|
||||
}
|
||||
|
||||
file, err := GetFileResponseFromCommit(repo, commit, opts.NewBranch, treePath)
|
||||
file, err := GetFileResponseFromCommit(ctx, repo, commit, opts.NewBranch, treePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -5,6 +5,7 @@
|
||||
package files
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
@@ -12,11 +13,11 @@ import (
|
||||
)
|
||||
|
||||
// GetDiffPreview produces and returns diff result of a file which is not yet committed.
|
||||
func GetDiffPreview(repo *repo_model.Repository, branch, treePath, content string) (*gitdiff.Diff, error) {
|
||||
func GetDiffPreview(ctx context.Context, repo *repo_model.Repository, branch, treePath, content string) (*gitdiff.Diff, error) {
|
||||
if branch == "" {
|
||||
branch = repo.DefaultBranch
|
||||
}
|
||||
t, err := NewTemporaryUploadRepository(repo)
|
||||
t, err := NewTemporaryUploadRepository(ctx, repo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -117,7 +117,7 @@ func TestGetDiffPreview(t *testing.T) {
|
||||
expectedDiff.NumFiles = len(expectedDiff.Files)
|
||||
|
||||
t.Run("with given branch", func(t *testing.T) {
|
||||
diff, err := GetDiffPreview(ctx.Repo.Repository, branch, treePath, content)
|
||||
diff, err := GetDiffPreview(ctx, ctx.Repo.Repository, branch, treePath, content)
|
||||
assert.NoError(t, err)
|
||||
expectedBs, err := json.Marshal(expectedDiff)
|
||||
assert.NoError(t, err)
|
||||
@@ -127,7 +127,7 @@ func TestGetDiffPreview(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("empty branch, same results", func(t *testing.T) {
|
||||
diff, err := GetDiffPreview(ctx.Repo.Repository, "", treePath, content)
|
||||
diff, err := GetDiffPreview(ctx, ctx.Repo.Repository, "", treePath, content)
|
||||
assert.NoError(t, err)
|
||||
expectedBs, err := json.Marshal(expectedDiff)
|
||||
assert.NoError(t, err)
|
||||
@@ -152,20 +152,20 @@ func TestGetDiffPreviewErrors(t *testing.T) {
|
||||
content := "# repo1\n\nDescription for repo1\nthis is a new line"
|
||||
|
||||
t.Run("empty repo", func(t *testing.T) {
|
||||
diff, err := GetDiffPreview(&repo_model.Repository{}, branch, treePath, content)
|
||||
diff, err := GetDiffPreview(ctx, &repo_model.Repository{}, branch, treePath, content)
|
||||
assert.Nil(t, diff)
|
||||
assert.EqualError(t, err, "repository does not exist [id: 0, uid: 0, owner_name: , name: ]")
|
||||
})
|
||||
|
||||
t.Run("bad branch", func(t *testing.T) {
|
||||
badBranch := "bad_branch"
|
||||
diff, err := GetDiffPreview(ctx.Repo.Repository, badBranch, treePath, content)
|
||||
diff, err := GetDiffPreview(ctx, ctx.Repo.Repository, badBranch, treePath, content)
|
||||
assert.Nil(t, diff)
|
||||
assert.EqualError(t, err, "branch does not exist [name: "+badBranch+"]")
|
||||
})
|
||||
|
||||
t.Run("empty treePath", func(t *testing.T) {
|
||||
diff, err := GetDiffPreview(ctx.Repo.Repository, branch, "", content)
|
||||
diff, err := GetDiffPreview(ctx, ctx.Repo.Repository, branch, "", content)
|
||||
assert.Nil(t, diff)
|
||||
assert.EqualError(t, err, "path is invalid [path: ]")
|
||||
})
|
||||
|
@@ -5,6 +5,7 @@
|
||||
package files
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"path"
|
||||
@@ -18,9 +19,9 @@ import (
|
||||
)
|
||||
|
||||
// GetFileResponseFromCommit Constructs a FileResponse from a Commit object
|
||||
func GetFileResponseFromCommit(repo *repo_model.Repository, commit *git.Commit, branch, treeName string) (*api.FileResponse, error) {
|
||||
fileContents, _ := GetContents(repo, treeName, branch, false) // ok if fails, then will be nil
|
||||
fileCommitResponse, _ := GetFileCommitResponse(repo, commit) // ok if fails, then will be nil
|
||||
func GetFileResponseFromCommit(ctx context.Context, repo *repo_model.Repository, commit *git.Commit, branch, treeName string) (*api.FileResponse, error) {
|
||||
fileContents, _ := GetContents(ctx, repo, treeName, branch, false) // ok if fails, then will be nil
|
||||
fileCommitResponse, _ := GetFileCommitResponse(repo, commit) // ok if fails, then will be nil
|
||||
verification := GetPayloadCommitVerification(commit)
|
||||
fileResponse := &api.FileResponse{
|
||||
Content: fileContents,
|
||||
|
@@ -109,12 +109,12 @@ func TestGetFileResponseFromCommit(t *testing.T) {
|
||||
repo := ctx.Repo.Repository
|
||||
branch := repo.DefaultBranch
|
||||
treePath := "README.md"
|
||||
gitRepo, _ := git.OpenRepository(repo.RepoPath())
|
||||
gitRepo, _ := git.OpenRepositoryCtx(ctx, repo.RepoPath())
|
||||
defer gitRepo.Close()
|
||||
commit, _ := gitRepo.GetBranchCommit(branch)
|
||||
expectedFileResponse := getExpectedFileResponse()
|
||||
|
||||
fileResponse, err := GetFileResponseFromCommit(repo, commit, branch, treePath)
|
||||
fileResponse, err := GetFileResponseFromCommit(ctx, repo, commit, branch, treePath)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, expectedFileResponse, fileResponse)
|
||||
}
|
||||
|
@@ -26,18 +26,19 @@ import (
|
||||
|
||||
// TemporaryUploadRepository is a type to wrap our upload repositories as a shallow clone
|
||||
type TemporaryUploadRepository struct {
|
||||
ctx context.Context
|
||||
repo *repo_model.Repository
|
||||
gitRepo *git.Repository
|
||||
basePath string
|
||||
}
|
||||
|
||||
// NewTemporaryUploadRepository creates a new temporary upload repository
|
||||
func NewTemporaryUploadRepository(repo *repo_model.Repository) (*TemporaryUploadRepository, error) {
|
||||
func NewTemporaryUploadRepository(ctx context.Context, repo *repo_model.Repository) (*TemporaryUploadRepository, error) {
|
||||
basePath, err := models.CreateTemporaryPath("upload")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
t := &TemporaryUploadRepository{repo: repo, basePath: basePath}
|
||||
t := &TemporaryUploadRepository{ctx: ctx, repo: repo, basePath: basePath}
|
||||
return t, nil
|
||||
}
|
||||
|
||||
@@ -51,7 +52,7 @@ func (t *TemporaryUploadRepository) Close() {
|
||||
|
||||
// Clone the base repository to our path and set branch as the HEAD
|
||||
func (t *TemporaryUploadRepository) Clone(branch string) error {
|
||||
if _, err := git.NewCommand("clone", "-s", "--bare", "-b", branch, t.repo.RepoPath(), t.basePath).Run(); err != nil {
|
||||
if _, err := git.NewCommandContext(t.ctx, "clone", "-s", "--bare", "-b", branch, t.repo.RepoPath(), t.basePath).Run(); err != nil {
|
||||
stderr := err.Error()
|
||||
if matched, _ := regexp.MatchString(".*Remote branch .* not found in upstream origin.*", stderr); matched {
|
||||
return git.ErrBranchNotExist{
|
||||
@@ -68,7 +69,7 @@ func (t *TemporaryUploadRepository) Clone(branch string) error {
|
||||
return fmt.Errorf("Clone: %v %s", err, stderr)
|
||||
}
|
||||
}
|
||||
gitRepo, err := git.OpenRepository(t.basePath)
|
||||
gitRepo, err := git.OpenRepositoryCtx(t.ctx, t.basePath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -78,7 +79,7 @@ func (t *TemporaryUploadRepository) Clone(branch string) error {
|
||||
|
||||
// SetDefaultIndex sets the git index to our HEAD
|
||||
func (t *TemporaryUploadRepository) SetDefaultIndex() error {
|
||||
if _, err := git.NewCommand("read-tree", "HEAD").RunInDir(t.basePath); err != nil {
|
||||
if _, err := git.NewCommandContext(t.ctx, "read-tree", "HEAD").RunInDir(t.basePath); err != nil {
|
||||
return fmt.Errorf("SetDefaultIndex: %v", err)
|
||||
}
|
||||
return nil
|
||||
@@ -96,7 +97,7 @@ func (t *TemporaryUploadRepository) LsFiles(filenames ...string) ([]string, erro
|
||||
}
|
||||
}
|
||||
|
||||
if err := git.NewCommand(cmdArgs...).RunInDirPipeline(t.basePath, stdOut, stdErr); err != nil {
|
||||
if err := git.NewCommandContext(t.ctx, cmdArgs...).RunInDirPipeline(t.basePath, stdOut, stdErr); err != nil {
|
||||
log.Error("Unable to run git ls-files for temporary repo: %s (%s) Error: %v\nstdout: %s\nstderr: %s", t.repo.FullName(), t.basePath, err, stdOut.String(), stdErr.String())
|
||||
err = fmt.Errorf("Unable to run git ls-files for temporary repo of: %s Error: %v\nstdout: %s\nstderr: %s", t.repo.FullName(), err, stdOut.String(), stdErr.String())
|
||||
return nil, err
|
||||
@@ -123,7 +124,7 @@ func (t *TemporaryUploadRepository) RemoveFilesFromIndex(filenames ...string) er
|
||||
}
|
||||
}
|
||||
|
||||
if err := git.NewCommand("update-index", "--remove", "-z", "--index-info").RunInDirFullPipeline(t.basePath, stdOut, stdErr, stdIn); err != nil {
|
||||
if err := git.NewCommandContext(t.ctx, "update-index", "--remove", "-z", "--index-info").RunInDirFullPipeline(t.basePath, stdOut, stdErr, stdIn); err != nil {
|
||||
log.Error("Unable to update-index for temporary repo: %s (%s) Error: %v\nstdout: %s\nstderr: %s", t.repo.FullName(), t.basePath, err, stdOut.String(), stdErr.String())
|
||||
return fmt.Errorf("Unable to update-index for temporary repo: %s Error: %v\nstdout: %s\nstderr: %s", t.repo.FullName(), err, stdOut.String(), stdErr.String())
|
||||
}
|
||||
@@ -135,7 +136,7 @@ func (t *TemporaryUploadRepository) HashObject(content io.Reader) (string, error
|
||||
stdOut := new(bytes.Buffer)
|
||||
stdErr := new(bytes.Buffer)
|
||||
|
||||
if err := git.NewCommand("hash-object", "-w", "--stdin").RunInDirFullPipeline(t.basePath, stdOut, stdErr, content); err != nil {
|
||||
if err := git.NewCommandContext(t.ctx, "hash-object", "-w", "--stdin").RunInDirFullPipeline(t.basePath, stdOut, stdErr, content); err != nil {
|
||||
log.Error("Unable to hash-object to temporary repo: %s (%s) Error: %v\nstdout: %s\nstderr: %s", t.repo.FullName(), t.basePath, err, stdOut.String(), stdErr.String())
|
||||
return "", fmt.Errorf("Unable to hash-object to temporary repo: %s Error: %v\nstdout: %s\nstderr: %s", t.repo.FullName(), err, stdOut.String(), stdErr.String())
|
||||
}
|
||||
@@ -145,7 +146,7 @@ func (t *TemporaryUploadRepository) HashObject(content io.Reader) (string, error
|
||||
|
||||
// AddObjectToIndex adds the provided object hash to the index with the provided mode and path
|
||||
func (t *TemporaryUploadRepository) AddObjectToIndex(mode, objectHash, objectPath string) error {
|
||||
if _, err := git.NewCommand("update-index", "--add", "--replace", "--cacheinfo", mode, objectHash, objectPath).RunInDir(t.basePath); err != nil {
|
||||
if _, err := git.NewCommandContext(t.ctx, "update-index", "--add", "--replace", "--cacheinfo", mode, objectHash, objectPath).RunInDir(t.basePath); err != nil {
|
||||
stderr := err.Error()
|
||||
if matched, _ := regexp.MatchString(".*Invalid path '.*", stderr); matched {
|
||||
return models.ErrFilePathInvalid{
|
||||
@@ -161,7 +162,7 @@ func (t *TemporaryUploadRepository) AddObjectToIndex(mode, objectHash, objectPat
|
||||
|
||||
// WriteTree writes the current index as a tree to the object db and returns its hash
|
||||
func (t *TemporaryUploadRepository) WriteTree() (string, error) {
|
||||
stdout, err := git.NewCommand("write-tree").RunInDir(t.basePath)
|
||||
stdout, err := git.NewCommandContext(t.ctx, "write-tree").RunInDir(t.basePath)
|
||||
if err != nil {
|
||||
log.Error("Unable to write tree in temporary repo: %s(%s): Error: %v", t.repo.FullName(), t.basePath, err)
|
||||
return "", fmt.Errorf("Unable to write-tree in temporary repo for: %s Error: %v", t.repo.FullName(), err)
|
||||
@@ -179,7 +180,7 @@ func (t *TemporaryUploadRepository) GetLastCommitByRef(ref string) (string, erro
|
||||
if ref == "" {
|
||||
ref = "HEAD"
|
||||
}
|
||||
stdout, err := git.NewCommand("rev-parse", ref).RunInDir(t.basePath)
|
||||
stdout, err := git.NewCommandContext(t.ctx, "rev-parse", ref).RunInDir(t.basePath)
|
||||
if err != nil {
|
||||
log.Error("Unable to get last ref for %s in temporary repo: %s(%s): Error: %v", ref, t.repo.FullName(), t.basePath, err)
|
||||
return "", fmt.Errorf("Unable to rev-parse %s in temporary repo for: %s Error: %v", ref, t.repo.FullName(), err)
|
||||
@@ -218,7 +219,7 @@ func (t *TemporaryUploadRepository) CommitTreeWithDate(author, committer *user_m
|
||||
|
||||
// Determine if we should sign
|
||||
if git.CheckGitVersionAtLeast("1.7.9") == nil {
|
||||
sign, keyID, signer, _ := asymkey_service.SignCRUDAction(t.repo.RepoPath(), author, t.basePath, "HEAD")
|
||||
sign, keyID, signer, _ := asymkey_service.SignCRUDAction(t.ctx, t.repo.RepoPath(), author, t.basePath, "HEAD")
|
||||
if sign {
|
||||
args = append(args, "-S"+keyID)
|
||||
if t.repo.GetTrustModel() == repo_model.CommitterTrustModel || t.repo.GetTrustModel() == repo_model.CollaboratorCommitterTrustModel {
|
||||
@@ -253,7 +254,7 @@ func (t *TemporaryUploadRepository) CommitTreeWithDate(author, committer *user_m
|
||||
|
||||
stdout := new(bytes.Buffer)
|
||||
stderr := new(bytes.Buffer)
|
||||
if err := git.NewCommand(args...).RunInDirTimeoutEnvFullPipeline(env, -1, t.basePath, stdout, stderr, messageBytes); err != nil {
|
||||
if err := git.NewCommandContext(t.ctx, args...).RunInDirTimeoutEnvFullPipeline(env, -1, t.basePath, stdout, stderr, messageBytes); err != nil {
|
||||
log.Error("Unable to commit-tree in temporary repo: %s (%s) Error: %v\nStdout: %s\nStderr: %s",
|
||||
t.repo.FullName(), t.basePath, err, stdout, stderr)
|
||||
return "", fmt.Errorf("Unable to commit-tree in temporary repo: %s Error: %v\nStdout: %s\nStderr: %s",
|
||||
@@ -266,7 +267,7 @@ func (t *TemporaryUploadRepository) CommitTreeWithDate(author, committer *user_m
|
||||
func (t *TemporaryUploadRepository) Push(doer *user_model.User, commitHash, branch string) error {
|
||||
// Because calls hooks we need to pass in the environment
|
||||
env := models.PushingEnvironment(doer, t.repo)
|
||||
if err := git.Push(t.gitRepo.Ctx, t.basePath, git.PushOptions{
|
||||
if err := git.Push(t.ctx, t.basePath, git.PushOptions{
|
||||
Remote: t.repo.RepoPath(),
|
||||
Branch: strings.TrimSpace(commitHash) + ":" + git.BranchPrefix + strings.TrimSpace(branch),
|
||||
Env: env,
|
||||
@@ -302,7 +303,7 @@ func (t *TemporaryUploadRepository) DiffIndex() (*gitdiff.Diff, error) {
|
||||
var diff *gitdiff.Diff
|
||||
var finalErr error
|
||||
|
||||
if err := git.NewCommand("diff-index", "--src-prefix=\\a/", "--dst-prefix=\\b/", "--cached", "-p", "HEAD").
|
||||
if err := git.NewCommandContext(t.ctx, "diff-index", "--src-prefix=\\a/", "--dst-prefix=\\b/", "--cached", "-p", "HEAD").
|
||||
RunInDirTimeoutEnvFullPipelineFunc(nil, 30*time.Second, t.basePath, stdoutWriter, stderr, nil, func(ctx context.Context, cancel context.CancelFunc) error {
|
||||
_ = stdoutWriter.Close()
|
||||
diff, finalErr = gitdiff.ParsePatch(setting.Git.MaxGitDiffLines, setting.Git.MaxGitDiffLineCharacters, setting.Git.MaxGitDiffFiles, stdoutReader, "")
|
||||
@@ -323,7 +324,7 @@ func (t *TemporaryUploadRepository) DiffIndex() (*gitdiff.Diff, error) {
|
||||
t.repo.FullName(), err, stderr)
|
||||
}
|
||||
|
||||
diff.NumFiles, diff.TotalAddition, diff.TotalDeletion, err = git.GetDiffShortStat(t.basePath, "--cached", "HEAD")
|
||||
diff.NumFiles, diff.TotalAddition, diff.TotalDeletion, err = git.GetDiffShortStat(t.ctx, t.basePath, "--cached", "HEAD")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@@ -5,6 +5,7 @@
|
||||
package files
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
@@ -16,12 +17,7 @@ import (
|
||||
)
|
||||
|
||||
// GetTreeBySHA get the GitTreeResponse of a repository using a sha hash.
|
||||
func GetTreeBySHA(repo *repo_model.Repository, sha string, page, perPage int, recursive bool) (*api.GitTreeResponse, error) {
|
||||
gitRepo, err := git.OpenRepository(repo.RepoPath())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer gitRepo.Close()
|
||||
func GetTreeBySHA(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, sha string, page, perPage int, recursive bool) (*api.GitTreeResponse, error) {
|
||||
gitTree, err := gitRepo.GetTree(sha)
|
||||
if err != nil || gitTree == nil {
|
||||
return nil, models.ErrSHANotFound{
|
||||
|
@@ -29,7 +29,7 @@ func TestGetTreeBySHA(t *testing.T) {
|
||||
ctx.SetParams(":id", "1")
|
||||
ctx.SetParams(":sha", sha)
|
||||
|
||||
tree, err := GetTreeBySHA(ctx.Repo.Repository, ctx.Params(":sha"), page, perPage, true)
|
||||
tree, err := GetTreeBySHA(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, ctx.Params(":sha"), page, perPage, true)
|
||||
assert.NoError(t, err)
|
||||
expectedTree := &api.GitTreeResponse{
|
||||
SHA: "65f1bf27bc3bf70f64657658635e66094edbcb4d",
|
||||
|
@@ -6,6 +6,7 @@ package files
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"fmt"
|
||||
"path"
|
||||
"strings"
|
||||
@@ -22,7 +23,6 @@ import (
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/util"
|
||||
asymkey_service "code.gitea.io/gitea/services/asymkey"
|
||||
repo_service "code.gitea.io/gitea/services/repository"
|
||||
|
||||
stdcharset "golang.org/x/net/html/charset"
|
||||
"golang.org/x/text/transform"
|
||||
@@ -125,7 +125,7 @@ func detectEncodingAndBOM(entry *git.TreeEntry, repo *repo_model.Repository) (st
|
||||
}
|
||||
|
||||
// CreateOrUpdateRepoFile adds or updates a file in the given repository
|
||||
func CreateOrUpdateRepoFile(repo *repo_model.Repository, doer *user_model.User, opts *UpdateRepoFileOptions) (*structs.FileResponse, error) {
|
||||
func CreateOrUpdateRepoFile(ctx context.Context, repo *repo_model.Repository, doer *user_model.User, opts *UpdateRepoFileOptions) (*structs.FileResponse, error) {
|
||||
// If no branch name is set, assume default branch
|
||||
if opts.OldBranch == "" {
|
||||
opts.OldBranch = repo.DefaultBranch
|
||||
@@ -134,8 +134,14 @@ func CreateOrUpdateRepoFile(repo *repo_model.Repository, doer *user_model.User,
|
||||
opts.NewBranch = opts.OldBranch
|
||||
}
|
||||
|
||||
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
defer closer.Close()
|
||||
|
||||
// oldBranch must exist for this operation
|
||||
if _, err := repo_service.GetBranch(repo, opts.OldBranch); err != nil {
|
||||
if _, err := gitRepo.GetBranch(opts.OldBranch); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -143,7 +149,7 @@ func CreateOrUpdateRepoFile(repo *repo_model.Repository, doer *user_model.User,
|
||||
// Check to make sure the branch does not already exist, otherwise we can't proceed.
|
||||
// If we aren't branching to a new branch, make sure user can commit to the given branch
|
||||
if opts.NewBranch != opts.OldBranch {
|
||||
existingBranch, err := repo_service.GetBranch(repo, opts.NewBranch)
|
||||
existingBranch, err := gitRepo.GetBranch(opts.NewBranch)
|
||||
if existingBranch != nil {
|
||||
return nil, models.ErrBranchAlreadyExists{
|
||||
BranchName: opts.NewBranch,
|
||||
@@ -152,7 +158,7 @@ func CreateOrUpdateRepoFile(repo *repo_model.Repository, doer *user_model.User,
|
||||
if err != nil && !git.IsErrBranchNotExist(err) {
|
||||
return nil, err
|
||||
}
|
||||
} else if err := VerifyBranchProtection(repo, doer, opts.OldBranch, opts.TreePath); err != nil {
|
||||
} else if err := VerifyBranchProtection(ctx, repo, doer, opts.OldBranch, opts.TreePath); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -180,7 +186,7 @@ func CreateOrUpdateRepoFile(repo *repo_model.Repository, doer *user_model.User,
|
||||
|
||||
author, committer := GetAuthorAndCommitterUsers(opts.Author, opts.Committer, doer)
|
||||
|
||||
t, err := NewTemporaryUploadRepository(repo)
|
||||
t, err := NewTemporaryUploadRepository(ctx, repo)
|
||||
if err != nil {
|
||||
log.Error("%v", err)
|
||||
}
|
||||
@@ -435,7 +441,7 @@ func CreateOrUpdateRepoFile(repo *repo_model.Repository, doer *user_model.User,
|
||||
return nil, err
|
||||
}
|
||||
|
||||
file, err := GetFileResponseFromCommit(repo, commit, opts.NewBranch, treePath)
|
||||
file, err := GetFileResponseFromCommit(ctx, repo, commit, opts.NewBranch, treePath)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -443,7 +449,7 @@ func CreateOrUpdateRepoFile(repo *repo_model.Repository, doer *user_model.User,
|
||||
}
|
||||
|
||||
// VerifyBranchProtection verify the branch protection for modifying the given treePath on the given branch
|
||||
func VerifyBranchProtection(repo *repo_model.Repository, doer *user_model.User, branchName, treePath string) error {
|
||||
func VerifyBranchProtection(ctx context.Context, repo *repo_model.Repository, doer *user_model.User, branchName, treePath string) error {
|
||||
protectedBranch, err := models.GetProtectedBranchBy(repo.ID, branchName)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -460,7 +466,7 @@ func VerifyBranchProtection(repo *repo_model.Repository, doer *user_model.User,
|
||||
}
|
||||
}
|
||||
if protectedBranch.RequireSignedCommits {
|
||||
_, _, _, err := asymkey_service.SignCRUDAction(repo.RepoPath(), doer, repo.RepoPath(), branchName)
|
||||
_, _, _, err := asymkey_service.SignCRUDAction(ctx, repo.RepoPath(), doer, repo.RepoPath(), branchName)
|
||||
if err != nil {
|
||||
if !asymkey_service.IsErrWontSign(err) {
|
||||
return err
|
||||
|
@@ -5,6 +5,7 @@
|
||||
package files
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"os"
|
||||
"path"
|
||||
@@ -49,7 +50,7 @@ func cleanUpAfterFailure(infos *[]uploadInfo, t *TemporaryUploadRepository, orig
|
||||
}
|
||||
|
||||
// UploadRepoFiles uploads files to the given repository
|
||||
func UploadRepoFiles(repo *repo_model.Repository, doer *user_model.User, opts *UploadRepoFileOptions) error {
|
||||
func UploadRepoFiles(ctx context.Context, repo *repo_model.Repository, doer *user_model.User, opts *UploadRepoFileOptions) error {
|
||||
if len(opts.Files) == 0 {
|
||||
return nil
|
||||
}
|
||||
@@ -80,7 +81,7 @@ func UploadRepoFiles(repo *repo_model.Repository, doer *user_model.User, opts *U
|
||||
infos[i] = uploadInfo{upload: upload}
|
||||
}
|
||||
|
||||
t, err := NewTemporaryUploadRepository(repo)
|
||||
t, err := NewTemporaryUploadRepository(ctx, repo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
Reference in New Issue
Block a user