github.com/gitbundle/modules@v0.0.0-20231025071548-85b91c5c3b01/git/repo_tag_nogogit.go (about) 1 // Copyright 2023 The GitBundle Inc. All rights reserved. 2 // Copyright 2017 The Gitea Authors. All rights reserved. 3 // Use of this source code is governed by a MIT-style 4 // license that can be found in the LICENSE file. 5 6 // Copyright 2015 The Gogs Authors. All rights reserved. 7 8 //go:build !gogit 9 10 package git 11 12 import ( 13 "errors" 14 "io" 15 16 "github.com/gitbundle/modules/log" 17 ) 18 19 // IsTagExist returns true if given tag exists in the repository. 20 func (repo *Repository) IsTagExist(name string) bool { 21 if name == "" { 22 return false 23 } 24 25 return repo.IsReferenceExist(TagPrefix + name) 26 } 27 28 // GetTags returns all tags of the repository. 29 // returning at most limit tags, or all if limit is 0. 30 func (repo *Repository) GetTags(skip, limit int) (tags []string, err error) { 31 tags, _, err = callShowRef(repo.Ctx, repo.Path, TagPrefix, "--tags", skip, limit) 32 return 33 } 34 35 // GetTagType gets the type of the tag, either commit (simple) or tag (annotated) 36 func (repo *Repository) GetTagType(id SHA1) (string, error) { 37 wr, rd, cancel := repo.CatFileBatchCheck(repo.Ctx) 38 defer cancel() 39 _, err := wr.Write([]byte(id.String() + "\n")) 40 if err != nil { 41 return "", err 42 } 43 _, typ, _, err := ReadBatchLine(rd) 44 if IsErrNotExist(err) { 45 return "", ErrNotExist{ID: id.String()} 46 } 47 return typ, nil 48 } 49 50 func (repo *Repository) getTag(tagID SHA1, name string) (*Tag, error) { 51 t, ok := repo.tagCache.Get(tagID.String()) 52 if ok { 53 log.Debug("Hit cache: %s", tagID) 54 tagClone := *t.(*Tag) 55 tagClone.Name = name // This is necessary because lightweight tags may have same id 56 return &tagClone, nil 57 } 58 59 tp, err := repo.GetTagType(tagID) 60 if err != nil { 61 return nil, err 62 } 63 64 // Get the commit ID and tag ID (may be different for annotated tag) for the returned tag object 65 commitIDStr, err := repo.GetTagCommitID(name) 66 if err != nil { 67 // every tag should have a commit ID so return all errors 68 return nil, err 69 } 70 commitID, err := NewIDFromString(commitIDStr) 71 if err != nil { 72 return nil, err 73 } 74 75 // If type is "commit, the tag is a lightweight tag 76 if ObjectType(tp) == ObjectCommit { 77 commit, err := repo.GetCommit(commitIDStr) 78 if err != nil { 79 return nil, err 80 } 81 tag := &Tag{ 82 Name: name, 83 ID: tagID, 84 Object: commitID, 85 Type: tp, 86 Tagger: commit.Committer, 87 Message: commit.Message(), 88 } 89 90 repo.tagCache.Set(tagID.String(), tag) 91 return tag, nil 92 } 93 94 // The tag is an annotated tag with a message. 95 wr, rd, cancel := repo.CatFileBatch(repo.Ctx) 96 defer cancel() 97 98 if _, err := wr.Write([]byte(tagID.String() + "\n")); err != nil { 99 return nil, err 100 } 101 _, typ, size, err := ReadBatchLine(rd) 102 if err != nil { 103 if errors.Is(err, io.EOF) || IsErrNotExist(err) { 104 return nil, ErrNotExist{ID: tagID.String()} 105 } 106 return nil, err 107 } 108 if typ != "tag" { 109 return nil, ErrNotExist{ID: tagID.String()} 110 } 111 112 // then we need to parse the tag 113 // and load the commit 114 data, err := io.ReadAll(io.LimitReader(rd, size)) 115 if err != nil { 116 return nil, err 117 } 118 _, err = rd.Discard(1) 119 if err != nil { 120 return nil, err 121 } 122 123 tag, err := parseTagData(data) 124 if err != nil { 125 return nil, err 126 } 127 128 tag.Name = name 129 tag.ID = tagID 130 tag.Type = tp 131 132 repo.tagCache.Set(tagID.String(), tag) 133 return tag, nil 134 }