2016-11-05 5 views
2

git repo의 로컬 복사본에서 날짜 이후 커밋을 얻은 다음 파일에 관련된 수정 사항을 추출하려고합니다. 나는 자식 명령이 비교하려는 경우견고한 커밋을 위해 적절한 diff/patch를 선택하는 방법

, 그것은 다음과 같습니다가 많은처럼 보이는 것을

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 

문제는 다음과 같습니다

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

내가 사용하는 스크립트입니다 여기서 파일의 수정은이 스크립트 출력의 끝입니다.

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

즉, 2463 개의 fi 수정 된/삭제 된/바꾸기. git log -p --reverse --after="2016-10-22"은 단 2 개의 파일 만 수정되었음을 보여줍니다.

git 명령과 같은 결과를 얻으려면 어떻게해야합니까? ie이 커밋에 의해 수정 된 실제 파일을 어떻게 찾을 수 있습니까?

답변

1

견고한 팀에서 답을 얻지 못했기 때문에 나는 libgit2-glib 여기에 https://github.com/ruby-gnome2/ggit에 대한 루비 gobject-introspectloader를 수행했습니다. 여기 https://github.com/ruby-gnome2/ruby 보면,

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를 복제 할 때, 당신이 2463을 얻을 수 있도록, 즉 모든 파일이 수정 된 인상을 받았는데, 그래서 2400 + 파일이 나에게 말한다.

이것은 첫 번째 부모 커밋에 대한 현재 커밋 (by the Walker 반환)과 기본적으로 다른 rugged#commit.diff의 일반적인 동작과 다릅니다.

git config core.autocrlf과 같은 설정이 true (로컬 repo에서 변경 될 수 있음)으로 설정되어 있는지 확인하세요.

+0

불행하게도, 차이가 없습니다 :

지금은 DIFF와 자식 명령 줄 인터페이스에 해당하는 로그를 찾을 수 있습니다 -gnome2/커밋/마스터, 이것은 내 테스트에 사용하는 repo입니다. "2016-10-22"날짜 이후에 수정/삭제/교체 된 2463 파일이 없음을 쉽게 볼 수 있습니다. – cedlemo

+0

@cedlemo : 예,'git log --name-status --online --after = "2016-10-22"는 3 개의 파일만을 보여줍니다. 즉, 스크립트에 문제가 있음을 의미합니다. 해당 날짜 이전의 커밋 *을 계산하기 때문입니까? 결국,'git log --name - status --online --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