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