You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

repo_tag.go 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. // Copyright 2015 The Gogs Authors. All rights reserved.
  2. // Copyright 2019 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. package git
  6. import (
  7. "strings"
  8. "github.com/mcuadros/go-version"
  9. "gopkg.in/src-d/go-git.v4/plumbing"
  10. )
  11. // TagPrefix tags prefix path on the repository
  12. const TagPrefix = "refs/tags/"
  13. // IsTagExist returns true if given tag exists in the repository.
  14. func IsTagExist(repoPath, name string) bool {
  15. return IsReferenceExist(repoPath, TagPrefix+name)
  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. if err != nil {
  21. return false
  22. }
  23. return true
  24. }
  25. // CreateTag create one tag in the repository
  26. func (repo *Repository) CreateTag(name, revision string) error {
  27. _, err := NewCommand("tag", name, revision).RunInDir(repo.Path)
  28. return err
  29. }
  30. func (repo *Repository) getTag(id SHA1) (*Tag, error) {
  31. t, ok := repo.tagCache.Get(id.String())
  32. if ok {
  33. log("Hit cache: %s", id)
  34. return t.(*Tag), nil
  35. }
  36. // Get tag type
  37. tp, err := NewCommand("cat-file", "-t", id.String()).RunInDir(repo.Path)
  38. if err != nil {
  39. return nil, err
  40. }
  41. tp = strings.TrimSpace(tp)
  42. // Tag is a commit.
  43. if ObjectType(tp) == ObjectCommit {
  44. tag := &Tag{
  45. ID: id,
  46. Object: id,
  47. Type: string(ObjectCommit),
  48. repo: repo,
  49. }
  50. repo.tagCache.Set(id.String(), tag)
  51. return tag, nil
  52. }
  53. // Tag with message.
  54. data, err := NewCommand("cat-file", "-p", id.String()).RunInDirBytes(repo.Path)
  55. if err != nil {
  56. return nil, err
  57. }
  58. tag, err := parseTagData(data)
  59. if err != nil {
  60. return nil, err
  61. }
  62. tag.ID = id
  63. tag.repo = repo
  64. repo.tagCache.Set(id.String(), tag)
  65. return tag, nil
  66. }
  67. // GetTag returns a Git tag by given name.
  68. func (repo *Repository) GetTag(name string) (*Tag, error) {
  69. idStr, err := repo.GetTagCommitID(name)
  70. if err != nil {
  71. return nil, err
  72. }
  73. id, err := NewIDFromString(idStr)
  74. if err != nil {
  75. return nil, err
  76. }
  77. tag, err := repo.getTag(id)
  78. if err != nil {
  79. return nil, err
  80. }
  81. tag.Name = name
  82. return tag, nil
  83. }
  84. // GetTagInfos returns all tag infos of the repository.
  85. func (repo *Repository) GetTagInfos() ([]*Tag, error) {
  86. // TODO this a slow implementation, makes one git command per tag
  87. stdout, err := NewCommand("tag").RunInDir(repo.Path)
  88. if err != nil {
  89. return nil, err
  90. }
  91. tagNames := strings.Split(stdout, "\n")
  92. var tags = make([]*Tag, 0, len(tagNames))
  93. for _, tagName := range tagNames {
  94. tagName = strings.TrimSpace(tagName)
  95. if len(tagName) == 0 {
  96. continue
  97. }
  98. tag, err := repo.GetTag(tagName)
  99. if err != nil {
  100. return nil, err
  101. }
  102. tags = append(tags, tag)
  103. }
  104. sortTagsByTime(tags)
  105. return tags, nil
  106. }
  107. // GetTags returns all tags of the repository.
  108. func (repo *Repository) GetTags() ([]string, error) {
  109. var tagNames []string
  110. tags, err := repo.gogitRepo.Tags()
  111. if err != nil {
  112. return nil, err
  113. }
  114. tags.ForEach(func(tag *plumbing.Reference) error {
  115. tagNames = append(tagNames, strings.TrimPrefix(tag.Name().String(), TagPrefix))
  116. return nil
  117. })
  118. version.Sort(tagNames)
  119. // Reverse order
  120. for i := 0; i < len(tagNames)/2; i++ {
  121. j := len(tagNames) - i - 1
  122. tagNames[i], tagNames[j] = tagNames[j], tagNames[i]
  123. }
  124. return tagNames, nil
  125. }