ruby - 如何为 rugged 的​​提交选择合适的差异/补丁

标签 ruby git rugged

我尝试在 git 存储库的本地副本中获取某个日期之后完成的提交,然后提取文件的相关修改。

如果我想将其与 git 命令进行比较,它将是:

git log -p --reverse --after="2016-10-01"

这是我使用的脚本:

require "rugged"
require "date"

git_dir = "../ruby-gnome2/"

repo = Rugged::Repository.new(git_dir)
walker = Rugged::Walker.new(repo)
walker.sorting(Rugged::SORT_DATE| Rugged::SORT_REVERSE)
walker.push(repo.head.target)

walker.each do |commit|
  c_time = Time.at(commit.time)
  next unless c_time >= Date.new(2016,10,01).to_time

    puts c_time
    puts commit.diff.size
    puts commit.diff.stat.inspect
end

问题是看起来很多文件都被修改了这里是这个脚本输出的结尾:

2016-10-22 17:33:37 +0200
2463
[2463, 0, 271332]

这意味着有 2463 个文件被修改/删除/替换。 git log -p --reverse --after="2016-10-22" 显示只有 2 个文件被修改。

如何获得与 git 命令相同的结果?即我怎样才能找到被这次提交修改的真实文件?

最佳答案

由于我没有从 rugged 团队得到任何答复,我在这里为 libgit2-glib 做了一个 ruby​​ gobject-introspection 加载器 https://github.com/ruby-gnome2/ggit .

现在可以找到git命令行界面对应的diff和日志了:

require "ggit"

PATH = File.expand_path(File.dirname(__FILE__))

repo_path = "#{PATH}/ruby-gnome2/.git"

file = Gio::File.path(repo_path)

begin
  repo = Ggit::Repository.open(file)
  revwalker = Ggit::RevisionWalker.new(repo)
  revwalker.sort_mode = [:time, :topological, :reverse]
  head = repo.head
  revwalker.push(head.target)
rescue => error
  STDERR.puts error.message
  exit 1
end

def signature_to_string(signature)
  name = signature.name
  email = signature.email
  time = signature.time.format("%c")

  "#{name} <#{email}> #{time}"
end

while oid = revwalker.next do
  commit = repo.lookup(oid, Ggit::Commit.gtype)

  author = signature_to_string(commit.author)
  date = commit.committer.time
  next unless (date.year >= 2016 && date.month >= 11 && date.day_of_month > 5)
  committer = signature_to_string(commit.committer)

  subject = commit.subject
  message = commit.message

  puts "SHA: #{oid}"
  puts "Author:  #{author}"
  puts "Committer: #{committer}"
  puts "Subject: #{subject}"
  puts "Message: #{message}"
  puts "----------------------------------------"

  commit_parents = commit.parents
  if commit_parents.size > 0
    parent_commit = commit_parents.get(0)
    commit_tree = commit.tree
    parent_tree = parent_commit.tree

    diff = Ggit::Diff.new(repo, :old_tree => parent_tree,
                          :new_tree => commit_tree, :options => nil)

    diff.print( Ggit::DiffFormatType::PATCH ).each do |_delta, _hunk, line|
      puts "\t | #{line.text}"
      0
    end

  end

end

关于ruby - 如何为 rugged 的​​提交选择合适的差异/补丁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40437557/

相关文章:

ruby - Ruby 中的祖先是什么,它们有什么用?

mysql - 如何防止多个worker竞相处理同一个任务?

git - 如何解决终端(git)中的 'Fatal: Invalid date format'

git - 如何最小化 git merge 冲突?

git - GitHub 和 GitLab 是否支持 git clone 的 --filter 参数?

Ruby BCrypt 加盐/散列似乎……错了?

ruby - 如何使用 ruby​​-git 递归克隆远程存储库?

git - merge 到主分支时,在第一个分支被压扁后 merge 分支的分支

ruby - 来自原点的坚固合并提交不会更新工作树

ruby - 与 Rugged 执行 "fast-forward"合并