code.gitea.io/gitea@v1.22.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 ObjectID) (string, error) {
    34  	wr, rd, cancel, err := repo.CatFileBatchCheck(repo.Ctx)
    35  	if err != nil {
    36  		return "", err
    37  	}
    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 ObjectID, 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, err := repo.CatFileBatch(repo.Ctx)
    96  	if err != nil {
    97  		return nil, err
    98  	}
    99  	defer cancel()
   100  
   101  	if _, err := wr.Write([]byte(tagID.String() + "\n")); err != nil {
   102  		return nil, err
   103  	}
   104  	_, typ, size, err := ReadBatchLine(rd)
   105  	if err != nil {
   106  		if errors.Is(err, io.EOF) || IsErrNotExist(err) {
   107  			return nil, ErrNotExist{ID: tagID.String()}
   108  		}
   109  		return nil, err
   110  	}
   111  	if typ != "tag" {
   112  		if err := DiscardFull(rd, size+1); err != nil {
   113  			return nil, err
   114  		}
   115  		return nil, ErrNotExist{ID: tagID.String()}
   116  	}
   117  
   118  	// then we need to parse the tag
   119  	// and load the commit
   120  	data, err := io.ReadAll(io.LimitReader(rd, size))
   121  	if err != nil {
   122  		return nil, err
   123  	}
   124  	_, err = rd.Discard(1)
   125  	if err != nil {
   126  		return nil, err
   127  	}
   128  
   129  	tag, err := parseTagData(tagID.Type(), data)
   130  	if err != nil {
   131  		return nil, err
   132  	}
   133  
   134  	tag.Name = name
   135  	tag.ID = tagID
   136  	tag.Type = tp
   137  
   138  	repo.tagCache.Set(tagID.String(), tag)
   139  	return tag, nil
   140  }