code.gitea.io/gitea@v1.22.3/modules/git/repo_branch_gogit.go (about) 1 // Copyright 2015 The Gogs Authors. All rights reserved. 2 // Copyright 2018 The Gitea Authors. All rights reserved. 3 // SPDX-License-Identifier: MIT 4 5 //go:build gogit 6 7 package git 8 9 import ( 10 "sort" 11 "strings" 12 13 "github.com/go-git/go-git/v5/plumbing" 14 "github.com/go-git/go-git/v5/plumbing/storer" 15 ) 16 17 // IsObjectExist returns true if the given object exists in the repository. 18 // FIXME: Inconsistent behavior with nogogit edition 19 // Unlike the implementation of IsObjectExist in nogogit edition, it does not support short hashes here. 20 // For example, IsObjectExist("153f451") will return false, but it will return true in nogogit edition. 21 // To fix this, the solution could be adding support for short hashes in gogit edition if it's really needed. 22 func (repo *Repository) IsObjectExist(name string) bool { 23 if name == "" { 24 return false 25 } 26 27 _, err := repo.gogitRepo.Object(plumbing.AnyObject, plumbing.NewHash(name)) 28 return err == nil 29 } 30 31 // IsReferenceExist returns true if given reference exists in the repository. 32 // FIXME: Inconsistent behavior with nogogit edition 33 // Unlike the implementation of IsObjectExist in nogogit edition, it does not support blob hashes here. 34 // For example, IsObjectExist([existing_blob_hash]) will return false, but it will return true in nogogit edition. 35 // To fix this, the solution could be refusing to support blob hashes in nogogit edition since a blob hash is not a reference. 36 func (repo *Repository) IsReferenceExist(name string) bool { 37 if name == "" { 38 return false 39 } 40 41 _, err := repo.gogitRepo.ResolveRevision(plumbing.Revision(name)) 42 43 return err == nil 44 } 45 46 // IsBranchExist returns true if given branch exists in current repository. 47 func (repo *Repository) IsBranchExist(name string) bool { 48 if name == "" { 49 return false 50 } 51 reference, err := repo.gogitRepo.Reference(plumbing.ReferenceName(BranchPrefix+name), true) 52 if err != nil { 53 return false 54 } 55 return reference.Type() != plumbing.InvalidReference 56 } 57 58 // GetBranches returns branches from the repository, skipping "skip" initial branches and 59 // returning at most "limit" branches, or all branches if "limit" is 0. 60 // Branches are returned with sort of `-commiterdate` as the nogogit 61 // implementation. This requires full fetch, sort and then the 62 // skip/limit applies later as gogit returns in undefined order. 63 func (repo *Repository) GetBranchNames(skip, limit int) ([]string, int, error) { 64 type BranchData struct { 65 name string 66 committerDate int64 67 } 68 var branchData []BranchData 69 70 branchIter, err := repo.gogitRepo.Branches() 71 if err != nil { 72 return nil, 0, err 73 } 74 75 _ = branchIter.ForEach(func(branch *plumbing.Reference) error { 76 obj, err := repo.gogitRepo.CommitObject(branch.Hash()) 77 if err != nil { 78 // skip branch if can't find commit 79 return nil 80 } 81 82 branchData = append(branchData, BranchData{strings.TrimPrefix(branch.Name().String(), BranchPrefix), obj.Committer.When.Unix()}) 83 return nil 84 }) 85 86 sort.Slice(branchData, func(i, j int) bool { 87 return !(branchData[i].committerDate < branchData[j].committerDate) 88 }) 89 90 var branchNames []string 91 maxPos := len(branchData) 92 if limit > 0 { 93 maxPos = min(skip+limit, maxPos) 94 } 95 for i := skip; i < maxPos; i++ { 96 branchNames = append(branchNames, branchData[i].name) 97 } 98 99 return branchNames, len(branchData), nil 100 } 101 102 // WalkReferences walks all the references from the repository 103 func (repo *Repository) WalkReferences(arg ObjectType, skip, limit int, walkfn func(sha1, refname string) error) (int, error) { 104 i := 0 105 var iter storer.ReferenceIter 106 var err error 107 switch arg { 108 case ObjectTag: 109 iter, err = repo.gogitRepo.Tags() 110 case ObjectBranch: 111 iter, err = repo.gogitRepo.Branches() 112 default: 113 iter, err = repo.gogitRepo.References() 114 } 115 if err != nil { 116 return i, err 117 } 118 defer iter.Close() 119 120 err = iter.ForEach(func(ref *plumbing.Reference) error { 121 if i < skip { 122 i++ 123 return nil 124 } 125 err := walkfn(ref.Hash().String(), string(ref.Name())) 126 i++ 127 if err != nil { 128 return err 129 } 130 if limit != 0 && i >= skip+limit { 131 return storer.ErrStop 132 } 133 return nil 134 }) 135 return i, err 136 } 137 138 // GetRefsBySha returns all references filtered with prefix that belong to a sha commit hash 139 func (repo *Repository) GetRefsBySha(sha, prefix string) ([]string, error) { 140 var revList []string 141 iter, err := repo.gogitRepo.References() 142 if err != nil { 143 return nil, err 144 } 145 err = iter.ForEach(func(ref *plumbing.Reference) error { 146 if ref.Hash().String() == sha && strings.HasPrefix(string(ref.Name()), prefix) { 147 revList = append(revList, string(ref.Name())) 148 } 149 return nil 150 }) 151 return revList, err 152 }