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  }