feat: vendor gitea 1.16.2

This commit is contained in:
2026-06-02 08:36:01 +00:00
parent 247cd60f69
commit 54798b4615
2145 changed files with 162965 additions and 126447 deletions
@@ -33,19 +33,18 @@ import (
actions_service "code.gitea.io/gitea/services/actions"
notify_service "code.gitea.io/gitea/services/notify"
release_service "code.gitea.io/gitea/services/release"
files_service "code.gitea.io/gitea/services/repository/files"
"xorm.io/builder"
)
// CreateNewBranch creates a new repository branch
func CreateNewBranch(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, gitRepo *git.Repository, oldBranchName, branchName string) (err error) {
func CreateNewBranch(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, oldBranchName, branchName string) (err error) {
branch, err := git_model.GetBranch(ctx, repo.ID, oldBranchName)
if err != nil {
return err
}
return CreateNewBranchFromCommit(ctx, doer, repo, gitRepo, branch.CommitID, branchName)
return CreateNewBranchFromCommit(ctx, doer, repo, branch.CommitID, branchName)
}
// Branch contains the branch information
@@ -123,9 +122,9 @@ func getDivergenceCacheKey(repoID int64, branchName string) string {
}
// getDivergenceFromCache gets the divergence from cache
func getDivergenceFromCache(repoID int64, branchName string) (*git.DivergeObject, bool) {
func getDivergenceFromCache(repoID int64, branchName string) (*gitrepo.DivergeObject, bool) {
data, ok := cache.GetCache().Get(getDivergenceCacheKey(repoID, branchName))
res := git.DivergeObject{
res := gitrepo.DivergeObject{
Ahead: -1,
Behind: -1,
}
@@ -139,7 +138,7 @@ func getDivergenceFromCache(repoID int64, branchName string) (*git.DivergeObject
return &res, true
}
func putDivergenceFromCache(repoID int64, branchName string, divergence *git.DivergeObject) error {
func putDivergenceFromCache(repoID int64, branchName string, divergence *gitrepo.DivergeObject) error {
bs, err := json.Marshal(divergence)
if err != nil {
return err
@@ -178,7 +177,7 @@ func loadOneBranch(ctx context.Context, repo *repo_model.Repository, dbBranch *g
p := protectedBranches.GetFirstMatched(branchName)
isProtected := p != nil
var divergence *git.DivergeObject
var divergence *gitrepo.DivergeObject
// it's not default branch
if repo.DefaultBranch != dbBranch.Name && !dbBranch.IsDeleted {
@@ -186,9 +185,9 @@ func loadOneBranch(ctx context.Context, repo *repo_model.Repository, dbBranch *g
divergence, cached = getDivergenceFromCache(repo.ID, dbBranch.Name)
if !cached {
var err error
divergence, err = files_service.CountDivergingCommits(ctx, repo, git.BranchPrefix+branchName)
divergence, err = gitrepo.GetDivergingCommits(ctx, repo, repo.DefaultBranch, git.BranchPrefix+branchName)
if err != nil {
log.Error("CountDivergingCommits: %v", err)
log.Error("GetDivergingCommits: %v", err)
} else {
if err = putDivergenceFromCache(repo.ID, dbBranch.Name, divergence); err != nil {
log.Error("putDivergenceFromCache: %v", err)
@@ -199,7 +198,7 @@ func loadOneBranch(ctx context.Context, repo *repo_model.Repository, dbBranch *g
if divergence == nil {
// tolerate the error that we cannot get divergence
divergence = &git.DivergeObject{Ahead: -1, Behind: -1}
divergence = &gitrepo.DivergeObject{Ahead: -1, Behind: -1}
}
pr, err := issues_model.GetLatestPullRequestByHeadInfo(ctx, repo.ID, branchName)
@@ -265,12 +264,12 @@ func checkBranchName(ctx context.Context, repo *repo_model.Repository, name stri
return git_model.ErrBranchAlreadyExists{
BranchName: name,
}
// If branchRefName like a/b but we want to create a branch named a then we have a conflict
// If branchRefName like "a/b" but we want to create a branch named a then we have a conflict
case strings.HasPrefix(branchRefName, name+"/"):
return git_model.ErrBranchNameConflict{
BranchName: branchRefName,
}
// Conversely if branchRefName like a but we want to create a branch named a/b then we also have a conflict
// Conversely if branchRefName like "a" but we want to create a branch named "a/b" then we also have a conflict
case strings.HasPrefix(name, branchRefName+"/"):
return git_model.ErrBranchNameConflict{
BranchName: branchRefName,
@@ -282,7 +281,6 @@ func checkBranchName(ctx context.Context, repo *repo_model.Repository, name stri
}
return nil
})
return err
}
@@ -375,7 +373,7 @@ func SyncBranchesToDB(ctx context.Context, repoID, pusherID int64, branchNames,
}
// CreateNewBranchFromCommit creates a new repository branch
func CreateNewBranchFromCommit(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, gitRepo *git.Repository, commitID, branchName string) (err error) {
func CreateNewBranchFromCommit(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, commitID, branchName string) (err error) {
err = repo.MustNotBeArchived()
if err != nil {
return err
@@ -386,8 +384,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 {
@@ -400,7 +397,7 @@ func CreateNewBranchFromCommit(ctx context.Context, doer *user_model.User, repo
}
// RenameBranch rename a branch
func RenameBranch(ctx context.Context, repo *repo_model.Repository, doer *user_model.User, gitRepo *git.Repository, from, to string) (string, error) {
func RenameBranch(ctx context.Context, repo *repo_model.Repository, doer *user_model.User, from, to string) (string, error) {
err := repo.MustNotBeArchived()
if err != nil {
return "", err
@@ -410,15 +407,19 @@ func RenameBranch(ctx context.Context, repo *repo_model.Repository, doer *user_m
return "target_exist", nil
}
if gitrepo.IsBranchExist(ctx, repo, to) {
if exist, _ := git_model.IsBranchExist(ctx, repo.ID, to); exist {
return "target_exist", nil
}
if !gitrepo.IsBranchExist(ctx, repo, from) {
return "from_not_exist", nil
fromBranch, err := git_model.GetBranch(ctx, repo.ID, from)
if err != nil {
if git_model.IsErrBranchNotExist(err) {
return "from_not_exist", nil
}
return "", err
}
perm, err := access_model.GetUserRepoPermission(ctx, repo, doer)
perm, err := access_model.GetDoerRepoPermission(ctx, repo, doer)
if err != nil {
return "", err
}
@@ -441,8 +442,17 @@ func RenameBranch(ctx context.Context, repo *repo_model.Repository, doer *user_m
}
}
// We also need to check if "to" matches with a protected branch rule.
rule, err := git_model.GetFirstMatchProtectedBranchRule(ctx, repo.ID, to)
if err != nil {
return "", err
}
if rule != nil && !rule.CanUserPush(ctx, doer) {
return "", git_model.ErrBranchIsProtected
}
if err := git_model.RenameBranch(ctx, repo, from, to, func(ctx context.Context, isDefault bool) error {
err2 := gitRepo.RenameBranch(from, to)
err2 := gitrepo.RenameBranch(ctx, repo, from, to)
if err2 != nil {
return err2
}
@@ -473,26 +483,79 @@ func RenameBranch(ctx context.Context, repo *repo_model.Repository, doer *user_m
}); err != nil {
return "", err
}
refNameTo := git.RefNameFromBranch(to)
refID, err := gitRepo.GetRefCommitID(refNameTo.String())
if err != nil {
return "", err
}
notify_service.DeleteRef(ctx, doer, repo, git.RefNameFromBranch(from))
notify_service.CreateRef(ctx, doer, repo, refNameTo, refID)
notify_service.CreateRef(ctx, doer, repo, git.RefNameFromBranch(to), fromBranch.CommitID)
return "", nil
}
var ErrBranchIsDefault = util.ErrorWrap(util.ErrPermissionDenied, "branch is default")
// UpdateBranch moves a branch reference to the provided commit. permission check should be done before calling this function.
func UpdateBranch(ctx context.Context, repo *repo_model.Repository, gitRepo *git.Repository, doer *user_model.User, branchName, newCommitID, expectedOldCommitID string, force bool) error {
branch, err := git_model.GetBranch(ctx, repo.ID, branchName)
if err != nil {
return err
}
if branch.IsDeleted {
return git_model.ErrBranchNotExist{
BranchName: branchName,
}
}
if expectedOldCommitID != "" {
expectedID, err := gitRepo.ConvertToGitID(expectedOldCommitID)
if err != nil {
return fmt.Errorf("ConvertToGitID(old): %w", err)
}
if expectedID.String() != branch.CommitID {
return util.NewInvalidArgumentErrorf("branch commit does not match [expected: %s, given: %s]", expectedID.String(), branch.CommitID)
}
}
newID, err := gitRepo.ConvertToGitID(newCommitID)
if err != nil {
return fmt.Errorf("ConvertToGitID(new): %w", err)
}
newCommit, err := gitRepo.GetCommit(newID.String())
if err != nil {
return err
}
if newCommit.ID.String() == branch.CommitID {
return nil
}
isForcePush, err := newCommit.IsForcePush(branch.CommitID)
if err != nil {
return err
}
if isForcePush && !force {
return util.NewInvalidArgumentErrorf("Force push %s need a confirm force parameter", branchName)
}
pushOpts := git.PushOptions{
Branch: fmt.Sprintf("%s:%s%s", newCommit.ID.String(), git.BranchPrefix, branchName),
Env: repo_module.PushingEnvironment(doer, repo),
Force: isForcePush || force,
}
if expectedOldCommitID != "" {
pushOpts.ForceWithLease = fmt.Sprintf("%s:%s", git.BranchPrefix+branchName, branch.CommitID)
}
// branch protection will be checked in the pre received hook, so that we don't need any check here
return gitrepo.Push(ctx, repo, repo, pushOpts)
}
var ErrBranchIsDefault = util.ErrorWrap(util.ErrPermissionDenied, "branch is default or pull request target")
func CanDeleteBranch(ctx context.Context, repo *repo_model.Repository, branchName string, doer *user_model.User) error {
if branchName == repo.DefaultBranch {
unitPRConfig := repo.MustGetUnit(ctx, unit.TypePullRequests).PullRequestsConfig()
if branchName == repo.DefaultBranch || branchName == unitPRConfig.DefaultTargetBranch {
return ErrBranchIsDefault
}
perm, err := access_model.GetUserRepoPermission(ctx, repo, doer)
perm, err := access_model.GetDoerRepoPermission(ctx, repo, doer)
if err != nil {
return err
}
@@ -510,8 +573,38 @@ func CanDeleteBranch(ctx context.Context, repo *repo_model.Repository, branchNam
return nil
}
func deleteBranchInternal(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, branchName string, branchCommit *git.Commit) (branchExisted bool, err error) {
activeInDB, err := git_model.IsBranchExist(ctx, repo.ID, branchName)
if err != nil {
return false, fmt.Errorf("IsBranchExist: %w", err)
}
// process the branch in db
if activeInDB {
if err := git_model.MarkBranchAsDeleted(ctx, repo.ID, branchName, doer.ID); err != nil {
return false, err
}
}
// process the branch in git
if branchCommit != nil {
err := gitrepo.DeleteBranch(ctx, repo, branchName, true)
if err != nil {
return false, fmt.Errorf("DeleteBranch: %w", err)
}
// since the branch existed in git, return branchExisted=true
branchExisted = true
} else {
// the branch didn't exist in git, return activeInDB to indicate whether the branch was active in DB,
// for consistency with that the user had seen on the web ui or in the branch list API response.
branchExisted = activeInDB
}
return branchExisted, nil
}
// DeleteBranch delete branch
func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, gitRepo *git.Repository, branchName string, pr *issues_model.PullRequest) error {
func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.Repository, gitRepo *git.Repository, branchName string) error {
err := repo.MustNotBeArchived()
if err != nil {
return err
@@ -521,48 +614,31 @@ func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.R
return err
}
rawBranch, err := git_model.GetBranch(ctx, repo.ID, branchName)
if err != nil && !git_model.IsErrBranchNotExist(err) {
return fmt.Errorf("GetBranch: %vc", err)
}
// database branch record not exist or it's a deleted branch
notExist := git_model.IsErrBranchNotExist(err) || rawBranch.IsDeleted
branchCommit, err := gitRepo.GetBranchCommit(branchName)
// branchCommit can be nil if the branch doesn't exist in git
if err != nil && !errors.Is(err, util.ErrNotExist) {
return err
}
if err := db.WithTx(ctx, func(ctx context.Context) error {
if !notExist {
if err := git_model.AddDeletedBranch(ctx, repo.ID, branchName, doer.ID); err != nil {
return err
}
}
if pr != nil {
if err := issues_model.AddDeletePRBranchComment(ctx, doer, pr.BaseRepo, pr.Issue.ID, pr.HeadBranch); err != nil {
return fmt.Errorf("DeleteBranch: %v", err)
}
}
if branchCommit == nil {
return nil
}
return gitRepo.DeleteBranch(branchName, git.DeleteBranchOptions{
Force: true,
})
}); err != nil {
branchExisted, err := db.WithTx2(ctx, func(ctx context.Context) (bool, error) {
return deleteBranchInternal(ctx, doer, repo, branchName, branchCommit)
})
if err != nil {
return err
}
if branchCommit == nil {
return nil
if !branchExisted {
return git.ErrBranchNotExist{Name: branchName}
}
// Don't return error below this
// Don't return error below this since the deletion has succeeded
if branchCommit != nil {
deleteBranchSuccessPostProcess(doer, repo, branchName, branchCommit)
}
return nil
}
func deleteBranchSuccessPostProcess(doer *user_model.User, repo *repo_model.Repository, branchName string, branchCommit *git.Commit) {
objectFormat := git.ObjectFormatFromName(repo.ObjectFormatName)
if err := PushUpdate(
&repo_module.PushUpdateOptions{
@@ -576,8 +652,6 @@ func DeleteBranch(ctx context.Context, doer *user_model.User, repo *repo_model.R
}); err != nil {
log.Error("PushUpdateOptions: %v", err)
}
return nil
}
type BranchSyncOptions struct {
@@ -627,7 +701,7 @@ func SetRepoDefaultBranch(ctx context.Context, repo *repo_model.Repository, newB
return nil
}
if !gitrepo.IsBranchExist(ctx, repo, newBranchName) {
if exist, _ := git_model.IsBranchExist(ctx, repo.ID, newBranchName); !exist {
return git_model.ErrBranchNotExist{
BranchName: newBranchName,
}
@@ -717,7 +791,7 @@ func GetBranchDivergingInfo(ctx reqctx.RequestContext, baseRepo *repo_model.Repo
// if the fork repo has new commits, this call will fail because they are not in the base repo
// exit status 128 - fatal: Invalid symmetric difference expression aaaaaaaaaaaa...bbbbbbbbbbbb
// so at the moment, we first check the update time, then check whether the fork branch has base's head
diff, err := git.GetDivergingCommits(ctx, baseRepo.RepoPath(), baseGitBranch.CommitID, headGitBranch.CommitID)
diff, err := gitrepo.GetDivergingCommits(ctx, baseRepo, baseGitBranch.CommitID, headGitBranch.CommitID)
if err != nil {
info.BaseHasNewCommits = baseGitBranch.UpdatedUnix > headGitBranch.UpdatedUnix
if headRepo.IsFork && info.BaseHasNewCommits {
@@ -825,9 +899,17 @@ func DeleteBranchAfterMerge(ctx context.Context, doer *user_model.User, prID int
return util.ErrorWrapTranslatable(util.ErrUnprocessableContent, "repo.branch.delete_branch_has_new_commits", fullBranchName)
}
err = DeleteBranch(ctx, doer, pr.HeadRepo, gitHeadRepo, pr.HeadBranch, pr)
err = DeleteBranch(ctx, doer, pr.HeadRepo, gitHeadRepo, pr.HeadBranch)
if errors.Is(err, util.ErrPermissionDenied) || errors.Is(err, util.ErrNotExist) {
return errFailedToDelete(err)
}
return err
if err != nil {
return err
}
// intentionally ignore the following error, since the branch has already been deleted successfully
if err := issues_model.AddDeletePRBranchComment(ctx, doer, pr.BaseRepo, pr.Issue.ID, pr.HeadBranch); err != nil {
log.Error("AddDeletePRBranchComment: %v", err)
}
return nil
}