2

我正在做一个项目,其中一个要求是需要调用git cherry命令来获得分支和另一个之间的一些差异 - (注意这不是git cherry-pick)。

我计划在这个项目中使用gem,但无论它是否支持API ruby rugged,我在文档中都找不到任何内容。git cherry

Rugged 是一个 ruby​​ 包装器,libgit2但我在它的文档中也找不到任何东西。

4

1 回答 1

3

libgit2(以及在它之上构建的东西,比如 Rugged)是相当低级的。可能永远不会git cherry内置类似的功能,但您通常可以自己编写一个。

不幸的是,目前,libgit2 没有提供补丁 ID 实现,这是 Git 用来确定相同补丁的技术。如果是这样,或者如果您想编写自己的,您可以使用 自己在两个范围内执行修订Rugged::Walker,比较第二个范围中的哪些补丁 ID 也存在于第一个范围中。这本质上就是 Git 在幕后所做的。

以下是您可以执行的操作示例,将 patch_id 函数替换为真实函数:

require 'rugged'
require 'digest'

def patch_id(patch)
  # This is not a real implementation; replace it with a real one.
  Digest::SHA1.hexdigest(patch.each_line.reject { |l| l =~ /^(diff|index|---|\+\+\+|@@)/ }.join)
end

def walk_revisions(repo, from, to)
  revisions = {}
  walker = Rugged::Walker.new(repo)
  walker.sorting(Rugged::SORT_TOPO | Rugged::SORT_REVERSE)
  walker.push(to)
  walker.hide(from)
  walker.each do |c|
    diff = c.parents[0].diff(c)
    revisions[patch_id(diff.patch)] = c.oid
  end
  revisions
end

repo = Rugged::Repository.new(ARGV[0])
a, b, c = ARGV[1..3].map { |r| repo.rev_parse(r) }
first = walk_revisions(repo, b, a)
second = walk_revisions(repo, c, b)
second.each do |id, rev|
  char = first.include?(id) ? '-' : '+'
  puts "#{char} #{rev}"
end
于 2018-03-25T22:03:58.530 回答