我希望克隆一个特定的存储库,获取所有标记并遍历它们。对于每个标记,我想签出根目录中的特定文件( package.json )。如果没有文件存在,它应该继续,否则它应该通过它,以便我可以检查它。
我从以下代码开始(我的第一个Go应用程序.)
package main
import (
"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)
}有人知道如何尝试通过给定的标记签出循环中的文件吗?
发布于 2022-08-31 23:21:51
如果只需要文件内容,则不需要“签出”任何内容;您可以直接从存储库中提取该内容。但是首先要注意的是:我既不是一个经验丰富的围棋程序员,也从来没有使用过go-git,所以可能有一种更好的方法来做到这一点。
从标记开始,您可以:
package.json
,提取相应的blob。现在你有你的内容了!
以上步骤可能如下所示:
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包的学习很有趣。
https://stackoverflow.com/questions/73561564
复制相似问题