-
-
Notifications
You must be signed in to change notification settings - Fork 7
/
git-stats
executable file
·89 lines (75 loc) · 2.76 KB
/
git-stats
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
#!/usr/bin/env ruby
# Originally borrowed from Jim Garvin, but heavily modified over the years
# http://github.com/coderifous/dotfiles/blob/master/bin/git-stats.rb
require "time"
require "date"
require "shellwords"
require "active_support"
require "active_support/core_ext/date"
require "active_support/core_ext/object"
require "active_support/core_ext/time"
require "active_support/core_ext/numeric"
def debug(msg)
puts msg if ENV["DEBUG"]
end
if ARGV[0] == "--after"
after = Time.parse(ARGV[1])
elsif ARGV[0].present?
weeks_shift = 0
day = nil
if ARGV[0] == "last-week"
weeks_shift = -1
elsif ARGV[0] == "this-week"
weeks_shift = 0
elsif ARGV[0].to_i <= 0
weeks_shift = ARGV[0].to_i
else
day = Time.parse(ARGV[0])
end
day ||= Time.parse(Date.today.to_s)
day += weeks_shift.weeks
after = day.beginning_of_week
before = day.end_of_week
end
after_option = ["--after", after.iso8601].shelljoin if after
before_option = ["--before", before.iso8601].shelljoin if before
authors = {}
command = "git shortlog #{after_option} #{before_option} -sne --no-merges"
debug(command)
open("| #{command}").each do |line|
line =~ /\d+\s+(.+)\s+<(.+)>/
name = Regexp.last_match(1)
email = Regexp.last_match(2)
authors[email] = name
# authors[email] = "#{name} <#{email}>"
end
author_width = 1 + authors.values.map(&:length).max.to_i
format = "%#{author_width}s %8s %8s %12s %12s %12s\n"
line_width = 58 + author_width
puts " Weekly Report: #{after.to_date} to #{before.to_date}" if after && before
puts " Report: #{after.to_date} to today" if after && !before
puts "-" * line_width
printf(format, *%w(author commits touches inserts deletes net))
puts "-" * line_width
total_commits = total_touches = total_inserts = total_deletes = 0
authors.each do |email, name|
author_commits = author_touches = author_inserts = author_deletes = 0
command = "git log #{after_option} #{before_option} --shortstat --no-merges --author=#{email.shellescape} | grep -E 'files? changed'"
debug(command)
open("| #{command}").each do |line|
touches = line.match(/(\d+) files? changed/)
inserts = line.match(/(\d+) insertion/)
deletes = line.match(/(\d+) deletion/)
author_commits += 1 if touches
author_touches += touches[1].to_i if touches
author_inserts += inserts[1].to_i if inserts
author_deletes += deletes[1].to_i if deletes
end
printf(format, name, author_commits, author_touches, author_inserts, -1 * author_deletes, author_inserts - author_deletes)
total_commits += author_commits
total_touches += author_touches
total_inserts += author_inserts
total_deletes += author_deletes
end
puts "-" * line_width
printf(format, authors.size, total_commits, total_touches, total_inserts, -1 * total_deletes, total_inserts - total_deletes)