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  }