20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
|
# File 'lib/git_pm/git_data.rb', line 20
def self.blame(head = "master", exclude = [])
lines_by_author = {}
wd = self.find_working_dir
return lines_by_author if not wd
Dir.chdir wd do
git = GitPm::Git.new
git.ls_tree({:r => true, :name_only => true}, head) do |stdout, stderr|
stdout.each { |filename|
parse = true
exclude.each { |expat|
len = expat.length
if filename[0, len] == expat
parse = false
break
end
}
next unless parse
lines = 0
committer = nil
filename = filename[0,filename.length-1]
add_to_current = false
modified_by = {}
git.blame({:incremental => true}, filename) { |stdout, stderr|
stdout.each { |line|
if line =~ /\w{40}\s(\d+)\s(\d+)\s(\d+)/
source_line = $1
result_line = $2
lines = $3.to_i
add_to_current = true
elsif line =~ /^committer\s(.+)/
committer = $1
modified_by[committer] = true
lines_by_author[committer] ||= {:lines => 0, :files => 0}
lines_by_author[committer][:lines] += lines
add_to_current = false
elsif line =~ /^committer-mail\s\<(.+)\>/
lines_by_author[committer][:email] = $1
elsif line =~ /^filename/
lines_by_author[committer][:lines] += lines if add_to_current
end
}
}
modified_by.each { |author, v|
lines_by_author[author][:files] += 1
}
}
end
end
lines_by_author
end
|