使用ruby rugged gem访问git log数据?

时间:2014-01-23 07:36:08

标签: ruby git rugged

对于git repo中的给定文件,我想查找修改文件的最后一次提交的SHA以及时间戳。

在命令行,使用git log显示特定文件路径的数据,例如:

git log -n 1 path/to/file

对ruby使用“git”gem我也可以这样做:

require 'git'
g = Git.open("/path/to/repo")
modified = g.log(1).object(relative/path/to/file).first.date
sha = g.log(1).object(relative/path/to/file).first.sha

这很棒,但在循环很多路径时对我来说运行得太慢了。由于Rugged使用C库,我希望它会更快,但无法看到如何在粗糙的语法中构造正确的查询。有什么建议?

1 个答案:

答案 0 :(得分:9)

这应该有效:

repo = Rugged::Repository.new("/path/to/repo")
walker = Rugged::Walker.new(repo)
walker.sorting(Rugged::SORT_DATE)
walker.push(repo.head.target)
commit = walker.find do |commit|
  commit.parents.size == 1 && commit.diff(paths: ["relative/path/to/file"]).size > 0
end
sha = commit.oid

采取并改编自https://github.com/libgit2/pygit2/issues/200#issuecomment-15899713

顺便说一下:仅仅因为用C语写的粗糙并不意味着昂贵的操作突然变得便宜和快速。显然,你节省了很多字符串解析和类似的东西,但这并不总是瓶颈。

由于您对此处的实际文本差异不感兴趣,因此libgit2 GIT_DIFF_FORCE_BINARY可能也有助于提高此查找的性能 - 遗憾的是,这在Rugged中尚未提供(但将会是,很快)。

使用Rugged repo本身进行测试,它可以正常工作:

repo = Rugged::Repository.new(".")
walker = Rugged::Walker.new(repo)
walker.sorting(Rugged::SORT_DATE)
walker.push(repo.head.target)
commit = walker.find do |commit|
  commit.parents.size == 1 && commit.diff(paths: ["Gemfile"]).size > 0
end
sha = commit.oid # => "8f5c763377f5bf0fb88d196b7c45a7d715264ad4"

walker = Rugged::Walker.new(repo)
walker.sorting(Rugged::SORT_DATE)
walker.push(repo.head.target)
commit = walker.find do |commit|
  commit.parents.size == 1 && commit.diff(paths: [".travis.yml"]).size > 0
end
sha = commit.oid # => "4e18e05944daa2ba8d63a2c6b149900e3b93a88f"