]> source.dussan.org Git - gitea.git/commitdiff
Make gogit Repository.GetBranchNames consistent (#28348)
authorAdam Majer <amajer@suse.de>
Thu, 7 Dec 2023 17:08:17 +0000 (17:08 +0000)
committerGitHub <noreply@github.com>
Thu, 7 Dec 2023 17:08:17 +0000 (12:08 -0500)
modules/git/repo_branch_gogit.go

index f9896a7a09047f062571d75bc4755db5e8dca655..1c0d9a18aa9d9c153d27516dd39fc2057beea081 100644 (file)
@@ -8,6 +8,7 @@ package git
 
 import (
        "context"
+       "sort"
        "strings"
 
        "github.com/go-git/go-git/v5/plumbing"
@@ -52,32 +53,46 @@ func (repo *Repository) IsBranchExist(name string) bool {
 
 // GetBranches returns branches from the repository, skipping "skip" initial branches and
 // returning at most "limit" branches, or all branches if "limit" is 0.
+// Branches are returned with sort of `-commiterdate` as the nogogit
+// implementation. This requires full fetch, sort and then the
+// skip/limit applies later as gogit returns in undefined order.
 func (repo *Repository) GetBranchNames(skip, limit int) ([]string, int, error) {
-       var branchNames []string
+       type BranchData struct {
+               name          string
+               committerDate int64
+       }
+       var branchData []BranchData
 
-       branches, err := repo.gogitRepo.Branches()
+       branchIter, err := repo.gogitRepo.Branches()
        if err != nil {
                return nil, 0, err
        }
 
-       i := 0
-       count := 0
-       _ = branches.ForEach(func(branch *plumbing.Reference) error {
-               count++
-               if i < skip {
-                       i++
-                       return nil
-               } else if limit != 0 && count > skip+limit {
+       _ = branchIter.ForEach(func(branch *plumbing.Reference) error {
+               obj, err := repo.gogitRepo.CommitObject(branch.Hash())
+               if err != nil {
+                       // skip branch if can't find commit
                        return nil
                }
 
-               branchNames = append(branchNames, strings.TrimPrefix(branch.Name().String(), BranchPrefix))
+               branchData = append(branchData, BranchData{strings.TrimPrefix(branch.Name().String(), BranchPrefix), obj.Committer.When.Unix()})
                return nil
        })
 
-       // TODO: Sort?
+       sort.Slice(branchData, func(i, j int) bool {
+               return !(branchData[i].committerDate < branchData[j].committerDate)
+       })
+
+       var branchNames []string
+       maxPos := len(branchData)
+       if limit > 0 {
+               maxPos = min(skip+limit, maxPos)
+       }
+       for i := skip; i < maxPos; i++ {
+               branchNames = append(branchNames, branchData[i].name)
+       }
 
-       return branchNames, count, nil
+       return branchNames, len(branchData), nil
 }
 
 // WalkReferences walks all the references from the repository