I'm working on a project and one of the requirements is the need to call git cherry
command to get some differences between on branch and the other - (note this is not git cherry-pick
).
I was planning to use ruby rugged
gem for this project but I cannot find anything in the documentation whether it supports the git cherry
API or not.
Rugged is a ruby wrapper around libgit2
but I could not find anything in its documentation either.
libgit2 (and by extension, the things built on top of it, like Rugged) is pretty low level. There probably won't ever be a git cherry
-like functionality built in, but you could normally write one yourself.
Unfortunately, at the moment, libgit2 doesn't provide a patch ID implementation, which is the technique that Git uses to determine identical patches. If it did, or if you wanted to write your own, you could perform the revision walk yourself over the two ranges using Rugged::Walker
, comparing which patch IDs from the second range were also present in the first range. That's essentially what Git does under the hood.
The following is an example of what you might do, replacing the patch_id function with a real one:
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