feat: vendor gitea 1.16.2
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user