You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

repo_branch_gogit.go 3.8KB

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