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

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

如何簽出特定的單個文件以使用 go-git 檢查它?

如何簽出特定的單個文件以使用 go-git 檢查它?

Go
慕仙森 2023-02-06 14:49:47
我想克隆一個特定的存儲庫,獲取所有標簽并遍歷它們。對于每個標簽,我想在根目錄中檢出一個特定文件 ( package.json )。如果不存在文件,它應該繼續,否則它應該傳遞它以便我可以檢查它。我從以下代碼開始(我的第一個 Go 應用程序......)package mainimport (    "fmt"    "github.com/go-git/go-billy/v5"    "github.com/go-git/go-billy/v5/memfs"    "github.com/go-git/go-git/v5"    "github.com/go-git/go-git/v5/plumbing"    "github.com/go-git/go-git/v5/plumbing/transport/http"    "github.com/go-git/go-git/v5/storage/memory"    "os")func main() {    authentication := &http.BasicAuth{        Username: "me",        Password: "my-key",    }    repositoryUrl := "my-repo-url"    inMemoryStorage := memory.NewStorage()    inMemoryFilesystem := memfs.New()    repository, err := cloneRepository(repositoryUrl, authentication, inMemoryStorage, inMemoryFilesystem)    if err != nil {        handleError(err)    }    tagsIterator, err := repository.Tags()    if err != nil {        handleError(err)    }    err = tagsIterator.ForEach(func(tag *plumbing.Reference) error {        fmt.Println(tag.Name().Short()) // for debugging purposes        // checkout package.json file ( at root ) via tag        return nil    })    if err != nil {        handleError(err)    }}func cloneRepository(repositoryUrl string, authentication *http.BasicAuth, inMemoryStorage *memory.Storage, inMemoryFilesystem billy.Filesystem) (*git.Repository, error) {    return git.Clone(inMemoryStorage, inMemoryFilesystem, &git.CloneOptions{        URL:  repositoryUrl,        Auth: authentication,    })}func handleError(err error) {    fmt.Println(err)    os.Exit(1)}有人知道如何通過給定標簽嘗試檢查循環內的文件嗎?
查看完整描述

1 回答

?
慕勒3428872

TA貢獻1848條經驗 獲得超6個贊

如果您只需要文件內容,則無需“簽出”任何內容;您可以直接從存儲庫中提取它。但首先要注意:我既不是經驗豐富的 Go 程序員,也沒有合作go-git過,所以可能有更優化的方法來做到這一點。

從標簽開始,您可以:

  1. 獲取標簽指向的提交

  2. 獲取提交指向的樹

  3. 遍歷樹尋找package.json

  4. 如果找到它,請提取相應的 blob?,F在你有了你的內容!

上面的步驟可能看起來像這樣:

func getFileFromRef(repository *git.Repository, ref *plumbing.Hash, filename string) (bool, []byte, error) {

    // Get the commit object corresponding to ref

    commit, err := repository.CommitObject(*ref)

    if err != nil {

        return false, nil, err

    }


    // Get the tree object from the commit

    tree, err := repository.TreeObject(commit.TreeHash)

    if err != nil {

        return false, nil, err

    }


    // Iterate through tree entries

    for _, entry := range tree.Entries {

        // If we find the target file...

        if entry.Name == filename {

            // Get the blob object from the repository

            blob, err := repository.BlobObject(entry.Hash)

            if err != nil {

                return false, nil, err

            }


            // Ask for a Reader

            reader, err := blob.Reader()

            if err != nil {

                return false, nil, err

            }


            // Allocate a slice for the data...

            data := make([]byte, blob.Size)


            // ...and read it in.

            n, err := reader.Read(data)

            if err != nil {

                return false, nil, err

            }


            // Double check that we read as many bytes as

            // we expected

            if int64(n) != blob.Size {

                return true, nil, fmt.Errorf("wrong size")

            }

            return true, data, nil

        }

    }


    return false, nil, nil

}

上面的函數將在給定提交引用filename的情況下在存儲庫的頂層查找(正如所寫的那樣,它不會遍歷子目錄)。您需要修改函數中的tagsIterator.ForEach循環才能執行以下操作:main


    err = tagsIterator.ForEach(func(tag *plumbing.Reference) error {

        // Get the commit to which the tag refers. We need this to

        // resolve annotated tags.

        ref, err := repository.ResolveRevision(plumbing.Revision(tag.Hash().String()))

        if err != nil {

            handleError(err)

        }


        found, content, err := getFileFromRef(repository, ref, "package.json")

        if found && err == nil {

            fmt.Printf("found \"package.json\" in tag %s\n", tag.Name().Short())

            fmt.Println(string(content))

        }


        return nil

    })

我不知道這是否是您要找的東西,但了解該go-git軟件包很有趣。


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

添加回答

舉報

0/150
提交
取消
微信客服

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

幫助反饋 APP下載

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

公眾號

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