Есть ли в libgit2 "вишня"?

Я работаю над проектом, и одним из требований является необходимость вызова команды git cherry, чтобы получить некоторые различия между веткой и другой (обратите внимание, что это не git cherry-pick).

Я планировал использовать ruby rugged gem для этого проекта, но не могу ничего найти в документации, поддерживает ли он git cherry API или нет.

Rugged — это ruby-обертка вокруг libgit2, но в его документации я тоже ничего не нашел.


person RobisonSantos    schedule 25.03.2018    source источник
comment
Я знаю, что вы хотели бы получить ответ на этот вопрос, но это не по теме, поскольку вы запрашиваете библиотеку или внешний ресурс.   -  person evolutionxbox    schedule 26.03.2018


Ответы (1)


libgit2 (и, соответственно, вещи, построенные поверх него, например, Rugged) довольно низкого уровня. Вероятно, никогда не будет встроенной git cherry функциональности, но обычно вы можете написать ее самостоятельно.

К сожалению, на данный момент libgit2 не предоставляет реализацию идентификатора патча, который является методом, который Git использует для определения идентичных патчей. Если бы это было так, или если бы вы хотели написать свой собственный, вы могли бы самостоятельно выполнить обход ревизий по двум диапазонам, используя Rugged::Walker, сравнивая, какие идентификаторы патчей из второго диапазона также присутствовали в первом диапазоне. По сути, это то, что 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
person bk2204    schedule 25.03.2018
comment
Спасибо... это то, что я искал. Не код, а объяснение того, почему libgit2 (и защищенный от расширения) не предлагает готовую команду git cherry. - person RobisonSantos; 27.03.2018