2016-11-05 61 views
2

我試圖獲得在日期之後在本地副本的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個fi修改/刪除/替換。而git log -p --reverse --after="2016-10-22"顯示只有2個文件被修改。

如何獲得與git命令相同的結果?即我如何找到由此提交修改的真實文件?

回答

1

因爲我沒有從這個崎嶇的團隊得到任何答案,所以我在libgit2-glib這裏做了一個紅寶石gobject-introspection加載程序,這裏是https://github.com/ruby-gnome2/ggit

現在我可以找到diff和對應於git的命令行界面日誌:

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 
0

當我克隆ruby-gnome2/ruby-gnome2,它告訴我有2400+的文件,所以你拿2463,這令我所有文件已被修改。

這與rugged#commit.diff的正常行爲不同,默認情況下,該行爲與第一個父提交相比有差異(返回by the Walker)。

檢查是否有一些設置,如git config core.autocrlf設置爲true(這可能會改變本地回購協議中的eol)。

+0

不幸的是,沒有區別,看這裏https://github.com/ruby-gnome2/ruby -gnome2/commits/master,這是我用於測試的回購。您可以很容易地看到「2016-10-22」日期之後沒有修改/刪除/替換的2463個文件。 – cedlemo

+0

@cedlemo:是的,'git log --name-status --oneline --after =「2016-10-22」'只顯示3個文件。這意味着你的腳本有問題。是因爲它在*日期之前計算提交*,而不是之後?畢竟,'git log --name-status --oneline --before =「2016-10-22」--all --branches | grep -e「^ M」| sort | uniq | wc'給出3362個文件。並且'除非c_time> = Date.new(2016,10,01).to_time'是可疑的...... – VonC

+0

'除非c_time> = Date.new(2016,10,01)'並不重要,因爲輸出我顯示的是循環上次提交的迭代,這意味着上次提交有2463個文件被修改,這是錯誤的。腳本可能有問題,但我不知道在哪裏。 – cedlemo