2016-11-05 6 views
2

Я пытаюсь получить коммиты, которые были сделаны после даты в локальной копии git repo, а затем извлечь связанные изменения в файлах.Как выбрать соответствующий diff/patch для фиксации с прочным

Если я хотел бы сравнить это с командой мерзавца, было бы:

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 les modified/deleted/replace. В то время как git log -p --reverse --after="2016-10-22" показывают, что изменены только 2 файла.

Как получить те же результаты, что и с помощью команды git? т.е. как я могу найти реальные файлы, которые были изменены этим фиксатором?

ответ

1

Поскольку у меня не было ответа от надежной команды, я сделал рубиновый gobject-introspection загрузчик для libgit2-glib здесь https://github.com/ruby-gnome2/ggit.

Теперь я могу найти различия и журналы, что соответствует интерфейсу командной строки мерзавца:

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, это репо, которое я использую для своих тестов. Вы можете легко увидеть, что не было файлов 2463, измененных/удаленных/замененных после даты «2016-10-22». – cedlemo

+0

@cedlemo: yes, '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 файлов , И 'if c_time> = Date.new (2016,10,01) .to_time' является подозрительным ... – VonC

+0

' if c_time> = Date.new (2016, 10, 01) 'не имеет большого значения, потому что вывод Я показал последнюю итерацию цикла над коммитами, что означает, что в последнем коммите было изменено 2463 файлов, что является ложным. Сценарий, возможно, проблема, но я не вижу, где. – cedlemo

Смежные вопросы