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:
@@ -669,7 +669,7 @@ func runRepoSyncReleases(_ *cli.Context) error {
|
||||
log.Trace("Processing next %d repos of %d", len(repos), count)
|
||||
for _, repo := range repos {
|
||||
log.Trace("Synchronizing repo %s with path %s", repo.FullName(), repo.RepoPath())
|
||||
gitRepo, err := git.OpenRepository(repo.RepoPath())
|
||||
gitRepo, err := git.OpenRepositoryCtx(ctx, repo.RepoPath())
|
||||
if err != nil {
|
||||
log.Warn("OpenRepository: %v", err)
|
||||
continue
|
||||
|
@@ -5,7 +5,6 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
golog "log"
|
||||
"os"
|
||||
@@ -116,7 +115,7 @@ func runRecreateTable(ctx *cli.Context) error {
|
||||
}
|
||||
recreateTables := migrations.RecreateTables(beans...)
|
||||
|
||||
return db.InitEngineWithMigration(context.Background(), func(x *xorm.Engine) error {
|
||||
return db.InitEngineWithMigration(stdCtx, func(x *xorm.Engine) error {
|
||||
if err := migrations.EnsureUpToDate(x); err != nil {
|
||||
return err
|
||||
}
|
||||
|
@@ -7,6 +7,7 @@ package integrations
|
||||
import (
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
files_service "code.gitea.io/gitea/services/repository/files"
|
||||
)
|
||||
@@ -20,7 +21,7 @@ func createFileInBranch(user *user_model.User, repo *repo_model.Repository, tree
|
||||
Author: nil,
|
||||
Committer: nil,
|
||||
}
|
||||
return files_service.CreateOrUpdateRepoFile(repo, user, opts)
|
||||
return files_service.CreateOrUpdateRepoFile(git.DefaultContext, repo, user, opts)
|
||||
}
|
||||
|
||||
func createFile(user *user_model.User, repo *repo_model.Repository, treePath string) (*api.FileResponse, error) {
|
||||
|
@@ -72,7 +72,7 @@ func testAPIGetContentsList(t *testing.T, u *url.URL) {
|
||||
|
||||
// Make a new branch in repo1
|
||||
newBranch := "test_branch"
|
||||
err := repo_service.CreateNewBranch(user2, repo1, repo1.DefaultBranch, newBranch)
|
||||
err := repo_service.CreateNewBranch(git.DefaultContext, user2, repo1, repo1.DefaultBranch, newBranch)
|
||||
assert.NoError(t, err)
|
||||
// Get the commit ID of the default branch
|
||||
gitRepo, err := git.OpenRepository(repo1.RepoPath())
|
||||
|
@@ -73,7 +73,7 @@ func testAPIGetContents(t *testing.T, u *url.URL) {
|
||||
|
||||
// Make a new branch in repo1
|
||||
newBranch := "test_branch"
|
||||
err := repo_service.CreateNewBranch(user2, repo1, repo1.DefaultBranch, newBranch)
|
||||
err := repo_service.CreateNewBranch(git.DefaultContext, user2, repo1, repo1.DefaultBranch, newBranch)
|
||||
assert.NoError(t, err)
|
||||
// Get the commit ID of the default branch
|
||||
gitRepo, err := git.OpenRepository(repo1.RepoPath())
|
||||
|
@@ -128,7 +128,7 @@ func doGitCloneFail(u *url.URL) func(*testing.T) {
|
||||
tmpDir, err := os.MkdirTemp("", "doGitCloneFail")
|
||||
assert.NoError(t, err)
|
||||
defer util.RemoveAll(tmpDir)
|
||||
assert.Error(t, git.Clone(u.String(), tmpDir, git.CloneRepoOptions{}))
|
||||
assert.Error(t, git.Clone(git.DefaultContext, u.String(), tmpDir, git.CloneRepoOptions{}))
|
||||
exist, err := util.IsExist(filepath.Join(tmpDir, "README.md"))
|
||||
assert.NoError(t, err)
|
||||
assert.False(t, exist)
|
||||
@@ -138,7 +138,7 @@ func doGitCloneFail(u *url.URL) func(*testing.T) {
|
||||
func doGitInitTestRepository(dstPath string) func(*testing.T) {
|
||||
return func(t *testing.T) {
|
||||
// Init repository in dstPath
|
||||
assert.NoError(t, git.InitRepository(dstPath, false))
|
||||
assert.NoError(t, git.InitRepository(git.DefaultContext, dstPath, false))
|
||||
// forcibly set default branch to master
|
||||
_, err := git.NewCommand("symbolic-ref", "HEAD", git.BranchPrefix+"master").RunInDir(dstPath)
|
||||
assert.NoError(t, err)
|
||||
|
@@ -86,7 +86,7 @@ func TestMirrorPull(t *testing.T) {
|
||||
|
||||
release, err := models.GetRelease(repo.ID, "v0.2")
|
||||
assert.NoError(t, err)
|
||||
assert.NoError(t, release_service.DeleteReleaseByID(release.ID, user, true))
|
||||
assert.NoError(t, release_service.DeleteReleaseByID(ctx, release.ID, user, true))
|
||||
|
||||
ok = mirror_service.SyncPullMirror(ctx, mirror.ID)
|
||||
assert.True(t, ok)
|
||||
|
@@ -241,11 +241,11 @@ func TestCantMergeConflict(t *testing.T) {
|
||||
gitRepo, err := git.OpenRepository(repo_model.RepoPath(user1.Name, repo1.Name))
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = pull.Merge(pr, user1, gitRepo, repo_model.MergeStyleMerge, "", "CONFLICT")
|
||||
err = pull.Merge(git.DefaultContext, pr, user1, gitRepo, repo_model.MergeStyleMerge, "", "CONFLICT")
|
||||
assert.Error(t, err, "Merge should return an error due to conflict")
|
||||
assert.True(t, models.IsErrMergeConflicts(err), "Merge error is not a conflict error")
|
||||
|
||||
err = pull.Merge(pr, user1, gitRepo, repo_model.MergeStyleRebase, "", "CONFLICT")
|
||||
err = pull.Merge(git.DefaultContext, pr, user1, gitRepo, repo_model.MergeStyleRebase, "", "CONFLICT")
|
||||
assert.Error(t, err, "Merge should return an error due to conflict")
|
||||
assert.True(t, models.IsErrRebaseConflicts(err), "Merge error is not a conflict error")
|
||||
gitRepo.Close()
|
||||
@@ -329,7 +329,7 @@ func TestCantMergeUnrelated(t *testing.T) {
|
||||
BaseBranch: "base",
|
||||
}).(*models.PullRequest)
|
||||
|
||||
err = pull.Merge(pr, user1, gitRepo, repo_model.MergeStyleMerge, "", "UNRELATED")
|
||||
err = pull.Merge(git.DefaultContext, pr, user1, gitRepo, repo_model.MergeStyleMerge, "", "UNRELATED")
|
||||
assert.Error(t, err, "Merge should return an error due to unrelated")
|
||||
assert.True(t, models.IsErrMergeUnrelatedHistories(err), "Merge error is not a unrelated histories error")
|
||||
gitRepo.Close()
|
||||
|
@@ -13,6 +13,7 @@ import (
|
||||
"code.gitea.io/gitea/models"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
pull_service "code.gitea.io/gitea/services/pull"
|
||||
repo_service "code.gitea.io/gitea/services/repository"
|
||||
files_service "code.gitea.io/gitea/services/repository/files"
|
||||
@@ -28,7 +29,7 @@ func TestAPIPullUpdate(t *testing.T) {
|
||||
pr := createOutdatedPR(t, user, org26)
|
||||
|
||||
//Test GetDiverging
|
||||
diffCount, err := pull_service.GetDiverging(pr)
|
||||
diffCount, err := pull_service.GetDiverging(git.DefaultContext, pr)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, diffCount.Behind)
|
||||
assert.EqualValues(t, 1, diffCount.Ahead)
|
||||
@@ -41,7 +42,7 @@ func TestAPIPullUpdate(t *testing.T) {
|
||||
session.MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
//Test GetDiverging after update
|
||||
diffCount, err = pull_service.GetDiverging(pr)
|
||||
diffCount, err = pull_service.GetDiverging(git.DefaultContext, pr)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 0, diffCount.Behind)
|
||||
assert.EqualValues(t, 2, diffCount.Ahead)
|
||||
@@ -56,7 +57,7 @@ func TestAPIPullUpdateByRebase(t *testing.T) {
|
||||
pr := createOutdatedPR(t, user, org26)
|
||||
|
||||
//Test GetDiverging
|
||||
diffCount, err := pull_service.GetDiverging(pr)
|
||||
diffCount, err := pull_service.GetDiverging(git.DefaultContext, pr)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 1, diffCount.Behind)
|
||||
assert.EqualValues(t, 1, diffCount.Ahead)
|
||||
@@ -69,7 +70,7 @@ func TestAPIPullUpdateByRebase(t *testing.T) {
|
||||
session.MakeRequest(t, req, http.StatusOK)
|
||||
|
||||
//Test GetDiverging after update
|
||||
diffCount, err = pull_service.GetDiverging(pr)
|
||||
diffCount, err = pull_service.GetDiverging(git.DefaultContext, pr)
|
||||
assert.NoError(t, err)
|
||||
assert.EqualValues(t, 0, diffCount.Behind)
|
||||
assert.EqualValues(t, 1, diffCount.Ahead)
|
||||
@@ -98,7 +99,7 @@ func createOutdatedPR(t *testing.T, actor, forkOrg *user_model.User) *models.Pul
|
||||
assert.NotEmpty(t, headRepo)
|
||||
|
||||
//create a commit on base Repo
|
||||
_, err = files_service.CreateOrUpdateRepoFile(baseRepo, actor, &files_service.UpdateRepoFileOptions{
|
||||
_, err = files_service.CreateOrUpdateRepoFile(git.DefaultContext, baseRepo, actor, &files_service.UpdateRepoFileOptions{
|
||||
TreePath: "File_A",
|
||||
Message: "Add File A",
|
||||
Content: "File A",
|
||||
@@ -121,7 +122,7 @@ func createOutdatedPR(t *testing.T, actor, forkOrg *user_model.User) *models.Pul
|
||||
assert.NoError(t, err)
|
||||
|
||||
//create a commit on head Repo
|
||||
_, err = files_service.CreateOrUpdateRepoFile(headRepo, actor, &files_service.UpdateRepoFileOptions{
|
||||
_, err = files_service.CreateOrUpdateRepoFile(git.DefaultContext, headRepo, actor, &files_service.UpdateRepoFileOptions{
|
||||
TreePath: "File_B",
|
||||
Message: "Add File on PR branch",
|
||||
Content: "File B",
|
||||
@@ -160,7 +161,7 @@ func createOutdatedPR(t *testing.T, actor, forkOrg *user_model.User) *models.Pul
|
||||
BaseRepo: baseRepo,
|
||||
Type: models.PullRequestGitea,
|
||||
}
|
||||
err = pull_service.NewPullRequest(baseRepo, pullIssue, nil, nil, pullRequest, nil)
|
||||
err = pull_service.NewPullRequest(git.DefaultContext, baseRepo, pullIssue, nil, nil, pullRequest, nil)
|
||||
assert.NoError(t, err)
|
||||
|
||||
issue := unittest.AssertExistsAndLoadBean(t, &models.Issue{Title: "Test Pull -to-update-"}).(*models.Issue)
|
||||
|
@@ -29,7 +29,7 @@ func TestCreateNewTagProtected(t *testing.T) {
|
||||
t.Run("API", func(t *testing.T) {
|
||||
defer PrintCurrentTest(t)()
|
||||
|
||||
err := release.CreateNewTag(owner, repo, "master", "v-1", "first tag")
|
||||
err := release.CreateNewTag(git.DefaultContext, owner, repo, "master", "v-1", "first tag")
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = models.InsertProtectedTag(&models.ProtectedTag{
|
||||
@@ -44,11 +44,11 @@ func TestCreateNewTagProtected(t *testing.T) {
|
||||
})
|
||||
assert.NoError(t, err)
|
||||
|
||||
err = release.CreateNewTag(owner, repo, "master", "v-2", "second tag")
|
||||
err = release.CreateNewTag(git.DefaultContext, owner, repo, "master", "v-2", "second tag")
|
||||
assert.Error(t, err)
|
||||
assert.True(t, models.IsErrProtectedTagName(err))
|
||||
|
||||
err = release.CreateNewTag(owner, repo, "master", "v-1.1", "third tag")
|
||||
err = release.CreateNewTag(git.DefaultContext, owner, repo, "master", "v-1.1", "third tag")
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
|
@@ -10,6 +10,7 @@ import (
|
||||
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
api "code.gitea.io/gitea/modules/structs"
|
||||
"code.gitea.io/gitea/modules/test"
|
||||
files_service "code.gitea.io/gitea/services/repository/files"
|
||||
@@ -80,7 +81,7 @@ func testDeleteRepoFile(t *testing.T, u *url.URL) {
|
||||
opts := getDeleteRepoFileOptions(repo)
|
||||
|
||||
t.Run("Delete README.md file", func(t *testing.T) {
|
||||
fileResponse, err := files_service.DeleteRepoFile(repo, doer, opts)
|
||||
fileResponse, err := files_service.DeleteRepoFile(git.DefaultContext, repo, doer, opts)
|
||||
assert.NoError(t, err)
|
||||
expectedFileResponse := getExpectedDeleteFileResponse(u)
|
||||
assert.NotNil(t, fileResponse)
|
||||
@@ -92,7 +93,7 @@ func testDeleteRepoFile(t *testing.T, u *url.URL) {
|
||||
})
|
||||
|
||||
t.Run("Verify README.md has been deleted", func(t *testing.T) {
|
||||
fileResponse, err := files_service.DeleteRepoFile(repo, doer, opts)
|
||||
fileResponse, err := files_service.DeleteRepoFile(git.DefaultContext, repo, doer, opts)
|
||||
assert.Nil(t, fileResponse)
|
||||
expectedError := "repository file does not exist [path: " + opts.TreePath + "]"
|
||||
assert.EqualError(t, err, expectedError)
|
||||
@@ -122,7 +123,7 @@ func testDeleteRepoFileWithoutBranchNames(t *testing.T, u *url.URL) {
|
||||
opts.NewBranch = ""
|
||||
|
||||
t.Run("Delete README.md without Branch Name", func(t *testing.T) {
|
||||
fileResponse, err := files_service.DeleteRepoFile(repo, doer, opts)
|
||||
fileResponse, err := files_service.DeleteRepoFile(git.DefaultContext, repo, doer, opts)
|
||||
assert.NoError(t, err)
|
||||
expectedFileResponse := getExpectedDeleteFileResponse(u)
|
||||
assert.NotNil(t, fileResponse)
|
||||
@@ -151,7 +152,7 @@ func TestDeleteRepoFileErrors(t *testing.T) {
|
||||
t.Run("Bad branch", func(t *testing.T) {
|
||||
opts := getDeleteRepoFileOptions(repo)
|
||||
opts.OldBranch = "bad_branch"
|
||||
fileResponse, err := files_service.DeleteRepoFile(repo, doer, opts)
|
||||
fileResponse, err := files_service.DeleteRepoFile(git.DefaultContext, repo, doer, opts)
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, fileResponse)
|
||||
expectedError := "branch does not exist [name: " + opts.OldBranch + "]"
|
||||
@@ -162,7 +163,7 @@ func TestDeleteRepoFileErrors(t *testing.T) {
|
||||
opts := getDeleteRepoFileOptions(repo)
|
||||
origSHA := opts.SHA
|
||||
opts.SHA = "bad_sha"
|
||||
fileResponse, err := files_service.DeleteRepoFile(repo, doer, opts)
|
||||
fileResponse, err := files_service.DeleteRepoFile(git.DefaultContext, repo, doer, opts)
|
||||
assert.Nil(t, fileResponse)
|
||||
assert.Error(t, err)
|
||||
expectedError := "sha does not match [given: " + opts.SHA + ", expected: " + origSHA + "]"
|
||||
@@ -172,7 +173,7 @@ func TestDeleteRepoFileErrors(t *testing.T) {
|
||||
t.Run("New branch already exists", func(t *testing.T) {
|
||||
opts := getDeleteRepoFileOptions(repo)
|
||||
opts.NewBranch = "develop"
|
||||
fileResponse, err := files_service.DeleteRepoFile(repo, doer, opts)
|
||||
fileResponse, err := files_service.DeleteRepoFile(git.DefaultContext, repo, doer, opts)
|
||||
assert.Nil(t, fileResponse)
|
||||
assert.Error(t, err)
|
||||
expectedError := "branch already exists [name: " + opts.NewBranch + "]"
|
||||
@@ -182,7 +183,7 @@ func TestDeleteRepoFileErrors(t *testing.T) {
|
||||
t.Run("TreePath is empty:", func(t *testing.T) {
|
||||
opts := getDeleteRepoFileOptions(repo)
|
||||
opts.TreePath = ""
|
||||
fileResponse, err := files_service.DeleteRepoFile(repo, doer, opts)
|
||||
fileResponse, err := files_service.DeleteRepoFile(git.DefaultContext, repo, doer, opts)
|
||||
assert.Nil(t, fileResponse)
|
||||
assert.Error(t, err)
|
||||
expectedError := "path contains a malformed path component [path: ]"
|
||||
@@ -192,7 +193,7 @@ func TestDeleteRepoFileErrors(t *testing.T) {
|
||||
t.Run("TreePath is a git directory:", func(t *testing.T) {
|
||||
opts := getDeleteRepoFileOptions(repo)
|
||||
opts.TreePath = ".git"
|
||||
fileResponse, err := files_service.DeleteRepoFile(repo, doer, opts)
|
||||
fileResponse, err := files_service.DeleteRepoFile(git.DefaultContext, repo, doer, opts)
|
||||
assert.Nil(t, fileResponse)
|
||||
assert.Error(t, err)
|
||||
expectedError := "path contains a malformed path component [path: " + opts.TreePath + "]"
|
||||
|
@@ -198,7 +198,7 @@ func TestCreateOrUpdateRepoFileForCreate(t *testing.T) {
|
||||
opts := getCreateRepoFileOptions(repo)
|
||||
|
||||
// test
|
||||
fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts)
|
||||
fileResponse, err := files_service.CreateOrUpdateRepoFile(git.DefaultContext, repo, doer, opts)
|
||||
|
||||
// asserts
|
||||
assert.NoError(t, err)
|
||||
@@ -234,7 +234,7 @@ func TestCreateOrUpdateRepoFileForUpdate(t *testing.T) {
|
||||
opts := getUpdateRepoFileOptions(repo)
|
||||
|
||||
// test
|
||||
fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts)
|
||||
fileResponse, err := files_service.CreateOrUpdateRepoFile(git.DefaultContext, repo, doer, opts)
|
||||
|
||||
// asserts
|
||||
assert.NoError(t, err)
|
||||
@@ -269,7 +269,7 @@ func TestCreateOrUpdateRepoFileForUpdateWithFileMove(t *testing.T) {
|
||||
opts.TreePath = "README_new.md" // new file name, README_new.md
|
||||
|
||||
// test
|
||||
fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts)
|
||||
fileResponse, err := files_service.CreateOrUpdateRepoFile(git.DefaultContext, repo, doer, opts)
|
||||
|
||||
// asserts
|
||||
assert.NoError(t, err)
|
||||
@@ -319,7 +319,7 @@ func TestCreateOrUpdateRepoFileWithoutBranchNames(t *testing.T) {
|
||||
opts.NewBranch = ""
|
||||
|
||||
// test
|
||||
fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts)
|
||||
fileResponse, err := files_service.CreateOrUpdateRepoFile(git.DefaultContext, repo, doer, opts)
|
||||
|
||||
// asserts
|
||||
assert.NoError(t, err)
|
||||
@@ -349,7 +349,7 @@ func TestCreateOrUpdateRepoFileErrors(t *testing.T) {
|
||||
t.Run("bad branch", func(t *testing.T) {
|
||||
opts := getUpdateRepoFileOptions(repo)
|
||||
opts.OldBranch = "bad_branch"
|
||||
fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts)
|
||||
fileResponse, err := files_service.CreateOrUpdateRepoFile(git.DefaultContext, repo, doer, opts)
|
||||
assert.Error(t, err)
|
||||
assert.Nil(t, fileResponse)
|
||||
expectedError := "branch does not exist [name: " + opts.OldBranch + "]"
|
||||
@@ -360,7 +360,7 @@ func TestCreateOrUpdateRepoFileErrors(t *testing.T) {
|
||||
opts := getUpdateRepoFileOptions(repo)
|
||||
origSHA := opts.SHA
|
||||
opts.SHA = "bad_sha"
|
||||
fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts)
|
||||
fileResponse, err := files_service.CreateOrUpdateRepoFile(git.DefaultContext, repo, doer, opts)
|
||||
assert.Nil(t, fileResponse)
|
||||
assert.Error(t, err)
|
||||
expectedError := "sha does not match [given: " + opts.SHA + ", expected: " + origSHA + "]"
|
||||
@@ -370,7 +370,7 @@ func TestCreateOrUpdateRepoFileErrors(t *testing.T) {
|
||||
t.Run("new branch already exists", func(t *testing.T) {
|
||||
opts := getUpdateRepoFileOptions(repo)
|
||||
opts.NewBranch = "develop"
|
||||
fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts)
|
||||
fileResponse, err := files_service.CreateOrUpdateRepoFile(git.DefaultContext, repo, doer, opts)
|
||||
assert.Nil(t, fileResponse)
|
||||
assert.Error(t, err)
|
||||
expectedError := "branch already exists [name: " + opts.NewBranch + "]"
|
||||
@@ -380,7 +380,7 @@ func TestCreateOrUpdateRepoFileErrors(t *testing.T) {
|
||||
t.Run("treePath is empty:", func(t *testing.T) {
|
||||
opts := getUpdateRepoFileOptions(repo)
|
||||
opts.TreePath = ""
|
||||
fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts)
|
||||
fileResponse, err := files_service.CreateOrUpdateRepoFile(git.DefaultContext, repo, doer, opts)
|
||||
assert.Nil(t, fileResponse)
|
||||
assert.Error(t, err)
|
||||
expectedError := "path contains a malformed path component [path: ]"
|
||||
@@ -390,7 +390,7 @@ func TestCreateOrUpdateRepoFileErrors(t *testing.T) {
|
||||
t.Run("treePath is a git directory:", func(t *testing.T) {
|
||||
opts := getUpdateRepoFileOptions(repo)
|
||||
opts.TreePath = ".git"
|
||||
fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts)
|
||||
fileResponse, err := files_service.CreateOrUpdateRepoFile(git.DefaultContext, repo, doer, opts)
|
||||
assert.Nil(t, fileResponse)
|
||||
assert.Error(t, err)
|
||||
expectedError := "path contains a malformed path component [path: " + opts.TreePath + "]"
|
||||
@@ -400,7 +400,7 @@ func TestCreateOrUpdateRepoFileErrors(t *testing.T) {
|
||||
t.Run("create file that already exists", func(t *testing.T) {
|
||||
opts := getCreateRepoFileOptions(repo)
|
||||
opts.TreePath = "README.md" //already exists
|
||||
fileResponse, err := files_service.CreateOrUpdateRepoFile(repo, doer, opts)
|
||||
fileResponse, err := files_service.CreateOrUpdateRepoFile(git.DefaultContext, repo, doer, opts)
|
||||
assert.Nil(t, fileResponse)
|
||||
assert.Error(t, err)
|
||||
expectedError := "repository file already exists [path: " + opts.TreePath + "]"
|
||||
|
@@ -56,6 +56,7 @@ func CreateNotice(ctx context.Context, tp NoticeType, desc string, args ...inter
|
||||
|
||||
// CreateRepositoryNotice creates new system notice with type NoticeRepository.
|
||||
func CreateRepositoryNotice(desc string, args ...interface{}) error {
|
||||
// Note we use the db.DefaultContext here rather than passing in a context as the context may be cancelled
|
||||
return CreateNotice(db.DefaultContext, NoticeRepository, desc, args...)
|
||||
}
|
||||
|
||||
@@ -65,7 +66,8 @@ func RemoveAllWithNotice(ctx context.Context, title, path string) {
|
||||
if err := util.RemoveAll(path); err != nil {
|
||||
desc := fmt.Sprintf("%s [%s]: %v", title, path, err)
|
||||
log.Warn(title+" [%s]: %v", path, err)
|
||||
if err = CreateNotice(ctx, NoticeRepository, desc); err != nil {
|
||||
// Note we use the db.DefaultContext here rather than passing in a context as the context may be cancelled
|
||||
if err = CreateNotice(db.DefaultContext, NoticeRepository, desc); err != nil {
|
||||
log.Error("CreateRepositoryNotice: %v", err)
|
||||
}
|
||||
}
|
||||
@@ -77,7 +79,9 @@ func RemoveStorageWithNotice(ctx context.Context, bucket storage.ObjectStorage,
|
||||
if err := bucket.Delete(path); err != nil {
|
||||
desc := fmt.Sprintf("%s [%s]: %v", title, path, err)
|
||||
log.Warn(title+" [%s]: %v", path, err)
|
||||
if err = CreateNotice(ctx, NoticeRepository, desc); err != nil {
|
||||
|
||||
// Note we use the db.DefaultContext here rather than passing in a context as the context may be cancelled
|
||||
if err = CreateNotice(db.DefaultContext, NoticeRepository, desc); err != nil {
|
||||
log.Error("CreateRepositoryNotice: %v", err)
|
||||
}
|
||||
}
|
||||
|
@@ -35,7 +35,7 @@ type Context struct {
|
||||
func WithEngine(ctx context.Context, e Engine) *Context {
|
||||
return &Context{
|
||||
Context: ctx,
|
||||
e: e,
|
||||
e: e.Context(ctx),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,6 +52,11 @@ func (ctx *Context) Value(key interface{}) interface{} {
|
||||
return ctx.Context.Value(key)
|
||||
}
|
||||
|
||||
// WithContext returns this engine tied to this context
|
||||
func (ctx *Context) WithContext(other context.Context) *Context {
|
||||
return WithEngine(other, ctx.e)
|
||||
}
|
||||
|
||||
// Engined structs provide an Engine
|
||||
type Engined interface {
|
||||
Engine() Engine
|
||||
|
@@ -64,6 +64,7 @@ type Engine interface {
|
||||
Distinct(...string) *xorm.Session
|
||||
Query(...interface{}) ([]map[string][]byte, error)
|
||||
Cols(...string) *xorm.Session
|
||||
Context(ctx context.Context) *xorm.Session
|
||||
}
|
||||
|
||||
// TableInfo returns table's information via an object
|
||||
|
@@ -724,7 +724,7 @@ func (c *Comment) CodeCommentURL() string {
|
||||
}
|
||||
|
||||
// LoadPushCommits Load push commits
|
||||
func (c *Comment) LoadPushCommits() (err error) {
|
||||
func (c *Comment) LoadPushCommits(ctx context.Context) (err error) {
|
||||
if c.Content == "" || c.Commits != nil || c.Type != CommentTypePullPush {
|
||||
return nil
|
||||
}
|
||||
@@ -746,11 +746,11 @@ func (c *Comment) LoadPushCommits() (err error) {
|
||||
c.NewCommit = data.CommitIDs[1]
|
||||
} else {
|
||||
repoPath := c.Issue.Repo.RepoPath()
|
||||
gitRepo, err := git.OpenRepository(repoPath)
|
||||
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repoPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer gitRepo.Close()
|
||||
defer closer.Close()
|
||||
|
||||
c.Commits = ConvertFromGitCommit(gitRepo.GetCommitsFromIDs(data.CommitIDs), c.Issue.Repo)
|
||||
c.CommitsNum = int64(len(c.Commits))
|
||||
@@ -1272,6 +1272,7 @@ func findCodeComments(ctx context.Context, opts FindCommentsOptions, issue *Issu
|
||||
|
||||
var err error
|
||||
if comment.RenderedContent, err = markdown.RenderString(&markup.RenderContext{
|
||||
Ctx: ctx,
|
||||
URLPrefix: issue.Repo.Link(),
|
||||
Metas: issue.Repo.ComposeMetas(),
|
||||
}, comment.Content); err != nil {
|
||||
@@ -1282,19 +1283,19 @@ func findCodeComments(ctx context.Context, opts FindCommentsOptions, issue *Issu
|
||||
}
|
||||
|
||||
// FetchCodeCommentsByLine fetches the code comments for a given treePath and line number
|
||||
func FetchCodeCommentsByLine(issue *Issue, currentUser *user_model.User, treePath string, line int64) ([]*Comment, error) {
|
||||
func FetchCodeCommentsByLine(ctx context.Context, issue *Issue, currentUser *user_model.User, treePath string, line int64) ([]*Comment, error) {
|
||||
opts := FindCommentsOptions{
|
||||
Type: CommentTypeCode,
|
||||
IssueID: issue.ID,
|
||||
TreePath: treePath,
|
||||
Line: line,
|
||||
}
|
||||
return findCodeComments(db.DefaultContext, opts, issue, currentUser, nil)
|
||||
return findCodeComments(ctx, opts, issue, currentUser, nil)
|
||||
}
|
||||
|
||||
// FetchCodeComments will return a 2d-map: ["Path"]["Line"] = Comments at line
|
||||
func FetchCodeComments(issue *Issue, currentUser *user_model.User) (CodeComments, error) {
|
||||
return fetchCodeComments(db.DefaultContext, issue, currentUser)
|
||||
func FetchCodeComments(ctx context.Context, issue *Issue, currentUser *user_model.User) (CodeComments, error) {
|
||||
return fetchCodeComments(ctx, issue, currentUser)
|
||||
}
|
||||
|
||||
// UpdateCommentsMigrationsByType updates comments' migrations information via given git service type and original id and poster id
|
||||
@@ -1318,7 +1319,7 @@ func UpdateCommentsMigrationsByType(tp structs.GitServiceType, originalAuthorID
|
||||
}
|
||||
|
||||
// CreatePushPullComment create push code to pull base comment
|
||||
func CreatePushPullComment(pusher *user_model.User, pr *PullRequest, oldCommitID, newCommitID string) (comment *Comment, err error) {
|
||||
func CreatePushPullComment(ctx context.Context, pusher *user_model.User, pr *PullRequest, oldCommitID, newCommitID string) (comment *Comment, err error) {
|
||||
if pr.HasMerged || oldCommitID == "" || newCommitID == "" {
|
||||
return nil, nil
|
||||
}
|
||||
@@ -1331,7 +1332,7 @@ func CreatePushPullComment(pusher *user_model.User, pr *PullRequest, oldCommitID
|
||||
|
||||
var data PushActionContent
|
||||
|
||||
data.CommitIDs, data.IsForcePush, err = getCommitIDsFromRepo(pr.BaseRepo, oldCommitID, newCommitID, pr.BaseBranch)
|
||||
data.CommitIDs, data.IsForcePush, err = getCommitIDsFromRepo(ctx, pr.BaseRepo, oldCommitID, newCommitID, pr.BaseBranch)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -1353,13 +1354,13 @@ func CreatePushPullComment(pusher *user_model.User, pr *PullRequest, oldCommitID
|
||||
// getCommitsFromRepo get commit IDs from repo in between oldCommitID and newCommitID
|
||||
// isForcePush will be true if oldCommit isn't on the branch
|
||||
// Commit on baseBranch will skip
|
||||
func getCommitIDsFromRepo(repo *repo_model.Repository, oldCommitID, newCommitID, baseBranch string) (commitIDs []string, isForcePush bool, err error) {
|
||||
func getCommitIDsFromRepo(ctx context.Context, repo *repo_model.Repository, oldCommitID, newCommitID, baseBranch string) (commitIDs []string, isForcePush bool, err error) {
|
||||
repoPath := repo.RepoPath()
|
||||
gitRepo, err := git.OpenRepository(repoPath)
|
||||
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repoPath)
|
||||
if err != nil {
|
||||
return nil, false, err
|
||||
}
|
||||
defer gitRepo.Close()
|
||||
defer closer.Close()
|
||||
|
||||
oldCommit, err := gitRepo.GetCommit(oldCommitID)
|
||||
if err != nil {
|
||||
|
@@ -8,6 +8,7 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
@@ -49,7 +50,7 @@ func TestFetchCodeComments(t *testing.T) {
|
||||
|
||||
issue := unittest.AssertExistsAndLoadBean(t, &Issue{ID: 2}).(*Issue)
|
||||
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1}).(*user_model.User)
|
||||
res, err := FetchCodeComments(issue, user)
|
||||
res, err := FetchCodeComments(db.DefaultContext, issue, user)
|
||||
assert.NoError(t, err)
|
||||
assert.Contains(t, res, "README.md")
|
||||
assert.Contains(t, res["README.md"], int64(4))
|
||||
@@ -57,7 +58,7 @@ func TestFetchCodeComments(t *testing.T) {
|
||||
assert.Equal(t, int64(4), res["README.md"][4][0].ID)
|
||||
|
||||
user2 := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2}).(*user_model.User)
|
||||
res, err = FetchCodeComments(issue, user2)
|
||||
res, err = FetchCodeComments(db.DefaultContext, issue, user2)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, res, 1)
|
||||
}
|
||||
|
@@ -162,7 +162,7 @@ func testCreatePR(t *testing.T, repo, doer int64, title, content string) *PullRe
|
||||
d := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: doer}).(*user_model.User)
|
||||
i := &Issue{RepoID: r.ID, PosterID: d.ID, Poster: d, Title: title, Content: content, IsPull: true}
|
||||
pr := &PullRequest{HeadRepoID: repo, BaseRepoID: repo, HeadBranch: "head", BaseBranch: "base", Status: PullRequestStatusMergeable}
|
||||
assert.NoError(t, NewPullRequest(r, i, nil, nil, pr))
|
||||
assert.NoError(t, NewPullRequest(db.DefaultContext, r, i, nil, nil, pr))
|
||||
pr.Issue = i
|
||||
return pr
|
||||
}
|
||||
|
@@ -12,6 +12,7 @@ import (
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/graceful"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
|
||||
@@ -90,7 +91,7 @@ func addCommitDivergenceToPulls(x *xorm.Engine) error {
|
||||
|
||||
gitRefName := fmt.Sprintf("refs/pull/%d/head", pr.Index)
|
||||
|
||||
divergence, err := git.GetDivergingCommits(repoPath, pr.BaseBranch, gitRefName)
|
||||
divergence, err := git.GetDivergingCommits(graceful.GetManager().HammerContext(), repoPath, pr.BaseBranch, gitRefName)
|
||||
if err != nil {
|
||||
log.Warn("Could not recalculate Divergence for pull: %d", pr.ID)
|
||||
pr.CommitsAhead = 0
|
||||
|
@@ -109,7 +109,7 @@ func fixPublisherIDforTagReleases(x *xorm.Engine) error {
|
||||
return err
|
||||
}
|
||||
}
|
||||
gitRepo, err = git.OpenRepository(repoPath(repo.OwnerName, repo.Name))
|
||||
gitRepo, err = git.OpenRepositoryCtx(git.DefaultContext, repoPath(repo.OwnerName, repo.Name))
|
||||
if err != nil {
|
||||
log.Error("Error whilst opening git repo for [%d]%s/%s. Error: %v", repo.ID, repo.OwnerName, repo.Name, err)
|
||||
return err
|
||||
|
@@ -99,7 +99,7 @@ func fixReleaseSha1OnReleaseTable(x *xorm.Engine) error {
|
||||
userCache[repo.OwnerID] = user
|
||||
}
|
||||
|
||||
gitRepo, err = git.OpenRepository(RepoPath(user.Name, repo.Name))
|
||||
gitRepo, err = git.OpenRepositoryCtx(git.DefaultContext, RepoPath(user.Name, repo.Name))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@@ -436,7 +436,7 @@ func (pr *PullRequest) SetMerged() (bool, error) {
|
||||
}
|
||||
|
||||
// NewPullRequest creates new pull request with labels for repository.
|
||||
func NewPullRequest(repo *repo_model.Repository, issue *Issue, labelIDs []int64, uuids []string, pr *PullRequest) (err error) {
|
||||
func NewPullRequest(outerCtx context.Context, repo *repo_model.Repository, issue *Issue, labelIDs []int64, uuids []string, pr *PullRequest) (err error) {
|
||||
idx, err := db.GetNextResourceIndex("issue_index", repo.ID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("generate pull request index failed: %v", err)
|
||||
@@ -449,6 +449,7 @@ func NewPullRequest(repo *repo_model.Repository, issue *Issue, labelIDs []int64,
|
||||
return err
|
||||
}
|
||||
defer committer.Close()
|
||||
ctx.WithContext(outerCtx)
|
||||
|
||||
if err = newIssue(ctx, issue.Poster, NewIssueOptions{
|
||||
Repo: repo,
|
||||
|
@@ -485,8 +485,9 @@ func (repo *Repository) CanEnableEditor() bool {
|
||||
}
|
||||
|
||||
// DescriptionHTML does special handles to description and return HTML string.
|
||||
func (repo *Repository) DescriptionHTML() template.HTML {
|
||||
func (repo *Repository) DescriptionHTML(ctx context.Context) template.HTML {
|
||||
desc, err := markup.RenderDescriptionHTML(&markup.RenderContext{
|
||||
Ctx: ctx,
|
||||
URLPrefix: repo.HTMLURL(),
|
||||
Metas: repo.ComposeMetas(),
|
||||
}, repo.Description)
|
||||
|
@@ -5,6 +5,7 @@
|
||||
package models
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"sort"
|
||||
"time"
|
||||
@@ -43,7 +44,7 @@ type ActivityStats struct {
|
||||
}
|
||||
|
||||
// GetActivityStats return stats for repository at given time range
|
||||
func GetActivityStats(repo *repo_model.Repository, timeFrom time.Time, releases, issues, prs, code bool) (*ActivityStats, error) {
|
||||
func GetActivityStats(ctx context.Context, repo *repo_model.Repository, timeFrom time.Time, releases, issues, prs, code bool) (*ActivityStats, error) {
|
||||
stats := &ActivityStats{Code: &git.CodeActivityStats{}}
|
||||
if releases {
|
||||
if err := stats.FillReleases(repo.ID, timeFrom); err != nil {
|
||||
@@ -64,11 +65,11 @@ func GetActivityStats(repo *repo_model.Repository, timeFrom time.Time, releases,
|
||||
return nil, fmt.Errorf("FillUnresolvedIssues: %v", err)
|
||||
}
|
||||
if code {
|
||||
gitRepo, err := git.OpenRepository(repo.RepoPath())
|
||||
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("OpenRepository: %v", err)
|
||||
}
|
||||
defer gitRepo.Close()
|
||||
defer closer.Close()
|
||||
|
||||
code, err := gitRepo.GetCodeActivityStats(timeFrom, repo.DefaultBranch)
|
||||
if err != nil {
|
||||
@@ -80,12 +81,12 @@ func GetActivityStats(repo *repo_model.Repository, timeFrom time.Time, releases,
|
||||
}
|
||||
|
||||
// GetActivityStatsTopAuthors returns top author stats for git commits for all branches
|
||||
func GetActivityStatsTopAuthors(repo *repo_model.Repository, timeFrom time.Time, count int) ([]*ActivityAuthorData, error) {
|
||||
gitRepo, err := git.OpenRepository(repo.RepoPath())
|
||||
func GetActivityStatsTopAuthors(ctx context.Context, repo *repo_model.Repository, timeFrom time.Time, count int) ([]*ActivityAuthorData, error) {
|
||||
gitRepo, closer, err := git.RepositoryFromContextOrOpen(ctx, repo.RepoPath())
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("OpenRepository: %v", err)
|
||||
}
|
||||
defer gitRepo.Close()
|
||||
defer closer.Close()
|
||||
|
||||
code, err := gitRepo.GetCodeActivityStats(timeFrom, "")
|
||||
if err != nil {
|
||||
|
@@ -86,7 +86,8 @@ func init() {
|
||||
db.RegisterModel(new(Review))
|
||||
}
|
||||
|
||||
func (r *Review) loadCodeComments(ctx context.Context) (err error) {
|
||||
// LoadCodeComments loads CodeComments
|
||||
func (r *Review) LoadCodeComments(ctx context.Context) (err error) {
|
||||
if r.CodeComments != nil {
|
||||
return
|
||||
}
|
||||
@@ -97,11 +98,6 @@ func (r *Review) loadCodeComments(ctx context.Context) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// LoadCodeComments loads CodeComments
|
||||
func (r *Review) LoadCodeComments() error {
|
||||
return r.loadCodeComments(db.DefaultContext)
|
||||
}
|
||||
|
||||
func (r *Review) loadIssue(e db.Engine) (err error) {
|
||||
if r.Issue != nil {
|
||||
return
|
||||
@@ -137,12 +133,13 @@ func (r *Review) LoadReviewerTeam() error {
|
||||
return r.loadReviewerTeam(db.GetEngine(db.DefaultContext))
|
||||
}
|
||||
|
||||
func (r *Review) loadAttributes(ctx context.Context) (err error) {
|
||||
// LoadAttributes loads all attributes except CodeComments
|
||||
func (r *Review) LoadAttributes(ctx context.Context) (err error) {
|
||||
e := db.GetEngine(ctx)
|
||||
if err = r.loadIssue(e); err != nil {
|
||||
return
|
||||
}
|
||||
if err = r.loadCodeComments(ctx); err != nil {
|
||||
if err = r.LoadCodeComments(ctx); err != nil {
|
||||
return
|
||||
}
|
||||
if err = r.loadReviewer(e); err != nil {
|
||||
@@ -154,11 +151,6 @@ func (r *Review) loadAttributes(ctx context.Context) (err error) {
|
||||
return
|
||||
}
|
||||
|
||||
// LoadAttributes loads all attributes except CodeComments
|
||||
func (r *Review) LoadAttributes() error {
|
||||
return r.loadAttributes(db.DefaultContext)
|
||||
}
|
||||
|
||||
func getReviewByID(e db.Engine, id int64) (*Review, error) {
|
||||
review := new(Review)
|
||||
if has, err := e.ID(id).Get(review); err != nil {
|
||||
@@ -405,7 +397,7 @@ func SubmitReview(doer *user_model.User, issue *Issue, reviewType ReviewType, co
|
||||
return nil, nil, err
|
||||
}
|
||||
} else {
|
||||
if err := review.loadCodeComments(ctx); err != nil {
|
||||
if err := review.LoadCodeComments(ctx); err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
if reviewType != ReviewTypeApprove && len(review.CodeComments) == 0 && len(strings.TrimSpace(content)) == 0 {
|
||||
|
@@ -7,6 +7,7 @@ package models
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/unittest"
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
|
||||
@@ -28,23 +29,23 @@ func TestGetReviewByID(t *testing.T) {
|
||||
func TestReview_LoadAttributes(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
review := unittest.AssertExistsAndLoadBean(t, &Review{ID: 1}).(*Review)
|
||||
assert.NoError(t, review.LoadAttributes())
|
||||
assert.NoError(t, review.LoadAttributes(db.DefaultContext))
|
||||
assert.NotNil(t, review.Issue)
|
||||
assert.NotNil(t, review.Reviewer)
|
||||
|
||||
invalidReview1 := unittest.AssertExistsAndLoadBean(t, &Review{ID: 2}).(*Review)
|
||||
assert.Error(t, invalidReview1.LoadAttributes())
|
||||
assert.Error(t, invalidReview1.LoadAttributes(db.DefaultContext))
|
||||
|
||||
invalidReview2 := unittest.AssertExistsAndLoadBean(t, &Review{ID: 3}).(*Review)
|
||||
assert.Error(t, invalidReview2.LoadAttributes())
|
||||
assert.Error(t, invalidReview2.LoadAttributes(db.DefaultContext))
|
||||
}
|
||||
|
||||
func TestReview_LoadCodeComments(t *testing.T) {
|
||||
assert.NoError(t, unittest.PrepareTestDatabase())
|
||||
|
||||
review := unittest.AssertExistsAndLoadBean(t, &Review{ID: 4}).(*Review)
|
||||
assert.NoError(t, review.LoadAttributes())
|
||||
assert.NoError(t, review.LoadCodeComments())
|
||||
assert.NoError(t, review.LoadAttributes(db.DefaultContext))
|
||||
assert.NoError(t, review.LoadCodeComments(db.DefaultContext))
|
||||
assert.Len(t, review.CodeComments, 1)
|
||||
assert.Equal(t, int64(4), review.CodeComments["README.md"][int64(4)][0].Line)
|
||||
}
|
||||
|
@@ -303,6 +303,7 @@ func APIContexter() func(http.Handler) http.Handler {
|
||||
ctx.Resp.Header().Set(`X-Frame-Options`, setting.CORSConfig.XFrameOptions)
|
||||
|
||||
ctx.Data["CsrfToken"] = html.EscapeString(ctx.csrf.GetToken())
|
||||
ctx.Data["Context"] = &ctx
|
||||
|
||||
next.ServeHTTP(ctx.Resp, ctx.Req)
|
||||
|
||||
@@ -321,35 +322,32 @@ func APIContexter() func(http.Handler) http.Handler {
|
||||
}
|
||||
|
||||
// ReferencesGitRepo injects the GitRepo into the Context
|
||||
func ReferencesGitRepo(allowEmpty bool) func(http.Handler) http.Handler {
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
|
||||
ctx := GetAPIContext(req)
|
||||
// Empty repository does not have reference information.
|
||||
if !allowEmpty && ctx.Repo.Repository.IsEmpty {
|
||||
func ReferencesGitRepo(allowEmpty bool) func(ctx *APIContext) (cancel context.CancelFunc) {
|
||||
return func(ctx *APIContext) (cancel context.CancelFunc) {
|
||||
// Empty repository does not have reference information.
|
||||
if !allowEmpty && ctx.Repo.Repository.IsEmpty {
|
||||
return
|
||||
}
|
||||
|
||||
// For API calls.
|
||||
if ctx.Repo.GitRepo == nil {
|
||||
repoPath := repo_model.RepoPath(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
|
||||
gitRepo, err := git.OpenRepositoryCtx(ctx, repoPath)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "RepoRef Invalid repo "+repoPath, err)
|
||||
return
|
||||
}
|
||||
|
||||
// For API calls.
|
||||
if ctx.Repo.GitRepo == nil {
|
||||
repoPath := repo_model.RepoPath(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
|
||||
gitRepo, err := git.OpenRepository(repoPath)
|
||||
if err != nil {
|
||||
ctx.Error(http.StatusInternalServerError, "RepoRef Invalid repo "+repoPath, err)
|
||||
return
|
||||
ctx.Repo.GitRepo = gitRepo
|
||||
// We opened it, we should close it
|
||||
return func() {
|
||||
// If it's been set to nil then assume someone else has closed it.
|
||||
if ctx.Repo.GitRepo != nil {
|
||||
ctx.Repo.GitRepo.Close()
|
||||
}
|
||||
ctx.Repo.GitRepo = gitRepo
|
||||
// We opened it, we should close it
|
||||
defer func() {
|
||||
// If it's been set to nil then assume someone else has closed it.
|
||||
if ctx.Repo.GitRepo != nil {
|
||||
ctx.Repo.GitRepo.Close()
|
||||
}
|
||||
}()
|
||||
}
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, req)
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
@@ -391,7 +389,7 @@ func RepoRefForAPI(next http.Handler) http.Handler {
|
||||
|
||||
if ctx.Repo.GitRepo == nil {
|
||||
repoPath := repo_model.RepoPath(ctx.Repo.Owner.Name, ctx.Repo.Repository.Name)
|
||||
ctx.Repo.GitRepo, err = git.OpenRepository(repoPath)
|
||||
ctx.Repo.GitRepo, err = git.OpenRepositoryCtx(ctx, repoPath)
|
||||
if err != nil {
|
||||
ctx.InternalServerError(err)
|
||||
return
|
||||
|
@@ -23,6 +23,7 @@ import (
|
||||
user_model "code.gitea.io/gitea/models/user"
|
||||
"code.gitea.io/gitea/modules/base"
|
||||
mc "code.gitea.io/gitea/modules/cache"
|
||||
"code.gitea.io/gitea/modules/git"
|
||||
"code.gitea.io/gitea/modules/json"
|
||||
"code.gitea.io/gitea/modules/log"
|
||||
"code.gitea.io/gitea/modules/setting"
|
||||
@@ -529,6 +530,10 @@ func (ctx *Context) Err() error {
|
||||
|
||||
// Value is part of the interface for context.Context and we pass this to the request context
|
||||
func (ctx *Context) Value(key interface{}) interface{} {
|
||||
if key == git.RepositoryContextKey && ctx.Repo != nil {
|
||||
return ctx.Repo.GitRepo
|
||||
}
|
||||
|
||||
return ctx.Req.Context().Value(key)
|
||||
}
|
||||
|
||||
@@ -631,6 +636,7 @@ func Contexter() func(next http.Handler) http.Handler {
|
||||
// PageData is passed by reference, and it will be rendered to `window.config.pageData` in `head.tmpl` for JavaScript modules
|
||||
ctx.PageData = map[string]interface{}{}
|
||||
ctx.Data["PageData"] = ctx.PageData
|
||||
ctx.Data["Context"] = &ctx
|
||||
|
||||
ctx.Req = WithContext(req, &ctx)
|
||||
ctx.csrf = Csrfer(csrfOpts, &ctx)
|
||||
|
@@ -6,12 +6,42 @@ package context
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/graceful"
|
||||
"code.gitea.io/gitea/modules/process"
|
||||
)
|
||||
|
||||
// PrivateContext represents a context for private routes
|
||||
type PrivateContext struct {
|
||||
*Context
|
||||
Override context.Context
|
||||
}
|
||||
|
||||
// Deadline is part of the interface for context.Context and we pass this to the request context
|
||||
func (ctx *PrivateContext) Deadline() (deadline time.Time, ok bool) {
|
||||
if ctx.Override != nil {
|
||||
return ctx.Override.Deadline()
|
||||
}
|
||||
return ctx.Req.Context().Deadline()
|
||||
}
|
||||
|
||||
// Done is part of the interface for context.Context and we pass this to the request context
|
||||
func (ctx *PrivateContext) Done() <-chan struct{} {
|
||||
if ctx.Override != nil {
|
||||
return ctx.Override.Done()
|
||||
}
|
||||
return ctx.Req.Context().Done()
|
||||
}
|
||||
|
||||
// Err is part of the interface for context.Context and we pass this to the request context
|
||||
func (ctx *PrivateContext) Err() error {
|
||||
if ctx.Override != nil {
|
||||
return ctx.Override.Err()
|
||||
}
|
||||
return ctx.Req.Context().Err()
|
||||
}
|
||||
|
||||
var (
|
||||
@@ -39,7 +69,18 @@ func PrivateContexter() func(http.Handler) http.Handler {
|
||||
},
|
||||
}
|
||||
ctx.Req = WithPrivateContext(req, ctx)
|
||||
ctx.Data["Context"] = ctx
|
||||
next.ServeHTTP(ctx.Resp, ctx.Req)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// OverrideContext overrides the underlying request context for Done() etc.
|
||||
// This function should be used when there is a need for work to continue even if the request has been cancelled.
|
||||
// Primarily this affects hook/post-receive and hook/proc-receive both of which need to continue working even if
|
||||
// the underlying request has timed out from the ssh/http push
|
||||
func OverrideContext(ctx *PrivateContext) (cancel context.CancelFunc) {
|
||||
// We now need to override the request context as the base for our work because even if the request is cancelled we have to continue this work
|
||||
ctx.Override, _, cancel = process.GetManager().AddContext(graceful.GetManager().HammerContext(), fmt.Sprintf("PrivateContext: %s", ctx.Req.RequestURI))
|
||||
return
|
||||
}
|
||||
|
@@ -109,7 +109,7 @@ type CanCommitToBranchResults struct {
|
||||
|
||||
// CanCommitToBranch returns true if repository is editable and user has proper access level
|
||||
// and branch is not protected for push
|
||||
func (r *Repository) CanCommitToBranch(doer *user_model.User) (CanCommitToBranchResults, error) {
|
||||
func (r *Repository) CanCommitToBranch(ctx context.Context, doer *user_model.User) (CanCommitToBranchResults, error) {
|
||||
protectedBranch, err := models.GetProtectedBranchBy(r.Repository.ID, r.BranchName)
|
||||
|
||||
if err != nil {
|
||||
@@ -122,7 +122,7 @@ func (r *Repository) CanCommitToBranch(doer *user_model.User) (CanCommitToBranch
|
||||
requireSigned = protectedBranch.RequireSignedCommits
|
||||
}
|
||||
|
||||
sign, keyID, _, err := asymkey_service.SignCRUDAction(r.Repository.RepoPath(), doer, r.Repository.RepoPath(), git.BranchPrefix+r.BranchName)
|
||||
sign, keyID, _, err := asymkey_service.SignCRUDAction(ctx, r.Repository.RepoPath(), doer, r.Repository.RepoPath(), git.BranchPrefix+r.BranchName)
|
||||
|
||||
canCommit := r.CanEnableEditor() && userCanPush
|
||||
if requireSigned {
|
||||
@@ -180,14 +180,14 @@ func (r *Repository) GetCommitsCount() (int64, error) {
|
||||
}
|
||||
|
||||
// GetCommitGraphsCount returns cached commit count for current view
|
||||
func (r *Repository) GetCommitGraphsCount(hidePRRefs bool, branches, files []string) (int64, error) {
|
||||
func (r *Repository) GetCommitGraphsCount(ctx context.Context, hidePRRefs bool, branches, files []string) (int64, error) {
|
||||
cacheKey := fmt.Sprintf("commits-count-%d-graph-%t-%s-%s", r.Repository.ID, hidePRRefs, branches, files)
|
||||
|
||||
return cache.GetInt64(cacheKey, func() (int64, error) {
|
||||
if len(branches) == 0 {
|
||||
return git.AllCommitsCount(r.Repository.RepoPath(), hidePRRefs, files...)
|
||||
return git.AllCommitsCount(ctx, r.Repository.RepoPath(), hidePRRefs, files...)
|
||||
}
|
||||
return git.CommitsCountFiles(r.Repository.RepoPath(), branches, files)
|
||||
return git.CommitsCountFiles(ctx, r.Repository.RepoPath(), branches, files)
|
||||
})
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user