@@ -52,7 +52,25 @@ func Branches(ctx *context.Context) {
5252 ctx .Data ["PageIsViewCode" ] = true
5353 ctx .Data ["PageIsBranches" ] = true
5454
55- ctx .Data ["Branches" ] = loadBranches (ctx )
55+ page := ctx .QueryInt ("page" )
56+ if page <= 1 {
57+ page = 1
58+ }
59+
60+ pageSize := ctx .QueryInt ("limit" )
61+ if pageSize <= 0 || pageSize > git .BranchesRangeSize {
62+ pageSize = git .BranchesRangeSize
63+ }
64+
65+ branches , branchesCount := loadBranches (ctx , page , pageSize )
66+ if ctx .Written () {
67+ return
68+ }
69+ ctx .Data ["Branches" ] = branches
70+ pager := context .NewPagination (int (branchesCount ), git .BranchesRangeSize , page , 5 )
71+ pager .SetDefaultParams (ctx )
72+ ctx .Data ["Page" ] = pager
73+
5674 ctx .HTML (200 , tplBranch )
5775}
5876
@@ -176,17 +194,25 @@ func deleteBranch(ctx *context.Context, branchName string) error {
176194 return nil
177195}
178196
179- func loadBranches (ctx * context.Context ) []* Branch {
197+ // loadBranches loads branches from the repository limited by page & pageSize.
198+ // NOTE: May write to context on error. page & pageSize must be > 0
199+ func loadBranches (ctx * context.Context , page , pageSize int ) ([]* Branch , int ) {
200+ defaultBranch , err := repo_module .GetBranch (ctx .Repo .Repository , ctx .Repo .Repository .DefaultBranch )
201+ if err != nil {
202+ ctx .ServerError ("GetDefaultBranch" , err )
203+ return nil , 0
204+ }
205+
180206 rawBranches , err := repo_module .GetBranches (ctx .Repo .Repository )
181207 if err != nil {
182208 ctx .ServerError ("GetBranches" , err )
183- return nil
209+ return nil , 0
184210 }
185211
186212 protectedBranches , err := ctx .Repo .Repository .GetProtectedBranches ()
187213 if err != nil {
188214 ctx .ServerError ("GetProtectedBranches" , err )
189- return nil
215+ return nil , 0
190216 }
191217
192218 repoIDToRepo := map [int64 ]* models.Repository {}
@@ -195,100 +221,129 @@ func loadBranches(ctx *context.Context) []*Branch {
195221 repoIDToGitRepo := map [int64 ]* git.Repository {}
196222 repoIDToGitRepo [ctx .Repo .Repository .ID ] = ctx .Repo .GitRepo
197223
198- branches := make ([]* Branch , len (rawBranches ))
199- for i := range rawBranches {
200- commit , err := rawBranches [i ].GetCommit ()
224+ var totalNumOfBranches = len (rawBranches )
225+ var startIndex = (page - 1 ) * pageSize
226+ if startIndex > totalNumOfBranches {
227+ startIndex = totalNumOfBranches - 1
228+ }
229+ var endIndex = startIndex + pageSize
230+ if endIndex > totalNumOfBranches {
231+ endIndex = totalNumOfBranches - 1
232+ }
233+
234+ var branches []* Branch
235+ for i := startIndex ; i < endIndex ; i ++ {
236+ var branch = loadOneBranch (ctx , rawBranches [i ], protectedBranches , repoIDToRepo , repoIDToGitRepo )
237+ if branch == nil {
238+ return nil , 0
239+ }
240+
241+ if branch .Name == ctx .Repo .Repository .DefaultBranch {
242+ // Skip default branch
243+ continue
244+ }
245+
246+ branches = append (branches , branch )
247+ }
248+
249+ // Always add the default branch
250+ branches = append (branches , loadOneBranch (ctx , defaultBranch , protectedBranches , repoIDToRepo , repoIDToGitRepo ))
251+
252+ if ctx .Repo .CanWrite (models .UnitTypeCode ) {
253+ deletedBranches , err := getDeletedBranches (ctx )
201254 if err != nil {
202- ctx .ServerError ("GetCommit " , err )
203- return nil
255+ ctx .ServerError ("getDeletedBranches " , err )
256+ return nil , 0
204257 }
258+ branches = append (branches , deletedBranches ... )
259+ }
205260
206- var isProtected bool
207- branchName := rawBranches [i ].Name
208- for _ , b := range protectedBranches {
209- if b .BranchName == branchName {
210- isProtected = true
211- break
212- }
261+ return branches , len (rawBranches ) - 1
262+ }
263+
264+ func loadOneBranch (ctx * context.Context , rawBranch * git.Branch , protectedBranches []* models.ProtectedBranch ,
265+ repoIDToRepo map [int64 ]* models.Repository ,
266+ repoIDToGitRepo map [int64 ]* git.Repository ) * Branch {
267+
268+ commit , err := rawBranch .GetCommit ()
269+ if err != nil {
270+ ctx .ServerError ("GetCommit" , err )
271+ return nil
272+ }
273+
274+ branchName := rawBranch .Name
275+ var isProtected bool
276+ for _ , b := range protectedBranches {
277+ if b .BranchName == branchName {
278+ isProtected = true
279+ break
213280 }
281+ }
282+
283+ divergence , divergenceError := repofiles .CountDivergingCommits (ctx .Repo .Repository , git .BranchPrefix + branchName )
284+ if divergenceError != nil {
285+ ctx .ServerError ("CountDivergingCommits" , divergenceError )
286+ return nil
287+ }
288+
289+ pr , err := models .GetLatestPullRequestByHeadInfo (ctx .Repo .Repository .ID , branchName )
290+ if err != nil {
291+ ctx .ServerError ("GetLatestPullRequestByHeadInfo" , err )
292+ return nil
293+ }
294+ headCommit := commit .ID .String ()
214295
215- divergence , divergenceError := repofiles .CountDivergingCommits (ctx .Repo .Repository , git .BranchPrefix + branchName )
216- if divergenceError != nil {
217- ctx .ServerError ("CountDivergingCommits" , divergenceError )
296+ mergeMovedOn := false
297+ if pr != nil {
298+ pr .HeadRepo = ctx .Repo .Repository
299+ if err := pr .LoadIssue (); err != nil {
300+ ctx .ServerError ("pr.LoadIssue" , err )
218301 return nil
219302 }
220-
221- pr , err := models . GetLatestPullRequestByHeadInfo ( ctx . Repo . Repository . ID , branchName )
222- if err != nil {
223- ctx .ServerError ("GetLatestPullRequestByHeadInfo " , err )
303+ if repo , ok := repoIDToRepo [ pr . BaseRepoID ]; ok {
304+ pr . BaseRepo = repo
305+ } else if err := pr . LoadBaseRepo (); err != nil {
306+ ctx .ServerError ("pr.LoadBaseRepo " , err )
224307 return nil
308+ } else {
309+ repoIDToRepo [pr .BaseRepoID ] = pr .BaseRepo
225310 }
226- headCommit := commit . ID . String ()
311+ pr . Issue . Repo = pr . BaseRepo
227312
228- mergeMovedOn := false
229- if pr != nil {
230- pr .HeadRepo = ctx .Repo .Repository
231- if err := pr .LoadIssue (); err != nil {
232- ctx .ServerError ("pr.LoadIssue" , err )
233- return nil
313+ if pr .HasMerged {
314+ baseGitRepo , ok := repoIDToGitRepo [pr .BaseRepoID ]
315+ if ! ok {
316+ baseGitRepo , err = git .OpenRepository (pr .BaseRepo .RepoPath ())
317+ if err != nil {
318+ ctx .ServerError ("OpenRepository" , err )
319+ return nil
320+ }
321+ defer baseGitRepo .Close ()
322+ repoIDToGitRepo [pr .BaseRepoID ] = baseGitRepo
234323 }
235- if repo , ok := repoIDToRepo [pr .BaseRepoID ]; ok {
236- pr .BaseRepo = repo
237- } else if err := pr .LoadBaseRepo (); err != nil {
238- ctx .ServerError ("pr.LoadBaseRepo" , err )
324+ pullCommit , err := baseGitRepo .GetRefCommitID (pr .GetGitRefName ())
325+ if err != nil && ! git .IsErrNotExist (err ) {
326+ ctx .ServerError ("GetBranchCommitID" , err )
239327 return nil
240- } else {
241- repoIDToRepo [pr .BaseRepoID ] = pr .BaseRepo
242328 }
243- pr .Issue .Repo = pr .BaseRepo
244-
245- if pr .HasMerged {
246- baseGitRepo , ok := repoIDToGitRepo [pr .BaseRepoID ]
247- if ! ok {
248- baseGitRepo , err = git .OpenRepository (pr .BaseRepo .RepoPath ())
249- if err != nil {
250- ctx .ServerError ("OpenRepository" , err )
251- return nil
252- }
253- defer baseGitRepo .Close ()
254- repoIDToGitRepo [pr .BaseRepoID ] = baseGitRepo
255- }
256- pullCommit , err := baseGitRepo .GetRefCommitID (pr .GetGitRefName ())
257- if err != nil && ! git .IsErrNotExist (err ) {
258- ctx .ServerError ("GetBranchCommitID" , err )
259- return nil
260- }
261- if err == nil && headCommit != pullCommit {
262- // the head has moved on from the merge - we shouldn't delete
263- mergeMovedOn = true
264- }
329+ if err == nil && headCommit != pullCommit {
330+ // the head has moved on from the merge - we shouldn't delete
331+ mergeMovedOn = true
265332 }
266333 }
267-
268- isIncluded := divergence .Ahead == 0 && ctx .Repo .Repository .DefaultBranch != branchName
269-
270- branches [i ] = & Branch {
271- Name : branchName ,
272- Commit : commit ,
273- IsProtected : isProtected ,
274- IsIncluded : isIncluded ,
275- CommitsAhead : divergence .Ahead ,
276- CommitsBehind : divergence .Behind ,
277- LatestPullRequest : pr ,
278- MergeMovedOn : mergeMovedOn ,
279- }
280334 }
281335
282- if ctx .Repo .CanWrite (models .UnitTypeCode ) {
283- deletedBranches , err := getDeletedBranches (ctx )
284- if err != nil {
285- ctx .ServerError ("getDeletedBranches" , err )
286- return nil
287- }
288- branches = append (branches , deletedBranches ... )
336+ isIncluded := divergence .Ahead == 0 && ctx .Repo .Repository .DefaultBranch != branchName
337+ return & Branch {
338+ Name : branchName ,
339+ Commit : commit ,
340+ IsProtected : isProtected ,
341+ IsIncluded : isIncluded ,
342+ CommitsAhead : divergence .Ahead ,
343+ CommitsBehind : divergence .Behind ,
344+ LatestPullRequest : pr ,
345+ MergeMovedOn : mergeMovedOn ,
289346 }
290-
291- return branches
292347}
293348
294349func getDeletedBranches (ctx * context.Context ) ([]* Branch , error ) {
0 commit comments