code.gitea.io/gitea@v1.21.7/models/git/branch_list.go (about) 1 // Copyright 2023 The Gitea Authors. All rights reserved. 2 // SPDX-License-Identifier: MIT 3 4 package git 5 6 import ( 7 "context" 8 9 "code.gitea.io/gitea/models/db" 10 user_model "code.gitea.io/gitea/models/user" 11 "code.gitea.io/gitea/modules/container" 12 "code.gitea.io/gitea/modules/util" 13 14 "xorm.io/builder" 15 "xorm.io/xorm" 16 ) 17 18 type BranchList []*Branch 19 20 func (branches BranchList) LoadDeletedBy(ctx context.Context) error { 21 ids := container.Set[int64]{} 22 for _, branch := range branches { 23 if !branch.IsDeleted { 24 continue 25 } 26 ids.Add(branch.DeletedByID) 27 } 28 usersMap := make(map[int64]*user_model.User, len(ids)) 29 if err := db.GetEngine(ctx).In("id", ids.Values()).Find(&usersMap); err != nil { 30 return err 31 } 32 for _, branch := range branches { 33 if !branch.IsDeleted { 34 continue 35 } 36 branch.DeletedBy = usersMap[branch.DeletedByID] 37 if branch.DeletedBy == nil { 38 branch.DeletedBy = user_model.NewGhostUser() 39 } 40 } 41 return nil 42 } 43 44 func (branches BranchList) LoadPusher(ctx context.Context) error { 45 ids := container.Set[int64]{} 46 for _, branch := range branches { 47 if branch.PusherID > 0 { // pusher_id maybe zero because some branches are sync by backend with no pusher 48 ids.Add(branch.PusherID) 49 } 50 } 51 usersMap := make(map[int64]*user_model.User, len(ids)) 52 if err := db.GetEngine(ctx).In("id", ids.Values()).Find(&usersMap); err != nil { 53 return err 54 } 55 for _, branch := range branches { 56 if branch.PusherID <= 0 { 57 continue 58 } 59 branch.Pusher = usersMap[branch.PusherID] 60 if branch.Pusher == nil { 61 branch.Pusher = user_model.NewGhostUser() 62 } 63 } 64 return nil 65 } 66 67 type FindBranchOptions struct { 68 db.ListOptions 69 RepoID int64 70 ExcludeBranchNames []string 71 IsDeletedBranch util.OptionalBool 72 OrderBy string 73 Keyword string 74 } 75 76 func (opts FindBranchOptions) ToConds() builder.Cond { 77 cond := builder.NewCond() 78 if opts.RepoID > 0 { 79 cond = cond.And(builder.Eq{"repo_id": opts.RepoID}) 80 } 81 82 if len(opts.ExcludeBranchNames) > 0 { 83 cond = cond.And(builder.NotIn("name", opts.ExcludeBranchNames)) 84 } 85 if !opts.IsDeletedBranch.IsNone() { 86 cond = cond.And(builder.Eq{"is_deleted": opts.IsDeletedBranch.IsTrue()}) 87 } 88 if opts.Keyword != "" { 89 cond = cond.And(builder.Like{"name", opts.Keyword}) 90 } 91 return cond 92 } 93 94 func CountBranches(ctx context.Context, opts FindBranchOptions) (int64, error) { 95 return db.GetEngine(ctx).Where(opts.ToConds()).Count(&Branch{}) 96 } 97 98 func orderByBranches(sess *xorm.Session, opts FindBranchOptions) *xorm.Session { 99 if !opts.IsDeletedBranch.IsFalse() { // if deleted branch included, put them at the end 100 sess = sess.OrderBy("is_deleted ASC") 101 } 102 103 if opts.OrderBy == "" { 104 // the commit_time might be the same, so add the "name" to make sure the order is stable 105 opts.OrderBy = "commit_time DESC, name ASC" 106 } 107 return sess.OrderBy(opts.OrderBy) 108 } 109 110 func FindBranches(ctx context.Context, opts FindBranchOptions) (BranchList, error) { 111 sess := db.GetEngine(ctx).Where(opts.ToConds()) 112 if opts.PageSize > 0 && !opts.IsListAll() { 113 sess = db.SetSessionPagination(sess, &opts.ListOptions) 114 } 115 sess = orderByBranches(sess, opts) 116 117 var branches []*Branch 118 return branches, sess.Find(&branches) 119 } 120 121 func FindBranchNames(ctx context.Context, opts FindBranchOptions) ([]string, error) { 122 sess := db.GetEngine(ctx).Select("name").Where(opts.ToConds()) 123 if opts.PageSize > 0 && !opts.IsListAll() { 124 sess = db.SetSessionPagination(sess, &opts.ListOptions) 125 } 126 sess = orderByBranches(sess, opts) 127 var branches []string 128 if err := sess.Table("branch").Find(&branches); err != nil { 129 return nil, err 130 } 131 return branches, nil 132 } 133 134 func FindBranchesByRepoAndBranchName(ctx context.Context, repoBranches map[int64]string) (map[int64]string, error) { 135 cond := builder.NewCond() 136 for repoID, branchName := range repoBranches { 137 cond = cond.Or(builder.And(builder.Eq{"repo_id": repoID}, builder.Eq{"name": branchName})) 138 } 139 var branches []*Branch 140 if err := db.GetEngine(ctx). 141 Where(cond).Find(&branches); err != nil { 142 return nil, err 143 } 144 branchMap := make(map[int64]string, len(branches)) 145 for _, branch := range branches { 146 branchMap[branch.RepoID] = branch.CommitID 147 } 148 return branchMap, nil 149 }