亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

獲取特定分支的標簽

獲取特定分支的標簽

Go
溫溫醬 2023-07-26 13:23:23
使用go-git:有沒有辦法只獲取特定分支的(輕量級和帶注釋的)標簽?由于我主要對主分支的標簽感興趣,所以類似的東西git tag --merged也足夠了。使用基本的 go-git 方法似乎不可能,例如Tags()......
查看完整描述

1 回答

?
慕村9548890

TA貢獻1884條經驗 獲得超4個贊

不完全是一個簡短的解決方案,但以下代碼通過以下方式實現了目標:

  1. 讀取整個分支的提交哈希值。

  2. 讀取存儲庫的所有標簽。

  3. 檢查并僅打印散列位于分支中的標簽。

注意:尚未嘗試使用帶注釋的標簽。但應該很接近。

package main


import (

    "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)

        }

    }

}


查看完整回答
反對 回復 2023-07-26
  • 1 回答
  • 0 關注
  • 152 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號