code.gitea.io/gitea@v1.19.3/modules/git/repo_tag_gogit.go (about) 1 // Copyright 2015 The Gogs Authors. All rights reserved. 2 // Copyright 2019 The Gitea Authors. All rights reserved. 3 // SPDX-License-Identifier: MIT 4 5 //go:build gogit 6 7 package git 8 9 import ( 10 "strings" 11 12 "code.gitea.io/gitea/modules/log" 13 14 "github.com/go-git/go-git/v5/plumbing" 15 ) 16 17 // IsTagExist returns true if given tag exists in the repository. 18 func (repo *Repository) IsTagExist(name string) bool { 19 _, err := repo.gogitRepo.Reference(plumbing.ReferenceName(TagPrefix+name), true) 20 return err == nil 21 } 22 23 // GetTags returns all tags of the repository. 24 // returning at most limit tags, or all if limit is 0. 25 func (repo *Repository) GetTags(skip, limit int) ([]string, error) { 26 var tagNames []string 27 28 tags, err := repo.gogitRepo.Tags() 29 if err != nil { 30 return nil, err 31 } 32 33 _ = tags.ForEach(func(tag *plumbing.Reference) error { 34 tagNames = append(tagNames, strings.TrimPrefix(tag.Name().String(), TagPrefix)) 35 return nil 36 }) 37 38 // Reverse order 39 for i := 0; i < len(tagNames)/2; i++ { 40 j := len(tagNames) - i - 1 41 tagNames[i], tagNames[j] = tagNames[j], tagNames[i] 42 } 43 44 // since we have to reverse order we can paginate only afterwards 45 if len(tagNames) < skip { 46 tagNames = []string{} 47 } else { 48 tagNames = tagNames[skip:] 49 } 50 if limit != 0 && len(tagNames) > limit { 51 tagNames = tagNames[:limit] 52 } 53 54 return tagNames, nil 55 } 56 57 // GetTagType gets the type of the tag, either commit (simple) or tag (annotated) 58 func (repo *Repository) GetTagType(id SHA1) (string, error) { 59 // Get tag type 60 obj, err := repo.gogitRepo.Object(plumbing.AnyObject, id) 61 if err != nil { 62 if err == plumbing.ErrReferenceNotFound { 63 return "", &ErrNotExist{ID: id.String()} 64 } 65 return "", err 66 } 67 68 return obj.Type().String(), nil 69 } 70 71 func (repo *Repository) getTag(tagID SHA1, name string) (*Tag, error) { 72 t, ok := repo.tagCache.Get(tagID.String()) 73 if ok { 74 log.Debug("Hit cache: %s", tagID) 75 tagClone := *t.(*Tag) 76 tagClone.Name = name // This is necessary because lightweight tags may have same id 77 return &tagClone, nil 78 } 79 80 tp, err := repo.GetTagType(tagID) 81 if err != nil { 82 return nil, err 83 } 84 85 // Get the commit ID and tag ID (may be different for annotated tag) for the returned tag object 86 commitIDStr, err := repo.GetTagCommitID(name) 87 if err != nil { 88 // every tag should have a commit ID so return all errors 89 return nil, err 90 } 91 commitID, err := NewIDFromString(commitIDStr) 92 if err != nil { 93 return nil, err 94 } 95 96 // If type is "commit, the tag is a lightweight tag 97 if ObjectType(tp) == ObjectCommit { 98 commit, err := repo.GetCommit(commitIDStr) 99 if err != nil { 100 return nil, err 101 } 102 tag := &Tag{ 103 Name: name, 104 ID: tagID, 105 Object: commitID, 106 Type: tp, 107 Tagger: commit.Committer, 108 Message: commit.Message(), 109 } 110 111 repo.tagCache.Set(tagID.String(), tag) 112 return tag, nil 113 } 114 115 gogitTag, err := repo.gogitRepo.TagObject(tagID) 116 if err != nil { 117 if err == plumbing.ErrReferenceNotFound { 118 return nil, &ErrNotExist{ID: tagID.String()} 119 } 120 121 return nil, err 122 } 123 124 tag := &Tag{ 125 Name: name, 126 ID: tagID, 127 Object: gogitTag.Target, 128 Type: tp, 129 Tagger: &gogitTag.Tagger, 130 Message: gogitTag.Message, 131 } 132 133 repo.tagCache.Set(tagID.String(), tag) 134 return tag, nil 135 }