diff options
author | Lunny Xiao <xiaolunwen@gmail.com> | 2023-06-29 18:03:20 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-06-29 10:03:20 +0000 |
commit | 6e19484f4d3bf372212f2da462110a1a8c10cbf2 (patch) | |
tree | e8f1b4920b286241e4ad59151b4f00d9941a27aa /routers | |
parent | 5a871932f0efc19a731ee5c1202679653d3cefff (diff) | |
download | gitea-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.go | 83 | ||||
-rw-r--r-- | routers/api/v1/repo/file.go | 6 | ||||
-rw-r--r-- | routers/api/v1/repo/patch.go | 5 | ||||
-rw-r--r-- | routers/web/admin/admin.go | 25 | ||||
-rw-r--r-- | routers/web/repo/branch.go | 213 | ||||
-rw-r--r-- | routers/web/repo/cherry_pick.go | 9 | ||||
-rw-r--r-- | routers/web/repo/compare.go | 17 | ||||
-rw-r--r-- | routers/web/repo/editor.go | 12 | ||||
-rw-r--r-- | routers/web/repo/issue.go | 8 | ||||
-rw-r--r-- | routers/web/repo/patch.go | 5 | ||||
-rw-r--r-- | routers/web/repo/pull.go | 2 | ||||
-rw-r--r-- | routers/web/repo/setting_protected_branch.go | 2 |
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 |