0


Go 原生的 git 实现库:go-git

go-git


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 使用

2.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("本地仓库路径")

2.3)获取 last commit hash:

rHead,_:= r.Head()// 将获得的 
rHeadStr := rHead.String()
rHeadIdx := strings.Index(rHeadStr," ")
lastCommitHash = rHeadStr[:rHeadIdx]

r.Head() 获取的是一个结构体存有的数据,数据格式可以阅读源码获得:

// Reference is a representation of git referencetype Reference struct{
    t      ReferenceType
    n      ReferenceName
    h      Hash
    target ReferenceName
}// Hash SHA1 hashed contenttype Hash [20]bytefunc(h Hash)String()string{return hex.EncodeToString(h[:])}

所以可以使用 String() 将获得的信息转为字符串,结尾有空格需要去掉。

2.4)对 commit 历史信息进行遍历

cIter,_:= r.Log(&git.LogOptions{From: ref.Hash()})
err = cIter.ForEach(func(c *object.Commit)error{returnnil})

LogOptions 的填写也可以通过阅读源码获取:

type LogOptions struct{// When the From option is set the log will only contain commits// reachable from it. If this option is not set, HEAD will be used as// the default From.
    From plumbing.Hash
    // The default traversal algorithm is Depth-first search// set Order=LogOrderCommitterTime for ordering by committer time (more compatible with `git log`)// set Order=LogOrderBSF for Breadth-first search
    Order LogOrder
    // Show only those commits in which the specified file was inserted/updated.// It is equivalent to running `git log -- <file-name>`.// this field is kept for compatility, it can be replaced with PathFilter
    FileName *string// Filter commits based on the path of files that are updated// takes file path as argument and should return true if the file is desired// It can be used to implement `git log -- <path>`// either <path> is a file path, or directory path, or a regexp of file/directory path
    PathFilter func(string)bool// Pretend as if all the refs in refs/, along with HEAD, are listed on the command line as <commit>.// It is equivalent to running `git log --all`.// If set on true, the From option will be ignored.
    All bool// Show commits more recent than a specific date.// It is equivalent to running `git log --since <date>` or `git log --after <date>`.
    Since *time.Time
    // Show commits older than a specific date.// It is equivalent to running `git log --until <date>` or `git log --before <date>`.
    Until *time.Time
}

可以通过: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)errorClose()}
  • 怎么根据只有一个 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 语言实现 git 命令产生了挺大的优化,更多使用方法可以阅读官方仓库进行学习:go-git

标签: git golang github

本文转载自: https://blog.csdn.net/m0_51573433/article/details/126449687
版权归原作者 CSPsy 所有, 如有侵权,请联系我们删除。

“Go 原生的 git 实现库:go-git”的评论:

还没有评论