mirror of
https://codeberg.org/forgejo/forgejo.git
synced 2025-05-31 11:52:10 +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:
parent
4563148a61
commit
5cb0c9aa0d
193 changed files with 1264 additions and 1154 deletions
|
@ -5,6 +5,7 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"time"
|
||||
|
@ -48,7 +49,7 @@ func NewPushCommits() *PushCommits {
|
|||
}
|
||||
|
||||
// toAPIPayloadCommit converts a single PushCommit to an api.PayloadCommit object.
|
||||
func (pc *PushCommits) toAPIPayloadCommit(repoPath, repoLink string, commit *PushCommit) (*api.PayloadCommit, error) {
|
||||
func (pc *PushCommits) toAPIPayloadCommit(ctx context.Context, repoPath, repoLink string, commit *PushCommit) (*api.PayloadCommit, error) {
|
||||
var err error
|
||||
authorUsername := ""
|
||||
author, ok := pc.emailUsers[commit.AuthorEmail]
|
||||
|
@ -75,7 +76,7 @@ func (pc *PushCommits) toAPIPayloadCommit(repoPath, repoLink string, commit *Pus
|
|||
committerUsername = committer.Name
|
||||
}
|
||||
|
||||
fileStatus, err := git.GetCommitFileStatus(repoPath, commit.Sha1)
|
||||
fileStatus, err := git.GetCommitFileStatus(ctx, repoPath, commit.Sha1)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("FileStatus [commit_sha1: %s]: %v", commit.Sha1, err)
|
||||
}
|
||||
|
@ -103,7 +104,7 @@ func (pc *PushCommits) toAPIPayloadCommit(repoPath, repoLink string, commit *Pus
|
|||
|
||||
// ToAPIPayloadCommits converts a PushCommits object to api.PayloadCommit format.
|
||||
// It returns all converted commits and, if provided, the head commit or an error otherwise.
|
||||
func (pc *PushCommits) ToAPIPayloadCommits(repoPath, repoLink string) ([]*api.PayloadCommit, *api.PayloadCommit, error) {
|
||||
func (pc *PushCommits) ToAPIPayloadCommits(ctx context.Context, repoPath, repoLink string) ([]*api.PayloadCommit, *api.PayloadCommit, error) {
|
||||
commits := make([]*api.PayloadCommit, len(pc.Commits))
|
||||
var headCommit *api.PayloadCommit
|
||||
|
||||
|
@ -111,7 +112,7 @@ func (pc *PushCommits) ToAPIPayloadCommits(repoPath, repoLink string) ([]*api.Pa
|
|||
pc.emailUsers = make(map[string]*user_model.User)
|
||||
}
|
||||
for i, commit := range pc.Commits {
|
||||
apiCommit, err := pc.toAPIPayloadCommit(repoPath, repoLink, commit)
|
||||
apiCommit, err := pc.toAPIPayloadCommit(ctx, repoPath, repoLink, commit)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
@ -123,7 +124,7 @@ func (pc *PushCommits) ToAPIPayloadCommits(repoPath, repoLink string) ([]*api.Pa
|
|||
}
|
||||
if pc.HeadCommit != nil && headCommit == nil {
|
||||
var err error
|
||||
headCommit, err = pc.toAPIPayloadCommit(repoPath, repoLink, pc.HeadCommit)
|
||||
headCommit, err = pc.toAPIPayloadCommit(ctx, repoPath, repoLink, pc.HeadCommit)
|
||||
if err != nil {
|
||||
return nil, nil, err
|
||||
}
|
||||
|
|
|
@ -50,7 +50,7 @@ func TestPushCommits_ToAPIPayloadCommits(t *testing.T) {
|
|||
pushCommits.HeadCommit = &PushCommit{Sha1: "69554a6"}
|
||||
|
||||
repo := unittest.AssertExistsAndLoadBean(t, &repo_model.Repository{ID: 16}).(*repo_model.Repository)
|
||||
payloadCommits, headCommit, err := pushCommits.ToAPIPayloadCommits(repo.RepoPath(), "/user2/repo16")
|
||||
payloadCommits, headCommit, err := pushCommits.ToAPIPayloadCommits(git.DefaultContext, repo.RepoPath(), "/user2/repo16")
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, payloadCommits, 3)
|
||||
assert.NotNil(t, headCommit)
|
||||
|
|
|
@ -99,7 +99,7 @@ func checkGiteaTemplate(tmpDir string) (*models.GiteaTemplate, error) {
|
|||
return gt, nil
|
||||
}
|
||||
|
||||
func generateRepoCommit(repo, templateRepo, generateRepo *repo_model.Repository, tmpDir string) error {
|
||||
func generateRepoCommit(ctx context.Context, repo, templateRepo, generateRepo *repo_model.Repository, tmpDir string) error {
|
||||
commitTimeStr := time.Now().Format(time.RFC3339)
|
||||
authorSig := repo.Owner.NewGitSig()
|
||||
|
||||
|
@ -115,7 +115,7 @@ func generateRepoCommit(repo, templateRepo, generateRepo *repo_model.Repository,
|
|||
|
||||
// Clone to temporary path and do the init commit.
|
||||
templateRepoPath := templateRepo.RepoPath()
|
||||
if err := git.Clone(templateRepoPath, tmpDir, git.CloneRepoOptions{
|
||||
if err := git.Clone(ctx, templateRepoPath, tmpDir, git.CloneRepoOptions{
|
||||
Depth: 1,
|
||||
Branch: templateRepo.DefaultBranch,
|
||||
}); err != nil {
|
||||
|
@ -172,19 +172,19 @@ func generateRepoCommit(repo, templateRepo, generateRepo *repo_model.Repository,
|
|||
}
|
||||
}
|
||||
|
||||
if err := git.InitRepository(tmpDir, false); err != nil {
|
||||
if err := git.InitRepository(ctx, tmpDir, false); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
repoPath := repo.RepoPath()
|
||||
if stdout, err := git.NewCommand("remote", "add", "origin", repoPath).
|
||||
if stdout, err := git.NewCommandContext(ctx, "remote", "add", "origin", repoPath).
|
||||
SetDescription(fmt.Sprintf("generateRepoCommit (git remote add): %s to %s", templateRepoPath, tmpDir)).
|
||||
RunInDirWithEnv(tmpDir, env); err != nil {
|
||||
log.Error("Unable to add %v as remote origin to temporary repo to %s: stdout %s\nError: %v", repo, tmpDir, stdout, err)
|
||||
return fmt.Errorf("git remote add: %v", err)
|
||||
}
|
||||
|
||||
return initRepoCommit(tmpDir, repo, repo.Owner, templateRepo.DefaultBranch)
|
||||
return initRepoCommit(ctx, tmpDir, repo, repo.Owner, templateRepo.DefaultBranch)
|
||||
}
|
||||
|
||||
func generateGitContent(ctx context.Context, repo, templateRepo, generateRepo *repo_model.Repository) (err error) {
|
||||
|
@ -199,7 +199,7 @@ func generateGitContent(ctx context.Context, repo, templateRepo, generateRepo *r
|
|||
}
|
||||
}()
|
||||
|
||||
if err = generateRepoCommit(repo, templateRepo, generateRepo, tmpDir); err != nil {
|
||||
if err = generateRepoCommit(ctx, repo, templateRepo, generateRepo, tmpDir); err != nil {
|
||||
return fmt.Errorf("generateRepoCommit: %v", err)
|
||||
}
|
||||
|
||||
|
@ -209,7 +209,7 @@ func generateGitContent(ctx context.Context, repo, templateRepo, generateRepo *r
|
|||
}
|
||||
|
||||
repo.DefaultBranch = templateRepo.DefaultBranch
|
||||
gitRepo, err := git.OpenRepository(repo.RepoPath())
|
||||
gitRepo, err := git.OpenRepositoryCtx(ctx, repo.RepoPath())
|
||||
if err != nil {
|
||||
return fmt.Errorf("openRepository: %v", err)
|
||||
}
|
||||
|
@ -273,7 +273,7 @@ func GenerateRepository(ctx context.Context, doer, owner *user_model.User, templ
|
|||
}
|
||||
}
|
||||
|
||||
if err = checkInitRepository(owner.Name, generateRepo.Name); err != nil {
|
||||
if err = checkInitRepository(ctx, owner.Name, generateRepo.Name); err != nil {
|
||||
return generateRepo, err
|
||||
}
|
||||
|
||||
|
|
|
@ -40,7 +40,7 @@ func prepareRepoCommit(ctx context.Context, repo *repo_model.Repository, tmpDir,
|
|||
)
|
||||
|
||||
// Clone to temporary path and do the init commit.
|
||||
if stdout, err := git.NewCommand("clone", repoPath, tmpDir).
|
||||
if stdout, err := git.NewCommandContext(ctx, "clone", repoPath, tmpDir).
|
||||
SetDescription(fmt.Sprintf("prepareRepoCommit (git clone): %s to %s", repoPath, tmpDir)).
|
||||
RunInDirWithEnv("", env); err != nil {
|
||||
log.Error("Failed to clone from %v into %s: stdout: %s\nError: %v", repo, tmpDir, stdout, err)
|
||||
|
@ -103,7 +103,7 @@ func prepareRepoCommit(ctx context.Context, repo *repo_model.Repository, tmpDir,
|
|||
}
|
||||
|
||||
// initRepoCommit temporarily changes with work directory.
|
||||
func initRepoCommit(tmpPath string, repo *repo_model.Repository, u *user_model.User, defaultBranch string) (err error) {
|
||||
func initRepoCommit(ctx context.Context, tmpPath string, repo *repo_model.Repository, u *user_model.User, defaultBranch string) (err error) {
|
||||
commitTimeStr := time.Now().Format(time.RFC3339)
|
||||
|
||||
sig := u.NewGitSig()
|
||||
|
@ -117,7 +117,7 @@ func initRepoCommit(tmpPath string, repo *repo_model.Repository, u *user_model.U
|
|||
committerName := sig.Name
|
||||
committerEmail := sig.Email
|
||||
|
||||
if stdout, err := git.NewCommand("add", "--all").
|
||||
if stdout, err := git.NewCommandContext(ctx, "add", "--all").
|
||||
SetDescription(fmt.Sprintf("initRepoCommit (git add): %s", tmpPath)).
|
||||
RunInDir(tmpPath); err != nil {
|
||||
log.Error("git add --all failed: Stdout: %s\nError: %v", stdout, err)
|
||||
|
@ -135,7 +135,7 @@ func initRepoCommit(tmpPath string, repo *repo_model.Repository, u *user_model.U
|
|||
}
|
||||
|
||||
if git.CheckGitVersionAtLeast("1.7.9") == nil {
|
||||
sign, keyID, signer, _ := asymkey_service.SignInitialCommit(tmpPath, u)
|
||||
sign, keyID, signer, _ := asymkey_service.SignInitialCommit(ctx, tmpPath, u)
|
||||
if sign {
|
||||
args = append(args, "-S"+keyID)
|
||||
|
||||
|
@ -154,7 +154,7 @@ func initRepoCommit(tmpPath string, repo *repo_model.Repository, u *user_model.U
|
|||
"GIT_COMMITTER_EMAIL="+committerEmail,
|
||||
)
|
||||
|
||||
if stdout, err := git.NewCommand(args...).
|
||||
if stdout, err := git.NewCommandContext(ctx, args...).
|
||||
SetDescription(fmt.Sprintf("initRepoCommit (git commit): %s", tmpPath)).
|
||||
RunInDirWithEnv(tmpPath, env); err != nil {
|
||||
log.Error("Failed to commit: %v: Stdout: %s\nError: %v", args, stdout, err)
|
||||
|
@ -165,7 +165,7 @@ func initRepoCommit(tmpPath string, repo *repo_model.Repository, u *user_model.U
|
|||
defaultBranch = setting.Repository.DefaultBranch
|
||||
}
|
||||
|
||||
if stdout, err := git.NewCommand("push", "origin", "HEAD:"+defaultBranch).
|
||||
if stdout, err := git.NewCommandContext(ctx, "push", "origin", "HEAD:"+defaultBranch).
|
||||
SetDescription(fmt.Sprintf("initRepoCommit (git push): %s", tmpPath)).
|
||||
RunInDirWithEnv(tmpPath, models.InternalPushingEnvironment(u, repo)); err != nil {
|
||||
log.Error("Failed to push back to HEAD: Stdout: %s\nError: %v", stdout, err)
|
||||
|
@ -175,7 +175,7 @@ func initRepoCommit(tmpPath string, repo *repo_model.Repository, u *user_model.U
|
|||
return nil
|
||||
}
|
||||
|
||||
func checkInitRepository(owner, name string) (err error) {
|
||||
func checkInitRepository(ctx context.Context, owner, name string) (err error) {
|
||||
// Somehow the directory could exist.
|
||||
repoPath := repo_model.RepoPath(owner, name)
|
||||
isExist, err := util.IsExist(repoPath)
|
||||
|
@ -191,7 +191,7 @@ func checkInitRepository(owner, name string) (err error) {
|
|||
}
|
||||
|
||||
// Init git bare new repository.
|
||||
if err = git.InitRepository(repoPath, true); err != nil {
|
||||
if err = git.InitRepository(ctx, repoPath, true); err != nil {
|
||||
return fmt.Errorf("git.InitRepository: %v", err)
|
||||
} else if err = createDelegateHooks(repoPath); err != nil {
|
||||
return fmt.Errorf("createDelegateHooks: %v", err)
|
||||
|
@ -201,7 +201,7 @@ func checkInitRepository(owner, name string) (err error) {
|
|||
|
||||
// InitRepository initializes README and .gitignore if needed.
|
||||
func initRepository(ctx context.Context, repoPath string, u *user_model.User, repo *repo_model.Repository, opts models.CreateRepoOptions) (err error) {
|
||||
if err = checkInitRepository(repo.OwnerName, repo.Name); err != nil {
|
||||
if err = checkInitRepository(ctx, repo.OwnerName, repo.Name); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
@ -222,7 +222,7 @@ func initRepository(ctx context.Context, repoPath string, u *user_model.User, re
|
|||
}
|
||||
|
||||
// Apply changes and commit.
|
||||
if err = initRepoCommit(tmpDir, repo, u, opts.DefaultBranch); err != nil {
|
||||
if err = initRepoCommit(ctx, tmpDir, repo, u, opts.DefaultBranch); err != nil {
|
||||
return fmt.Errorf("initRepoCommit: %v", err)
|
||||
}
|
||||
}
|
||||
|
@ -241,7 +241,7 @@ func initRepository(ctx context.Context, repoPath string, u *user_model.User, re
|
|||
|
||||
if len(opts.DefaultBranch) > 0 {
|
||||
repo.DefaultBranch = opts.DefaultBranch
|
||||
gitRepo, err := git.OpenRepository(repo.RepoPath())
|
||||
gitRepo, err := git.OpenRepositoryCtx(ctx, repo.RepoPath())
|
||||
if err != nil {
|
||||
return fmt.Errorf("openRepository: %v", err)
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
package repository
|
||||
|
||||
import (
|
||||
"context"
|
||||
"strings"
|
||||
|
||||
repo_model "code.gitea.io/gitea/models/repo"
|
||||
|
@ -98,12 +99,12 @@ func (opts *PushUpdateOptions) RepoFullName() string {
|
|||
}
|
||||
|
||||
// IsForcePush detect if a push is a force push
|
||||
func IsForcePush(opts *PushUpdateOptions) (bool, error) {
|
||||
func IsForcePush(ctx context.Context, opts *PushUpdateOptions) (bool, error) {
|
||||
if !opts.IsUpdateBranch() {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
output, err := git.NewCommand("rev-list", "--max-count=1", opts.OldCommitID, "^"+opts.NewCommitID).
|
||||
output, err := git.NewCommandContext(ctx, "rev-list", "--max-count=1", opts.OldCommitID, "^"+opts.NewCommitID).
|
||||
RunInDir(repo_model.RepoPath(opts.RepoUserName, opts.RepoName))
|
||||
if err != nil {
|
||||
return false, err
|
||||
|
|
|
@ -36,11 +36,11 @@ var commonWikiURLSuffixes = []string{".wiki.git", ".git/wiki"}
|
|||
|
||||
// WikiRemoteURL returns accessible repository URL for wiki if exists.
|
||||
// Otherwise, it returns an empty string.
|
||||
func WikiRemoteURL(remote string) string {
|
||||
func WikiRemoteURL(ctx context.Context, remote string) string {
|
||||
remote = strings.TrimSuffix(remote, ".git")
|
||||
for _, suffix := range commonWikiURLSuffixes {
|
||||
wikiURL := remote + suffix
|
||||
if git.IsRepoURLAccessible(wikiURL) {
|
||||
if git.IsRepoURLAccessible(ctx, wikiURL) {
|
||||
return wikiURL
|
||||
}
|
||||
}
|
||||
|
@ -71,7 +71,7 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User,
|
|||
return repo, fmt.Errorf("Failed to remove %s: %v", repoPath, err)
|
||||
}
|
||||
|
||||
if err = git.CloneWithContext(ctx, opts.CloneAddr, repoPath, git.CloneRepoOptions{
|
||||
if err = git.Clone(ctx, opts.CloneAddr, repoPath, git.CloneRepoOptions{
|
||||
Mirror: true,
|
||||
Quiet: true,
|
||||
Timeout: migrateTimeout,
|
||||
|
@ -81,13 +81,13 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User,
|
|||
|
||||
if opts.Wiki {
|
||||
wikiPath := repo_model.WikiPath(u.Name, opts.RepoName)
|
||||
wikiRemotePath := WikiRemoteURL(opts.CloneAddr)
|
||||
wikiRemotePath := WikiRemoteURL(ctx, opts.CloneAddr)
|
||||
if len(wikiRemotePath) > 0 {
|
||||
if err := util.RemoveAll(wikiPath); err != nil {
|
||||
return repo, fmt.Errorf("Failed to remove %s: %v", wikiPath, err)
|
||||
}
|
||||
|
||||
if err = git.CloneWithContext(ctx, wikiRemotePath, wikiPath, git.CloneRepoOptions{
|
||||
if err = git.Clone(ctx, wikiRemotePath, wikiPath, git.CloneRepoOptions{
|
||||
Mirror: true,
|
||||
Quiet: true,
|
||||
Timeout: migrateTimeout,
|
||||
|
@ -116,7 +116,7 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User,
|
|||
return repo, fmt.Errorf("error in MigrateRepositoryGitData(git update-server-info): %v", err)
|
||||
}
|
||||
|
||||
gitRepo, err := git.OpenRepository(repoPath)
|
||||
gitRepo, err := git.OpenRepositoryCtx(ctx, repoPath)
|
||||
if err != nil {
|
||||
return repo, fmt.Errorf("OpenRepository: %v", err)
|
||||
}
|
||||
|
@ -196,7 +196,7 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User,
|
|||
repo.IsMirror = true
|
||||
err = models.UpdateRepository(repo, false)
|
||||
} else {
|
||||
repo, err = CleanUpMigrateInfo(repo)
|
||||
repo, err = CleanUpMigrateInfo(ctx, repo)
|
||||
}
|
||||
|
||||
return repo, err
|
||||
|
@ -217,7 +217,7 @@ func cleanUpMigrateGitConfig(configPath string) error {
|
|||
}
|
||||
|
||||
// CleanUpMigrateInfo finishes migrating repository and/or wiki with things that don't need to be done for mirrors.
|
||||
func CleanUpMigrateInfo(repo *repo_model.Repository) (*repo_model.Repository, error) {
|
||||
func CleanUpMigrateInfo(ctx context.Context, repo *repo_model.Repository) (*repo_model.Repository, error) {
|
||||
repoPath := repo.RepoPath()
|
||||
if err := createDelegateHooks(repoPath); err != nil {
|
||||
return repo, fmt.Errorf("createDelegateHooks: %v", err)
|
||||
|
@ -228,7 +228,7 @@ func CleanUpMigrateInfo(repo *repo_model.Repository) (*repo_model.Repository, er
|
|||
}
|
||||
}
|
||||
|
||||
_, err := git.NewCommand("remote", "rm", "origin").RunInDir(repoPath)
|
||||
_, err := git.NewCommandContext(ctx, "remote", "rm", "origin").RunInDir(repoPath)
|
||||
if err != nil && !strings.HasPrefix(err.Error(), "exit status 128 - fatal: No such remote ") {
|
||||
return repo, fmt.Errorf("CleanUpMigrateInfo: %v", err)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue