慕村9548890
不完全是一个简短的解决方案,但以下代码通过以下方式实现了目标:读取整个分支的提交哈希值。读取存储库的所有标签。检查并仅打印散列位于分支中的标签。注意:尚未尝试使用带注释的标签。但应该很接近。package mainimport ( "log" "github.com/src-d/go-billy/memfs" "gopkg.in/src-d/go-git.v4" "gopkg.in/src-d/go-git.v4/plumbing" "gopkg.in/src-d/go-git.v4/plumbing/object" "gopkg.in/src-d/go-git.v4/storage/memory")func getBranchHashes(repo *git.Repository, branchName string) (hashes map[plumbing.Hash]bool, err error) { // get branch reference name branch, err := repo.Branch("master") if err != nil { return } // get reference of the reference name ref, err := repo.Reference(branch.Merge, true) if err != nil { return } // retrieve logs from the branch reference commit // (default order is depth first) logs, err := repo.Log(&git.LogOptions{ From: ref.Hash(), }) if err != nil { return } defer logs.Close() // a channel to collect all hashes chHash := make(chan plumbing.Hash) chErr := make(chan error) go func() { err = logs.ForEach(func(commit *object.Commit) (err error) { chHash <- commit.Hash return }) if err != nil { chErr <- err } close(chErr) close(chHash) }() // make all hashes into a map hashes = make(map[plumbing.Hash]bool)hashLoop: for { select { case err = <-chErr: if err != nil { return } break hashLoop case h := <-chHash: hashes[h] = true } } return}type TagRef struct { Hash plumbing.Hash Name string}func main() { // Filesystem abstraction based on memory fs := memfs.New() // Git objects storer based on memory storer := memory.NewStorage() // Clones the repository into the worktree (fs) and storer all the .git // content into the storer repo, err := git.Clone(storer, fs, &git.CloneOptions{ URL: "https://github.com/yookoala/gofast.git", }) if err != nil { log.Fatal(err) } hashes, err := getBranchHashes(repo, "master") if err != nil { log.Fatal(err) } // get all tags in the repo tags, err := repo.Tags() if err != nil { log.Fatal(err) } tagRefs := make(chan TagRef) go func() { err = tags.ForEach(func(ref *plumbing.Reference) (err error) { if annotedTag, err := repo.TagObject(ref.Hash()); err != plumbing.ErrObjectNotFound { if annotedTag.TargetType == plumbing.CommitObject { tagRefs <- TagRef{ Hash: annotedTag.Target, Name: ref.Name().Short(), } } return nil } tagRefs <- TagRef{ Hash: ref.Hash(), Name: ref.Name().Short(), } return }) if err != nil { log.Fatal(err) } close(tagRefs) }() for tagRef := range tagRefs { if _, ok := hashes[tagRef.Hash]; ok { log.Printf("tag: %s, hash: %s", tagRef.Name, tagRef.Hash) } }}