Use gitrepo's clone and push when possible (#36093)

1 Move `IsRepositoryModelOrDirExist` and `CheckCreateRepository` to
service layer
2 Use `gitrepo.Pushxxx` instead of `git.Push` when possible
3 use `gitrepo.Clonexxx` instead of `gitrepo.Clone` when possible
This commit is contained in:
Lunny Xiao
2025-12-10 09:41:01 -08:00
committed by GitHub
parent 1c69fdccdd
commit 24b81ac8b9
19 changed files with 78 additions and 76 deletions

View File

@@ -215,7 +215,7 @@ func checkCommitGraph(ctx context.Context, logger log.Logger, autofix bool) erro
if !isExist {
numNeedUpdate++
if autofix {
if err := git.WriteCommitGraph(ctx, repo.RepoPath()); err != nil {
if err := gitrepo.WriteCommitGraph(ctx, repo); err != nil {
logger.Error("Unable to write commit-graph in %s. Error: %v", repo.FullName(), err)
return err
}

View File

@@ -153,7 +153,7 @@ func runPushSync(ctx context.Context, m *repo_model.PushMirror) error {
log.Trace("Pushing %s mirror[%d] remote %s", storageRepo.RelativePath(), m.ID, m.RemoteName)
envs := proxy.EnvWithProxy(remoteURL.URL)
if err := gitrepo.Push(ctx, storageRepo, git.PushOptions{
if err := gitrepo.PushToExternal(ctx, storageRepo, git.PushOptions{
Remote: m.RemoteName,
Force: true,
Mirror: true,

View File

@@ -570,13 +570,11 @@ func pushToBaseRepoHelper(ctx context.Context, pr *issues_model.PullRequest, pre
log.Error("Unable to load head repository for PR[%d] Error: %v", pr.ID, err)
return err
}
headRepoPath := pr.HeadRepo.RepoPath()
if err := pr.LoadBaseRepo(ctx); err != nil {
log.Error("Unable to load base repository for PR[%d] Error: %v", pr.ID, err)
return err
}
baseRepoPath := pr.BaseRepo.RepoPath()
if err = pr.LoadIssue(ctx); err != nil {
return fmt.Errorf("unable to load issue %d for pr %d: %w", pr.IssueID, pr.ID, err)
@@ -587,8 +585,7 @@ func pushToBaseRepoHelper(ctx context.Context, pr *issues_model.PullRequest, pre
gitRefName := pr.GetGitHeadRefName()
if err := git.Push(ctx, headRepoPath, git.PushOptions{
Remote: baseRepoPath,
if err := gitrepo.Push(ctx, pr.HeadRepo, pr.BaseRepo, git.PushOptions{
Branch: prefixHeadBranch + pr.HeadBranch + ":" + gitRefName,
Force: true,
// Use InternalPushingEnvironment here because we know that pre-receive and post-receive do not run on a refs/pulls/...

View File

@@ -385,8 +385,7 @@ func CreateNewBranchFromCommit(ctx context.Context, doer *user_model.User, repo
return err
}
if err := git.Push(ctx, repo.RepoPath(), git.PushOptions{
Remote: repo.RepoPath(),
if err := gitrepo.Push(ctx, repo, repo, git.PushOptions{
Branch: fmt.Sprintf("%s:%s%s", commitID, git.BranchPrefix, branchName),
Env: repo_module.PushingEnvironment(doer, repo),
}); err != nil {

View File

@@ -18,6 +18,7 @@ import (
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/git/gitcmd"
"code.gitea.io/gitea/modules/gitrepo"
"code.gitea.io/gitea/modules/log"
repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/setting"
@@ -362,8 +363,7 @@ func (t *TemporaryUploadRepository) CommitTree(ctx context.Context, opts *Commit
func (t *TemporaryUploadRepository) Push(ctx context.Context, doer *user_model.User, commitHash, branch string, force bool) error {
// Because calls hooks we need to pass in the environment
env := repo_module.PushingEnvironment(doer, t.repo)
if err := git.Push(ctx, t.basePath, git.PushOptions{
Remote: t.repo.RepoPath(),
if err := gitrepo.PushFromLocal(ctx, t.basePath, t.repo, git.PushOptions{
Branch: strings.TrimSpace(commitHash) + ":" + git.BranchPrefix + strings.TrimSpace(branch),
Env: env,
Force: force,

View File

@@ -230,8 +230,7 @@ func generateRepoCommit(ctx context.Context, repo, templateRepo, generateRepo *r
)
// Clone to temporary path and do the init commit.
templateRepoPath := templateRepo.RepoPath()
if err := git.Clone(ctx, templateRepoPath, tmpDir, git.CloneRepoOptions{
if err := gitrepo.CloneRepoToLocal(ctx, templateRepo, tmpDir, git.CloneRepoOptions{
Depth: 1,
Branch: templateRepo.DefaultBranch,
}); err != nil {

View File

@@ -11,6 +11,7 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/gitrepo"
repo_module "code.gitea.io/gitea/modules/repository"
"code.gitea.io/gitea/modules/reqctx"
"code.gitea.io/gitea/modules/util"
@@ -33,8 +34,7 @@ func MergeUpstream(ctx reqctx.RequestContext, doer *user_model.User, repo *repo_
return "up-to-date", nil
}
err = git.Push(ctx, repo.BaseRepo.RepoPath(), git.PushOptions{
Remote: repo.RepoPath(),
err = gitrepo.Push(ctx, repo.BaseRepo, repo, git.PushOptions{
Branch: fmt.Sprintf("%s:%s", divergingInfo.BaseBranchName, branch),
Env: repo_module.PushingEnvironment(doer, repo),
})

View File

@@ -74,8 +74,6 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User,
repo *repo_model.Repository, opts migration.MigrateOptions,
httpTransport *http.Transport,
) (*repo_model.Repository, error) {
repoPath := repo.RepoPath()
if u.IsOrganization() {
t, err := organization.OrgFromUser(u).GetOwnerTeam(ctx)
if err != nil {
@@ -92,7 +90,7 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User,
return repo, fmt.Errorf("failed to remove existing repo dir %q, err: %w", repo.FullName(), err)
}
if err := git.Clone(ctx, opts.CloneAddr, repoPath, git.CloneRepoOptions{
if err := gitrepo.CloneExternalRepo(ctx, opts.CloneAddr, repo, git.CloneRepoOptions{
Mirror: true,
Quiet: true,
Timeout: migrateTimeout,
@@ -104,7 +102,7 @@ func MigrateRepositoryGitData(ctx context.Context, u *user_model.User,
return repo, fmt.Errorf("clone error: %w", err)
}
if err := git.WriteCommitGraph(ctx, repoPath); err != nil {
if err := gitrepo.WriteCommitGraph(ctx, repo); err != nil {
return repo, err
}

View File

@@ -345,3 +345,31 @@ func HasWiki(ctx context.Context, repo *repo_model.Repository) bool {
}
return hasWiki && err == nil
}
// CheckCreateRepository check if doer could create a repository in new owner
func CheckCreateRepository(ctx context.Context, doer, owner *user_model.User, name string, overwriteOrAdopt bool) error {
if !doer.CanCreateRepoIn(owner) {
return repo_model.ErrReachLimitOfRepo{Limit: owner.MaxRepoCreation}
}
if err := repo_model.IsUsableRepoName(name); err != nil {
return err
}
has, err := repo_model.IsRepositoryModelExist(ctx, owner, name)
if err != nil {
return err
} else if has {
return repo_model.ErrRepoAlreadyExist{Uname: owner.Name, Name: name}
}
repo := repo_model.StorageRepo(repo_model.RelativePath(owner.Name, name))
isExist, err := gitrepo.IsRepositoryExist(ctx, repo)
if err != nil {
log.Error("Unable to check if %s exists. Error: %v", repo.RelativePath(), err)
return err
}
if !overwriteOrAdopt && isExist {
return repo_model.ErrRepoFilesAlreadyExist{Uname: owner.Name, Name: name}
}
return nil
}

View File

@@ -90,6 +90,17 @@ func AcceptTransferOwnership(ctx context.Context, repo *repo_model.Repository, d
return nil
}
// isRepositoryModelOrDirExist returns true if the repository with given name under user has already existed.
func isRepositoryModelOrDirExist(ctx context.Context, u *user_model.User, repoName string) (bool, error) {
has, err := repo_model.IsRepositoryModelExist(ctx, u, repoName)
if err != nil {
return false, err
}
repo := repo_model.StorageRepo(repo_model.RelativePath(u.Name, repoName))
isExist, err := gitrepo.IsRepositoryExist(ctx, repo)
return has || isExist, err
}
// transferOwnership transfers all corresponding repository items from old user to new one.
func transferOwnership(ctx context.Context, doer *user_model.User, newOwnerName string, repo *repo_model.Repository, teams []*organization.Team) (err error) {
repoRenamed := false
@@ -143,7 +154,7 @@ func transferOwnership(ctx context.Context, doer *user_model.User, newOwnerName
newOwnerName = newOwner.Name // ensure capitalisation matches
// Check if new owner has repository with same name.
if has, err := repo_model.IsRepositoryModelOrDirExist(ctx, newOwner, repo.Name); err != nil {
if has, err := isRepositoryModelOrDirExist(ctx, newOwner, repo.Name); err != nil {
return fmt.Errorf("IsRepositoryExist: %w", err)
} else if has {
return repo_model.ErrRepoAlreadyExist{
@@ -345,7 +356,7 @@ func changeRepositoryName(ctx context.Context, repo *repo_model.Repository, newR
return err
}
has, err := repo_model.IsRepositoryModelOrDirExist(ctx, repo.Owner, newRepoName)
has, err := isRepositoryModelOrDirExist(ctx, repo.Owner, newRepoName)
if err != nil {
return fmt.Errorf("IsRepositoryExist: %w", err)
} else if has {

View File

@@ -25,8 +25,6 @@ import (
repo_service "code.gitea.io/gitea/services/repository"
)
const DefaultRemote = "origin"
func getWikiWorkingLockKey(repoID int64) string {
return fmt.Sprintf("wiki_working_%d", repoID)
}
@@ -214,8 +212,7 @@ func updateWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
return err
}
if err := git.Push(gitRepo.Ctx, basePath, git.PushOptions{
Remote: DefaultRemote,
if err := gitrepo.PushFromLocal(gitRepo.Ctx, basePath, repo.WikiStorageRepo(), git.PushOptions{
Branch: fmt.Sprintf("%s:%s%s", commitHash.String(), git.BranchPrefix, repo.DefaultWikiBranch),
Env: repo_module.FullPushingEnvironment(
doer,
@@ -333,8 +330,7 @@ func DeleteWikiPage(ctx context.Context, doer *user_model.User, repo *repo_model
return err
}
if err := git.Push(gitRepo.Ctx, basePath, git.PushOptions{
Remote: DefaultRemote,
if err := gitrepo.PushFromLocal(gitRepo.Ctx, basePath, repo.WikiStorageRepo(), git.PushOptions{
Branch: fmt.Sprintf("%s:%s%s", commitHash.String(), git.BranchPrefix, repo.DefaultWikiBranch),
Env: repo_module.FullPushingEnvironment(
doer,