* Use go-git for tree reading and commit info lookup. Signed-off-by: Filip Navara <navara@emclient.com> * Use TreeEntry.IsRegular() instead of ObjectType that was removed. Signed-off-by: Filip Navara <navara@emclient.com> * Use the treePath to optimize commit info search. Signed-off-by: Filip Navara <navara@emclient.com> * Extract the latest commit at treePath along with the other commits. Signed-off-by: Filip Navara <navara@emclient.com> * Fix listing commit info for a directory that was created in one commit and never modified after. Signed-off-by: Filip Navara <navara@emclient.com> * Avoid nearly all external 'git' invocations when doing directory listing (.editorconfig code path is still hit). Signed-off-by: Filip Navara <navara@emclient.com> * Use go-git for reading blobs. Signed-off-by: Filip Navara <navara@emclient.com> * Make SHA1 type alias for plumbing.Hash in go-git. Signed-off-by: Filip Navara <navara@emclient.com> * Make Signature type alias for object.Signature in go-git. Signed-off-by: Filip Navara <navara@emclient.com> * Fix GetCommitsInfo for repository with only one commit. Signed-off-by: Filip Navara <navara@emclient.com> * Fix PGP signature verification. Signed-off-by: Filip Navara <navara@emclient.com> * Fix issues with walking commit graph across merges. Signed-off-by: Filip Navara <navara@emclient.com> * Fix typo in condition. Signed-off-by: Filip Navara <navara@emclient.com> * Speed up loading branch list by keeping the repository reference (and thus all the loaded packfile indexes). Signed-off-by: Filip Navara <navara@emclient.com> * Fix lising submodules. Signed-off-by: Filip Navara <navara@emclient.com> * Fix build Signed-off-by: Filip Navara <navara@emclient.com> * Add back commit cache because of name-rev Signed-off-by: Filip Navara <navara@emclient.com> * Fix tests Signed-off-by: Filip Navara <navara@emclient.com> * Fix code style * Fix spelling * Address PR feedback Signed-off-by: Filip Navara <navara@emclient.com> * Update vendor module list Signed-off-by: Filip Navara <navara@emclient.com> * Fix getting trees by commit id Signed-off-by: Filip Navara <navara@emclient.com> * Fix remaining unit test failures * Fix GetTreeBySHA * Avoid running `git name-rev` if not necessary Signed-off-by: Filip Navara <navara@emclient.com> * Move Branch code to git module * Clean up GPG signature verification and fix it for tagged commits * Address PR feedback (import formatting, copyright headers) * Make blob lookup by SHA working * Update tests to use public API * Allow getting content from any type of object through the blob interface * Change test to actually expect the object content that is in the GIT repository * Change one more test to actually expect the object content that is in the GIT repository * Add comments
152 lines
3.3 KiB
Go
152 lines
3.3 KiB
Go
// Copyright 2015 The Gogs Authors. All rights reserved.
|
|
// Copyright 2019 The Gitea Authors. All rights reserved.
|
|
// Use of this source code is governed by a MIT-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package git
|
|
|
|
import (
|
|
"strings"
|
|
|
|
"github.com/mcuadros/go-version"
|
|
"gopkg.in/src-d/go-git.v4/plumbing"
|
|
)
|
|
|
|
// TagPrefix tags prefix path on the repository
|
|
const TagPrefix = "refs/tags/"
|
|
|
|
// IsTagExist returns true if given tag exists in the repository.
|
|
func IsTagExist(repoPath, name string) bool {
|
|
return IsReferenceExist(repoPath, TagPrefix+name)
|
|
}
|
|
|
|
// IsTagExist returns true if given tag exists in the repository.
|
|
func (repo *Repository) IsTagExist(name string) bool {
|
|
_, err := repo.gogitRepo.Reference(plumbing.ReferenceName(TagPrefix+name), true)
|
|
if err != nil {
|
|
return false
|
|
}
|
|
return true
|
|
}
|
|
|
|
// CreateTag create one tag in the repository
|
|
func (repo *Repository) CreateTag(name, revision string) error {
|
|
_, err := NewCommand("tag", name, revision).RunInDir(repo.Path)
|
|
return err
|
|
}
|
|
|
|
func (repo *Repository) getTag(id SHA1) (*Tag, error) {
|
|
t, ok := repo.tagCache.Get(id.String())
|
|
if ok {
|
|
log("Hit cache: %s", id)
|
|
return t.(*Tag), nil
|
|
}
|
|
|
|
// Get tag type
|
|
tp, err := NewCommand("cat-file", "-t", id.String()).RunInDir(repo.Path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
tp = strings.TrimSpace(tp)
|
|
|
|
// Tag is a commit.
|
|
if ObjectType(tp) == ObjectCommit {
|
|
tag := &Tag{
|
|
ID: id,
|
|
Object: id,
|
|
Type: string(ObjectCommit),
|
|
repo: repo,
|
|
}
|
|
|
|
repo.tagCache.Set(id.String(), tag)
|
|
return tag, nil
|
|
}
|
|
|
|
// Tag with message.
|
|
data, err := NewCommand("cat-file", "-p", id.String()).RunInDirBytes(repo.Path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
tag, err := parseTagData(data)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
tag.ID = id
|
|
tag.repo = repo
|
|
|
|
repo.tagCache.Set(id.String(), tag)
|
|
return tag, nil
|
|
}
|
|
|
|
// GetTag returns a Git tag by given name.
|
|
func (repo *Repository) GetTag(name string) (*Tag, error) {
|
|
idStr, err := repo.GetTagCommitID(name)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
id, err := NewIDFromString(idStr)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
tag, err := repo.getTag(id)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
tag.Name = name
|
|
return tag, nil
|
|
}
|
|
|
|
// GetTagInfos returns all tag infos of the repository.
|
|
func (repo *Repository) GetTagInfos() ([]*Tag, error) {
|
|
// TODO this a slow implementation, makes one git command per tag
|
|
stdout, err := NewCommand("tag").RunInDir(repo.Path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
tagNames := strings.Split(stdout, "\n")
|
|
var tags = make([]*Tag, 0, len(tagNames))
|
|
for _, tagName := range tagNames {
|
|
tagName = strings.TrimSpace(tagName)
|
|
if len(tagName) == 0 {
|
|
continue
|
|
}
|
|
|
|
tag, err := repo.GetTag(tagName)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
tags = append(tags, tag)
|
|
}
|
|
sortTagsByTime(tags)
|
|
return tags, nil
|
|
}
|
|
|
|
// GetTags returns all tags of the repository.
|
|
func (repo *Repository) GetTags() ([]string, error) {
|
|
var tagNames []string
|
|
|
|
tags, err := repo.gogitRepo.Tags()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
tags.ForEach(func(tag *plumbing.Reference) error {
|
|
tagNames = append(tagNames, strings.TrimPrefix(tag.Name().String(), TagPrefix))
|
|
return nil
|
|
})
|
|
|
|
version.Sort(tagNames)
|
|
|
|
// Reverse order
|
|
for i := 0; i < len(tagNames)/2; i++ {
|
|
j := len(tagNames) - i - 1
|
|
tagNames[i], tagNames[j] = tagNames[j], tagNames[i]
|
|
}
|
|
|
|
return tagNames, nil
|
|
}
|