aboutsummaryrefslogtreecommitdiffstats
path: root/routers
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2023-06-29 18:03:20 +0800
committerGitHub <noreply@github.com>2023-06-29 10:03:20 +0000
commit6e19484f4d3bf372212f2da462110a1a8c10cbf2 (patch)
treee8f1b4920b286241e4ad59151b4f00d9941a27aa /routers
parent5a871932f0efc19a731ee5c1202679653d3cefff (diff)
downloadgitea-6e19484f4d3bf372212f2da462110a1a8c10cbf2.tar.gz
gitea-6e19484f4d3bf372212f2da462110a1a8c10cbf2.zip
Sync branches into databases (#22743)
Related #14180 Related #25233 Related #22639 Close #19786 Related #12763 This PR will change all the branches retrieve method from reading git data to read database to reduce git read operations. - [x] Sync git branches information into database when push git data - [x] Create a new table `Branch`, merge some columns of `DeletedBranch` into `Branch` table and drop the table `DeletedBranch`. - [x] Read `Branch` table when visit `code` -> `branch` page - [x] Read `Branch` table when list branch names in `code` page dropdown - [x] Read `Branch` table when list git ref compare page - [x] Provide a button in admin page to manually sync all branches. - [x] Sync branches if repository is not empty but database branches are empty when visiting pages with branches list - [x] Use `commit_time desc` as the default FindBranch order by to keep consistent as before and deleted branches will be always at the end. --------- Co-authored-by: Jason Song <i@wolfogre.com>
Diffstat (limited to 'routers')
-rw-r--r--routers/api/v1/repo/branch.go83
-rw-r--r--routers/api/v1/repo/file.go6
-rw-r--r--routers/api/v1/repo/patch.go5
-rw-r--r--routers/web/admin/admin.go25
-rw-r--r--routers/web/repo/branch.go213
-rw-r--r--routers/web/repo/cherry_pick.go9
-rw-r--r--routers/web/repo/compare.go17
-rw-r--r--routers/web/repo/editor.go12
-rw-r--r--routers/web/repo/issue.go8
-rw-r--r--routers/web/repo/patch.go5
-rw-r--r--routers/web/repo/pull.go2
-rw-r--r--routers/web/repo/setting_protected_branch.go2
12 files changed, 140 insertions, 247 deletions
diff --git a/routers/api/v1/repo/branch.go b/routers/api/v1/repo/branch.go
index 5336ccb797..4900ecf4d0 100644
--- a/routers/api/v1/repo/branch.go
+++ b/routers/api/v1/repo/branch.go
@@ -15,7 +15,9 @@ import (
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git"
+ repo_module "code.gitea.io/gitea/modules/repository"
api "code.gitea.io/gitea/modules/structs"
+ "code.gitea.io/gitea/modules/util"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/routers/api/v1/utils"
"code.gitea.io/gitea/services/convert"
@@ -76,7 +78,7 @@ func GetBranch(ctx *context.APIContext) {
return
}
- br, err := convert.ToBranch(ctx, ctx.Repo.Repository, branch, c, branchProtection, ctx.Doer, ctx.Repo.IsAdmin())
+ br, err := convert.ToBranch(ctx, ctx.Repo.Repository, branch.Name, c, branchProtection, ctx.Doer, ctx.Repo.IsAdmin())
if err != nil {
ctx.Error(http.StatusInternalServerError, "convert.ToBranch", err)
return
@@ -118,6 +120,37 @@ func DeleteBranch(ctx *context.APIContext) {
branchName := ctx.Params("*")
+ if ctx.Repo.Repository.IsEmpty {
+ ctx.Error(http.StatusForbidden, "", "Git Repository is empty.")
+ return
+ }
+
+ // check whether branches of this repository has been synced
+ totalNumOfBranches, err := git_model.CountBranches(ctx, git_model.FindBranchOptions{
+ RepoID: ctx.Repo.Repository.ID,
+ IsDeletedBranch: util.OptionalBoolFalse,
+ })
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "CountBranches", err)
+ return
+ }
+ if totalNumOfBranches == 0 { // sync branches immediately because non-empty repository should have at least 1 branch
+ _, err = repo_module.SyncRepoBranches(ctx, ctx.Repo.Repository.ID, 0)
+ if err != nil {
+ ctx.ServerError("SyncRepoBranches", err)
+ return
+ }
+ }
+
+ if ctx.Repo.Repository.IsArchived {
+ ctx.Error(http.StatusForbidden, "IsArchived", fmt.Errorf("can not delete branch of an archived repository"))
+ return
+ }
+ if ctx.Repo.Repository.IsMirror {
+ ctx.Error(http.StatusForbidden, "IsMirrored", fmt.Errorf("can not delete branch of an mirror repository"))
+ return
+ }
+
if err := repo_service.DeleteBranch(ctx, ctx.Doer, ctx.Repo.Repository, ctx.Repo.GitRepo, branchName); err != nil {
switch {
case git.IsErrBranchNotExist(err):
@@ -203,14 +236,14 @@ func CreateBranch(ctx *context.APIContext) {
err = repo_service.CreateNewBranchFromCommit(ctx, ctx.Doer, ctx.Repo.Repository, oldCommit.ID.String(), opt.BranchName)
if err != nil {
- if models.IsErrBranchDoesNotExist(err) {
+ if git_model.IsErrBranchNotExist(err) {
ctx.Error(http.StatusNotFound, "", "The old branch does not exist")
}
if models.IsErrTagAlreadyExists(err) {
ctx.Error(http.StatusConflict, "", "The branch with the same tag already exists.")
- } else if models.IsErrBranchAlreadyExists(err) || git.IsErrPushOutOfDate(err) {
+ } else if git_model.IsErrBranchAlreadyExists(err) || git.IsErrPushOutOfDate(err) {
ctx.Error(http.StatusConflict, "", "The branch already exists.")
- } else if models.IsErrBranchNameConflict(err) {
+ } else if git_model.IsErrBranchNameConflict(err) {
ctx.Error(http.StatusConflict, "", "The branch with the same name already exists.")
} else {
ctx.Error(http.StatusInternalServerError, "CreateNewBranchFromCommit", err)
@@ -236,7 +269,7 @@ func CreateBranch(ctx *context.APIContext) {
return
}
- br, err := convert.ToBranch(ctx, ctx.Repo.Repository, branch, commit, branchProtection, ctx.Doer, ctx.Repo.IsAdmin())
+ br, err := convert.ToBranch(ctx, ctx.Repo.Repository, branch.Name, commit, branchProtection, ctx.Doer, ctx.Repo.IsAdmin())
if err != nil {
ctx.Error(http.StatusInternalServerError, "convert.ToBranch", err)
return
@@ -275,20 +308,38 @@ func ListBranches(ctx *context.APIContext) {
// "200":
// "$ref": "#/responses/BranchList"
- var totalNumOfBranches int
+ var totalNumOfBranches int64
var apiBranches []*api.Branch
listOptions := utils.GetListOptions(ctx)
if !ctx.Repo.Repository.IsEmpty && ctx.Repo.GitRepo != nil {
+ branchOpts := git_model.FindBranchOptions{
+ ListOptions: listOptions,
+ RepoID: ctx.Repo.Repository.ID,
+ IsDeletedBranch: util.OptionalBoolFalse,
+ }
+ var err error
+ totalNumOfBranches, err = git_model.CountBranches(ctx, branchOpts)
+ if err != nil {
+ ctx.Error(http.StatusInternalServerError, "CountBranches", err)
+ return
+ }
+ if totalNumOfBranches == 0 { // sync branches immediately because non-empty repository should have at least 1 branch
+ totalNumOfBranches, err = repo_module.SyncRepoBranches(ctx, ctx.Repo.Repository.ID, 0)
+ if err != nil {
+ ctx.ServerError("SyncRepoBranches", err)
+ return
+ }
+ }
+
rules, err := git_model.FindRepoProtectedBranchRules(ctx, ctx.Repo.Repository.ID)
if err != nil {
ctx.Error(http.StatusInternalServerError, "FindMatchedProtectedBranchRules", err)
return
}
- skip, _ := listOptions.GetStartEnd()
- branches, total, err := ctx.Repo.GitRepo.GetBranches(skip, listOptions.PageSize)
+ branches, err := git_model.FindBranches(ctx, branchOpts)
if err != nil {
ctx.Error(http.StatusInternalServerError, "GetBranches", err)
return
@@ -296,11 +347,11 @@ func ListBranches(ctx *context.APIContext) {
apiBranches = make([]*api.Branch, 0, len(branches))
for i := range branches {
- c, err := branches[i].GetCommit()
+ c, err := ctx.Repo.GitRepo.GetBranchCommit(branches[i].Name)
if err != nil {
// Skip if this branch doesn't exist anymore.
if git.IsErrNotExist(err) {
- total--
+ totalNumOfBranches--
continue
}
ctx.Error(http.StatusInternalServerError, "GetCommit", err)
@@ -308,19 +359,17 @@ func ListBranches(ctx *context.APIContext) {
}
branchProtection := rules.GetFirstMatched(branches[i].Name)
- apiBranch, err := convert.ToBranch(ctx, ctx.Repo.Repository, branches[i], c, branchProtection, ctx.Doer, ctx.Repo.IsAdmin())
+ apiBranch, err := convert.ToBranch(ctx, ctx.Repo.Repository, branches[i].Name, c, branchProtection, ctx.Doer, ctx.Repo.IsAdmin())
if err != nil {
ctx.Error(http.StatusInternalServerError, "convert.ToBranch", err)
return
}
apiBranches = append(apiBranches, apiBranch)
}
-
- totalNumOfBranches = total
}
- ctx.SetLinkHeader(totalNumOfBranches, listOptions.PageSize)
- ctx.SetTotalCountHeader(int64(totalNumOfBranches))
+ ctx.SetLinkHeader(int(totalNumOfBranches), listOptions.PageSize)
+ ctx.SetTotalCountHeader(totalNumOfBranches)
ctx.JSON(http.StatusOK, apiBranches)
}
@@ -580,7 +629,7 @@ func CreateBranchProtection(ctx *context.APIContext) {
}()
}
// FIXME: since we only need to recheck files protected rules, we could improve this
- matchedBranches, err := git_model.FindAllMatchedBranches(ctx, ctx.Repo.GitRepo, ruleName)
+ matchedBranches, err := git_model.FindAllMatchedBranches(ctx, ctx.Repo.Repository.ID, ruleName)
if err != nil {
ctx.Error(http.StatusInternalServerError, "FindAllMatchedBranches", err)
return
@@ -851,7 +900,7 @@ func EditBranchProtection(ctx *context.APIContext) {
}
// FIXME: since we only need to recheck files protected rules, we could improve this
- matchedBranches, err := git_model.FindAllMatchedBranches(ctx, ctx.Repo.GitRepo, protectBranch.RuleName)
+ matchedBranches, err := git_model.FindAllMatchedBranches(ctx, ctx.Repo.Repository.ID, protectBranch.RuleName)
if err != nil {
ctx.Error(http.StatusInternalServerError, "FindAllMatchedBranches", err)
return
diff --git a/routers/api/v1/repo/file.go b/routers/api/v1/repo/file.go
index 2b468d6e73..48f890ee55 100644
--- a/routers/api/v1/repo/file.go
+++ b/routers/api/v1/repo/file.go
@@ -687,12 +687,12 @@ func handleCreateOrUpdateFileError(ctx *context.APIContext, err error) {
ctx.Error(http.StatusForbidden, "Access", err)
return
}
- if models.IsErrBranchAlreadyExists(err) || models.IsErrFilenameInvalid(err) || models.IsErrSHADoesNotMatch(err) ||
+ if git_model.IsErrBranchAlreadyExists(err) || models.IsErrFilenameInvalid(err) || models.IsErrSHADoesNotMatch(err) ||
models.IsErrFilePathInvalid(err) || models.IsErrRepoFileAlreadyExists(err) {
ctx.Error(http.StatusUnprocessableEntity, "Invalid", err)
return
}
- if models.IsErrBranchDoesNotExist(err) || git.IsErrBranchNotExist(err) {
+ if git_model.IsErrBranchNotExist(err) || git.IsErrBranchNotExist(err) {
ctx.Error(http.StatusNotFound, "BranchDoesNotExist", err)
return
}
@@ -843,7 +843,7 @@ func DeleteFile(ctx *context.APIContext) {
if git.IsErrBranchNotExist(err) || models.IsErrRepoFileDoesNotExist(err) || git.IsErrNotExist(err) {
ctx.Error(http.StatusNotFound, "DeleteFile", err)
return
- } else if models.IsErrBranchAlreadyExists(err) ||
+ } else if git_model.IsErrBranchAlreadyExists(err) ||
models.IsErrFilenameInvalid(err) ||
models.IsErrSHADoesNotMatch(err) ||
models.IsErrCommitIDDoesNotMatch(err) ||
diff --git a/routers/api/v1/repo/patch.go b/routers/api/v1/repo/patch.go
index 6fbb9e7b3a..d2f055355d 100644
--- a/routers/api/v1/repo/patch.go
+++ b/routers/api/v1/repo/patch.go
@@ -8,6 +8,7 @@ import (
"time"
"code.gitea.io/gitea/models"
+ git_model "code.gitea.io/gitea/models/git"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/modules/context"
"code.gitea.io/gitea/modules/git"
@@ -91,12 +92,12 @@ func ApplyDiffPatch(ctx *context.APIContext) {
ctx.Error(http.StatusForbidden, "Access", err)
return
}
- if models.IsErrBranchAlreadyExists(err) || models.IsErrFilenameInvalid(err) || models.IsErrSHADoesNotMatch(err) ||
+ if git_model.IsErrBranchAlreadyExists(err) || models.IsErrFilenameInvalid(err) || models.IsErrSHADoesNotMatch(err) ||
models.IsErrFilePathInvalid(err) || models.IsErrRepoFileAlreadyExists(err) {
ctx.Error(http.StatusUnprocessableEntity, "Invalid", err)
return
}
- if models.IsErrBranchDoesNotExist(err) || git.IsErrBranchNotExist(err) {
+ if git_model.IsErrBranchNotExist(err) || git.IsErrBranchNotExist(err) {
ctx.Error(http.StatusNotFound, "BranchDoesNotExist", err)
return
}
diff --git a/routers/web/admin/admin.go b/routers/web/admin/admin.go
index 797ba8798d..225a8c6705 100644
--- a/routers/web/admin/admin.go
+++ b/routers/web/admin/admin.go
@@ -14,12 +14,15 @@ import (
activities_model "code.gitea.io/gitea/models/activities"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
+ "code.gitea.io/gitea/modules/graceful"
"code.gitea.io/gitea/modules/json"
+ "code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/updatechecker"
"code.gitea.io/gitea/modules/web"
"code.gitea.io/gitea/services/cron"
"code.gitea.io/gitea/services/forms"
+ repo_service "code.gitea.io/gitea/services/repository"
)
const (
@@ -133,12 +136,22 @@ func DashboardPost(ctx *context.Context) {
// Run operation.
if form.Op != "" {
- task := cron.GetTask(form.Op)
- if task != nil {
- go task.RunWithUser(ctx.Doer, nil)
- ctx.Flash.Success(ctx.Tr("admin.dashboard.task.started", ctx.Tr("admin.dashboard."+form.Op)))
- } else {
- ctx.Flash.Error(ctx.Tr("admin.dashboard.task.unknown", form.Op))
+ switch form.Op {
+ case "sync_repo_branches":
+ go func() {
+ if err := repo_service.AddAllRepoBranchesToSyncQueue(graceful.GetManager().ShutdownContext(), ctx.Doer.ID); err != nil {
+ log.Error("AddAllRepoBranchesToSyncQueue: %v: %v", ctx.Doer.ID, err)
+ }
+ }()
+ ctx.Flash.Success(ctx.Tr("admin.dashboard.sync_branch.started"))
+ default:
+ task := cron.GetTask(form.Op)
+ if task != nil {
+ go task.RunWithUser(ctx.Doer, nil)
+ ctx.Flash.Success(ctx.Tr("admin.dashboard.task.started", ctx.Tr("admin.dashboard."+form.Op)))
+ } else {
+ ctx.Flash.Error(ctx.Tr("admin.dashboard.task.unknown", form.Op))
+ }
}
}
if form.From == "monitor" {
diff --git a/routers/web/repo/branch.go b/routers/web/repo/branch.go
index ea2c01856d..f0282a71b8 100644
--- a/routers/web/repo/branch.go
+++ b/routers/web/repo/branch.go
@@ -13,7 +13,6 @@ import (
"code.gitea.io/gitea/models"
git_model "code.gitea.io/gitea/models/git"
- issues_model "code.gitea.io/gitea/models/issues"
repo_model "code.gitea.io/gitea/models/repo"
"code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/modules/base"
@@ -28,32 +27,16 @@ import (
"code.gitea.io/gitea/services/forms"
release_service "code.gitea.io/gitea/services/release"
repo_service "code.gitea.io/gitea/services/repository"
- files_service "code.gitea.io/gitea/services/repository/files"
)
const (
tplBranch base.TplName = "repo/branch/list"
)
-// Branch contains the branch information
-type Branch struct {
- Name string
- Commit *git.Commit
- IsProtected bool
- IsDeleted bool
- IsIncluded bool
- DeletedBranch *git_model.DeletedBranch
- CommitsAhead int
- CommitsBehind int
- LatestPullRequest *issues_model.PullRequest
- MergeMovedOn bool
-}
-
// Branches render repository branch page
func Branches(ctx *context.Context) {
ctx.Data["Title"] = "Branches"
ctx.Data["IsRepoToolbarBranches"] = true
- ctx.Data["DefaultBranch"] = ctx.Repo.Repository.DefaultBranch
ctx.Data["AllowsPulls"] = ctx.Repo.Repository.AllowsPulls()
ctx.Data["IsWriter"] = ctx.Repo.CanWrite(unit.TypeCode)
ctx.Data["IsMirror"] = ctx.Repo.Repository.IsMirror
@@ -68,15 +51,15 @@ func Branches(ctx *context.Context) {
}
pageSize := setting.Git.BranchesRangeSize
- skip := (page - 1) * pageSize
- log.Debug("Branches: skip: %d limit: %d", skip, pageSize)
- defaultBranchBranch, branches, branchesCount := loadBranches(ctx, skip, pageSize)
- if ctx.Written() {
+ defaultBranch, branches, branchesCount, err := repo_service.LoadBranches(ctx, ctx.Repo.Repository, ctx.Repo.GitRepo, util.OptionalBoolNone, page, pageSize)
+ if err != nil {
+ ctx.ServerError("LoadBranches", err)
return
}
+
ctx.Data["Branches"] = branches
- ctx.Data["DefaultBranchBranch"] = defaultBranchBranch
- pager := context.NewPagination(branchesCount, pageSize, page, 5)
+ ctx.Data["DefaultBranchBranch"] = defaultBranch
+ pager := context.NewPagination(int(branchesCount), pageSize, page, 5)
pager.SetDefaultParams(ctx)
ctx.Data["Page"] = pager
@@ -130,7 +113,7 @@ func RestoreBranchPost(ctx *context.Context) {
if err := git.Push(ctx, ctx.Repo.Repository.RepoPath(), git.PushOptions{
Remote: ctx.Repo.Repository.RepoPath(),
- Branch: fmt.Sprintf("%s:%s%s", deletedBranch.Commit, git.BranchPrefix, deletedBranch.Name),
+ Branch: fmt.Sprintf("%s:%s%s", deletedBranch.CommitID, git.BranchPrefix, deletedBranch.Name),
Env: repo_module.PushingEnvironment(ctx.Doer, ctx.Repo.Repository),
}); err != nil {
if strings.Contains(err.Error(), "already exists") {
@@ -148,7 +131,7 @@ func RestoreBranchPost(ctx *context.Context) {
&repo_module.PushUpdateOptions{
RefFullName: git.RefNameFromBranch(deletedBranch.Name),
OldCommitID: git.EmptySHA,
- NewCommitID: deletedBranch.Commit,
+ NewCommitID: deletedBranch.CommitID,
PusherID: ctx.Doer.ID,
PusherName: ctx.Doer.Name,
RepoUserName: ctx.Repo.Owner.Name,
@@ -166,180 +149,6 @@ func redirect(ctx *context.Context) {
})
}
-// loadBranches loads branches from the repository limited by page & pageSize.
-// NOTE: May write to context on error.
-func loadBranches(ctx *context.Context, skip, limit int) (*Branch, []*Branch, int) {
- defaultBranch, err := ctx.Repo.GitRepo.GetBranch(ctx.Repo.Repository.DefaultBranch)
- if err != nil {
- if !git.IsErrBranchNotExist(err) {
- log.Error("loadBranches: get default branch: %v", err)
- ctx.ServerError("GetDefaultBranch", err)
- return nil, nil, 0
- }
- log.Warn("loadBranches: missing default branch %s for %-v", ctx.Repo.Repository.DefaultBranch, ctx.Repo.Repository)
- }
-
- rawBranches, totalNumOfBranches, err := ctx.Repo.GitRepo.GetBranches(skip, limit)
- if err != nil {
- log.Error("GetBranches: %v", err)
- ctx.ServerError("GetBranches", err)
- return nil, nil, 0
- }
-
- rules, err := git_model.FindRepoProtectedBranchRules(ctx, ctx.Repo.Repository.ID)
- if err != nil {
- ctx.ServerError("FindRepoProtectedBranchRules", err)
- return nil, nil, 0
- }
-
- repoIDToRepo := map[int64]*repo_model.Repository{}
- repoIDToRepo[ctx.Repo.Repository.ID] = ctx.Repo.Repository
-
- repoIDToGitRepo := map[int64]*git.Repository{}
- repoIDToGitRepo[ctx.Repo.Repository.ID] = ctx.Repo.GitRepo
-
- var branches []*Branch
- for i := range rawBranches {
- if defaultBranch != nil && rawBranches[i].Name == defaultBranch.Name {
- // Skip default branch
- continue
- }
-
- branch := loadOneBranch(ctx, rawBranches[i], defaultBranch, &rules, repoIDToRepo, repoIDToGitRepo)
- if branch == nil {
- return nil, nil, 0
- }
-
- branches = append(branches, branch)
- }
-
- var defaultBranchBranch *Branch
- if defaultBranch != nil {
- // Always add the default branch
- log.Debug("loadOneBranch: load default: '%s'", defaultBranch.Name)
- defaultBranchBranch = loadOneBranch(ctx, defaultBranch, defaultBranch, &rules, repoIDToRepo, repoIDToGitRepo)
- branches = append(branches, defaultBranchBranch)
- }
-
- if ctx.Repo.CanWrite(unit.TypeCode) {
- deletedBranches, err := getDeletedBranches(ctx)
- if err != nil {
- ctx.ServerError("getDeletedBranches", err)
- return nil, nil, 0
- }
- branches = append(branches, deletedBranches...)
- }
-
- return defaultBranchBranch, branches, totalNumOfBranches
-}
-
-func loadOneBranch(ctx *context.Context, rawBranch, defaultBranch *git.Branch, protectedBranches *git_model.ProtectedBranchRules,
- repoIDToRepo map[int64]*repo_model.Repository,
- repoIDToGitRepo map[int64]*git.Repository,
-) *Branch {
- log.Trace("loadOneBranch: '%s'", rawBranch.Name)
-
- commit, err := rawBranch.GetCommit()
- if err != nil {
- ctx.ServerError("GetCommit", err)
- return nil
- }
-
- branchName := rawBranch.Name
- p := protectedBranches.GetFirstMatched(branchName)
- isProtected := p != nil
-
- divergence := &git.DivergeObject{
- Ahead: -1,
- Behind: -1,
- }
- if defaultBranch != nil {
- divergence, err = files_service.CountDivergingCommits(ctx, ctx.Repo.Repository, git.BranchPrefix+branchName)
- if err != nil {
- log.Error("CountDivergingCommits", err)
- }
- }
-
- pr, err := issues_model.GetLatestPullRequestByHeadInfo(ctx.Repo.Repository.ID, branchName)
- if err != nil {
- ctx.ServerError("GetLatestPullRequestByHeadInfo", err)
- return nil
- }
- headCommit := commit.ID.String()
-
- mergeMovedOn := false
- if pr != nil {
- pr.HeadRepo = ctx.Repo.Repository
- if err := pr.LoadIssue(ctx); err != nil {
- ctx.ServerError("LoadIssue", err)
- return nil
- }
- if repo, ok := repoIDToRepo[pr.BaseRepoID]; ok {
- pr.BaseRepo = repo
- } else if err := pr.LoadBaseRepo(ctx); err != nil {
- ctx.ServerError("LoadBaseRepo", err)
- return nil
- } else {
- repoIDToRepo[pr.BaseRepoID] = pr.BaseRepo
- }
- pr.Issue.Repo = pr.BaseRepo
-
- if pr.HasMerged {
- baseGitRepo, ok := repoIDToGitRepo[pr.BaseRepoID]
- if !ok {
- baseGitRepo, err = git.OpenRepository(ctx, pr.BaseRepo.RepoPath())
- if err != nil {
- ctx.ServerError("OpenRepository", err)
- return nil
- }
- defer baseGitRepo.Close()
- repoIDToGitRepo[pr.BaseRepoID] = baseGitRepo
- }
- pullCommit, err := baseGitRepo.GetRefCommitID(pr.GetGitRefName())
- if err != nil && !git.IsErrNotExist(err) {
- ctx.ServerError("GetBranchCommitID", err)
- return nil
- }
- if err == nil && headCommit != pullCommit {
- // the head has moved on from the merge - we shouldn't delete
- mergeMovedOn = true
- }
- }
- }
-
- isIncluded := divergence.Ahead == 0 && ctx.Repo.Repository.DefaultBranch != branchName
- return &Branch{
- Name: branchName,
- Commit: commit,
- IsProtected: isProtected,
- IsIncluded: isIncluded,
- CommitsAhead: divergence.Ahead,
- CommitsBehind: divergence.Behind,
- LatestPullRequest: pr,
- MergeMovedOn: mergeMovedOn,
- }
-}
-
-func getDeletedBranches(ctx *context.Context) ([]*Branch, error) {
- branches := []*Branch{}
-
- deletedBranches, err := git_model.GetDeletedBranches(ctx, ctx.Repo.Repository.ID)
- if err != nil {
- return branches, err
- }
-
- for i := range deletedBranches {
- deletedBranches[i].LoadUser(ctx)
- branches = append(branches, &Branch{
- Name: deletedBranches[i].Name,
- IsDeleted: true,
- DeletedBranch: deletedBranches[i],
- })
- }
-
- return branches, nil
-}
-
// CreateBranch creates new branch in repository
func CreateBranch(ctx *context.Context) {
form := web.GetForm(ctx).(*forms.NewBranchForm)
@@ -380,13 +189,13 @@ func CreateBranch(ctx *context.Context) {
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL())
return
}
- if models.IsErrBranchAlreadyExists(err) || git.IsErrPushOutOfDate(err) {
+ if git_model.IsErrBranchAlreadyExists(err) || git.IsErrPushOutOfDate(err) {
ctx.Flash.Error(ctx.Tr("repo.branch.branch_already_exists", form.NewBranchName))
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL())
return
}
- if models.IsErrBranchNameConflict(err) {
- e := err.(models.ErrBranchNameConflict)
+ if git_model.IsErrBranchNameConflict(err) {
+ e := err.(git_model.ErrBranchNameConflict)
ctx.Flash.Error(ctx.Tr("repo.branch.branch_name_conflict", form.NewBranchName, e.BranchName))
ctx.Redirect(ctx.Repo.RepoLink + "/src/" + ctx.Repo.BranchNameSubURL())
return
diff --git a/routers/web/repo/cherry_pick.go b/routers/web/repo/cherry_pick.go
index 48bc6959e0..5017d02252 100644
--- a/routers/web/repo/cherry_pick.go
+++ b/routers/web/repo/cherry_pick.go
@@ -9,6 +9,7 @@ import (
"strings"
"code.gitea.io/gitea/models"
+ git_model "code.gitea.io/gitea/models/git"
"code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
@@ -124,9 +125,9 @@ func CherryPickPost(ctx *context.Context) {
// First lets try the simple plain read-tree -m approach
opts.Content = sha
if _, err := files.CherryPick(ctx, ctx.Repo.Repository, ctx.Doer, form.Revert, opts); err != nil {
- if models.IsErrBranchAlreadyExists(err) {
+ if git_model.IsErrBranchAlreadyExists(err) {
// User has specified a branch that already exists
- branchErr := err.(models.ErrBranchAlreadyExists)
+ branchErr := err.(git_model.ErrBranchAlreadyExists)
ctx.Data["Err_NewBranchName"] = true
ctx.RenderWithErr(ctx.Tr("repo.editor.branch_already_exists", branchErr.BranchName), tplCherryPick, &form)
return
@@ -161,9 +162,9 @@ func CherryPickPost(ctx *context.Context) {
ctx.Data["FileContent"] = opts.Content
if _, err := files.ApplyDiffPatch(ctx, ctx.Repo.Repository, ctx.Doer, opts); err != nil {
- if models.IsErrBranchAlreadyExists(err) {
+ if git_model.IsErrBranchAlreadyExists(err) {
// User has specified a branch that already exists
- branchErr := err.(models.ErrBranchAlreadyExists)
+ branchErr := err.(git_model.ErrBranchAlreadyExists)
ctx.Data["Err_NewBranchName"] = true
ctx.RenderWithErr(ctx.Tr("repo.editor.branch_already_exists", branchErr.BranchName), tplCherryPick, &form)
return
diff --git a/routers/web/repo/compare.go b/routers/web/repo/compare.go
index 0ca1f90547..7089c219ad 100644
--- a/routers/web/repo/compare.go
+++ b/routers/web/repo/compare.go
@@ -16,6 +16,7 @@ import (
"path/filepath"
"strings"
+ "code.gitea.io/gitea/models/db"
git_model "code.gitea.io/gitea/models/git"
issues_model "code.gitea.io/gitea/models/issues"
access_model "code.gitea.io/gitea/models/perm/access"
@@ -683,7 +684,13 @@ func getBranchesAndTagsForRepo(ctx gocontext.Context, repo *repo_model.Repositor
}
defer gitRepo.Close()
- branches, _, err = gitRepo.GetBranchNames(0, 0)
+ branches, err = git_model.FindBranchNames(ctx, git_model.FindBranchOptions{
+ RepoID: repo.ID,
+ ListOptions: db.ListOptions{
+ ListAll: true,
+ },
+ IsDeletedBranch: util.OptionalBoolFalse,
+ })
if err != nil {
return nil, nil, err
}
@@ -734,7 +741,13 @@ func CompareDiff(ctx *context.Context) {
return
}
- headBranches, _, err := ci.HeadGitRepo.GetBranchNames(0, 0)
+ headBranches, err := git_model.FindBranchNames(ctx, git_model.FindBranchOptions{
+ RepoID: ci.HeadRepo.ID,
+ ListOptions: db.ListOptions{
+ ListAll: true,
+ },
+ IsDeletedBranch: util.OptionalBoolFalse,
+ })
if err != nil {
ctx.ServerError("GetBranches", err)
return
diff --git a/routers/web/repo/editor.go b/routers/web/repo/editor.go
index 2fea8a9532..a63b08126c 100644
--- a/routers/web/repo/editor.go
+++ b/routers/web/repo/editor.go
@@ -327,10 +327,10 @@ func editFilePost(ctx *context.Context, form forms.EditRepoFileForm, isNewFile b
} else {
ctx.Error(http.StatusInternalServerError, err.Error())
}
- } else if models.IsErrBranchAlreadyExists(err) {
+ } else if git_model.IsErrBranchAlreadyExists(err) {
// For when a user specifies a new branch that already exists
ctx.Data["Err_NewBranchName"] = true
- if branchErr, ok := err.(models.ErrBranchAlreadyExists); ok {
+ if branchErr, ok := err.(git_model.ErrBranchAlreadyExists); ok {
ctx.RenderWithErr(ctx.Tr("repo.editor.branch_already_exists", branchErr.BranchName), tplEditFile, &form)
} else {
ctx.Error(http.StatusInternalServerError, err.Error())
@@ -529,9 +529,9 @@ func DeleteFilePost(ctx *context.Context) {
} else {
ctx.Error(http.StatusInternalServerError, err.Error())
}
- } else if models.IsErrBranchAlreadyExists(err) {
+ } else if git_model.IsErrBranchAlreadyExists(err) {
// For when a user specifies a new branch that already exists
- if branchErr, ok := err.(models.ErrBranchAlreadyExists); ok {
+ if branchErr, ok := err.(git_model.ErrBranchAlreadyExists); ok {
ctx.RenderWithErr(ctx.Tr("repo.editor.branch_already_exists", branchErr.BranchName), tplDeleteFile, &form)
} else {
ctx.Error(http.StatusInternalServerError, err.Error())
@@ -731,10 +731,10 @@ func UploadFilePost(ctx *context.Context) {
} else if git.IsErrBranchNotExist(err) {
branchErr := err.(git.ErrBranchNotExist)
ctx.RenderWithErr(ctx.Tr("repo.editor.branch_does_not_exist", branchErr.Name), tplUploadFile, &form)
- } else if models.IsErrBranchAlreadyExists(err) {
+ } else if git_model.IsErrBranchAlreadyExists(err) {
// For when a user specifies a new branch that already exists
ctx.Data["Err_NewBranchName"] = true
- branchErr := err.(models.ErrBranchAlreadyExists)
+ branchErr := err.(git_model.ErrBranchAlreadyExists)
ctx.RenderWithErr(ctx.Tr("repo.editor.branch_already_exists", branchErr.BranchName), tplUploadFile, &form)
} else if git.IsErrPushOutOfDate(err) {
ctx.RenderWithErr(ctx.Tr("repo.editor.file_changed_while_editing", ctx.Repo.RepoLink+"/compare/"+util.PathEscapeSegments(ctx.Repo.CommitID)+"..."+util.PathEscapeSegments(form.NewBranchName)), tplUploadFile, &form)
diff --git a/routers/web/repo/issue.go b/routers/web/repo/issue.go
index a0dd14e314..4f14cc381f 100644
--- a/routers/web/repo/issue.go
+++ b/routers/web/repo/issue.go
@@ -785,7 +785,13 @@ func RetrieveRepoMetas(ctx *context.Context, repo *repo_model.Repository, isPull
return nil
}
- brs, _, err := ctx.Repo.GitRepo.GetBranchNames(0, 0)
+ brs, err := git_model.FindBranchNames(ctx, git_model.FindBranchOptions{
+ RepoID: ctx.Repo.Repository.ID,
+ ListOptions: db.ListOptions{
+ ListAll: true,
+ },
+ IsDeletedBranch: util.OptionalBoolFalse,
+ })
if err != nil {
ctx.ServerError("GetBranches", err)
return nil
diff --git a/routers/web/repo/patch.go b/routers/web/repo/patch.go
index efb4662496..5faf9f4fa9 100644
--- a/routers/web/repo/patch.go
+++ b/routers/web/repo/patch.go
@@ -7,6 +7,7 @@ import (
"strings"
"code.gitea.io/gitea/models"
+ git_model "code.gitea.io/gitea/models/git"
"code.gitea.io/gitea/models/unit"
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/context"
@@ -94,9 +95,9 @@ func NewDiffPatchPost(ctx *context.Context) {
Content: strings.ReplaceAll(form.Content, "\r", ""),
})
if err != nil {
- if models.IsErrBranchAlreadyExists(err) {
+ if git_model.IsErrBranchAlreadyExists(err) {
// User has specified a branch that already exists
- branchErr := err.(models.ErrBranchAlreadyExists)
+ branchErr := err.(git_model.ErrBranchAlreadyExists)
ctx.Data["Err_NewBranchName"] = true
ctx.RenderWithErr(ctx.Tr("repo.editor.branch_already_exists", branchErr.BranchName), tplEditFile, &form)
return
diff --git a/routers/web/repo/pull.go b/routers/web/repo/pull.go
index f2a58a35a7..950979a6ed 100644
--- a/routers/web/repo/pull.go
+++ b/routers/web/repo/pull.go
@@ -1493,7 +1493,7 @@ func UpdatePullRequestTarget(ctx *context.Context) {
"error": err.Error(),
"user_error": errorMessage,
})
- } else if models.IsErrBranchesEqual(err) {
+ } else if git_model.IsErrBranchesEqual(err) {
errorMessage := ctx.Tr("repo.pulls.nothing_to_compare")
ctx.Flash.Error(errorMessage)
diff --git a/routers/web/repo/setting_protected_branch.go b/routers/web/repo/setting_protected_branch.go
index 1a944799c2..ae8a799f06 100644
--- a/routers/web/repo/setting_protected_branch.go
+++ b/routers/web/repo/setting_protected_branch.go
@@ -286,7 +286,7 @@ func SettingsProtectedBranchPost(ctx *context.Context) {
}
// FIXME: since we only need to recheck files protected rules, we could improve this
- matchedBranches, err := git_model.FindAllMatchedBranches(ctx, ctx.Repo.GitRepo, protectBranch.RuleName)
+ matchedBranches, err := git_model.FindAllMatchedBranches(ctx, ctx.Repo.Repository.ID, protectBranch.RuleName)
if err != nil {
ctx.ServerError("FindAllMatchedBranches", err)
return