1. go-git 介绍
一个用 Go 语言编写的 git 实现库:它的官方仓库地址:go-git
为什么我们需要它? 举个例子:
如果我们需要获取 git log 的信息,需要通过 Go 调用 cmd 命令来获取:获取 git 的 last commit hash 的话需要耗费的时间大概在 50ms 左右(不同运行环境可能不一样)
它的慢原因是什么呢 ? Go 调用 cmd 命令本身存在着性能原因 其次,如果想要获取其它仓库的 git log 信息,还存在着跨文件调用的消耗
所以这里 go-git 的作用就体现出来了!由于它是 go 编写的 git 实现库,所以对 cmd 命令调用的消耗就可以避免了。测试之后,使用时间在 500μs 左右,巨大的提升!
2. go-git 使用
1)go-git 的安装:
go get -u github.com/go-git/go-git/v5
2.2)拉取仓库:
通过 github 地址
r, err := git.Clone(memory.NewStorage(), nil, &git.CloneOptions{
URL: "仓库地址",
})
通过本地仓库
r, err := git.PlainOpen("本地仓库路径")
3)获取 last commit hash:
rHead, _ := r.Head()
// 将获得的
rHeadStr := rHead.String()
rHeadIdx := strings.Index(rHeadStr, " ")
lastCommitHash = rHeadStr[:rHeadIdx]
所以可以使用 String() 将获得的信息转为字符串,结尾有空格需要去掉。
4)对 commit 历史信息进行遍历
cIter, _ := r.Log(&git.LogOptions{From: ref.Hash()})
err = cIter.ForEach(func(c *object.Commit) error {
return nil
})
可以通过:Order 指定遍历的方式,Since 和 Until 指定遍历时间范围。
cIter 是一个 object.Commiter 结构体,拥有以下方法,可以根据需要进行使用。
// CommitIter is a generic closable interface for iterating over commits.
type CommitIter interface {
Next() (*Commit, error)
ForEach(func(*Commit) error) error
Close()
}
怎么根据只有一个 Hash 值获取 commit 呢 ?
thisHash := plumbing.NewHash(string("Hash 值"))
thisCommit, _ := object.GetCommit(r.Storer, thisHash)
根据 commit 结构体又可以获得别的信息:
type Commit struct {
// Hash of the commit object.
Hash plumbing.Hash
// Author is the original author of the commit.
Author Signature
// Committer is the one performing the commit, might be different from
// Author.
Committer Signature
// PGPSignature is the PGP signature of the commit.
PGPSignature string
// Message is the commit message, contains arbitrary text.
Message string
// TreeHash is the hash of the root tree of the commit.
TreeHash plumbing.Hash
// ParentHashes are the hashes of the parent commits of the commit.
ParentHashes []plumbing.Hash
s storer.EncodedObjectStorer
}
type Signature struct {
// Name represents a person name. It is an arbitrary string.
Name string
// Email is an email, but it cannot be assumed to be well-formed.
Email string
// When is the timestamp of the signature.
When time.Time
}
例如:获取 commit 的时间
thisCommit.Committer.When.String()
在Go项目中,使用Git可以更好地管理项目的依赖关系。当使用Go模块(go mod)时,Git仓库可以作为依赖的源。例如,很多开源的Go库都托管在GitHub(基于Git的代码托管平台)上。开发人员可以通过在go. mod和go. sum文件中指定依赖的Git仓库地址和版本标签,精确地控制项目所依赖的外部代码。这有助于确保项目在不同环境下构建的一致性,避免因为依赖版本的混乱而导致的编译失败或运行时错误。