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