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 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
| require 'open3' require 'date'
def get_commit_list(author_name) commit_list = []
git_log_command = "git log --author='#{author_name}' --pretty='format:%H|%ad|%an' --numstat" Open3.popen3(git_log_command) do |stdin, stdout, stderr, wait_thr| commit_info = {}
stdout.each_line do |line|
if line =~ /\|/ commit_id, date_str, author = line.chomp.split("|") date = Date.parse(date_str)
commit_info = { commit_id: commit_id, date: date, author: author, added_lines: 0, removed_lines: 0 } elsif line =~ /^(\d+)\s+(\d+)/ added_lines = $1.to_i removed_lines = $2.to_i commit_info[:added_lines] += added_lines commit_info[:removed_lines] += removed_lines elsif line.strip.empty? commit_list << commit_info end end
commit_list << commit_info unless commit_info.empty? end
commit_list end
def commits_histogram(commits, start_date) histogram = Hash.new { |hash, key| hash[key] = { commits: 0, added_lines: 0, removed_lines: 0 } }
commits.each do |commit| year = commit[:date].year
start_new_year = Date.new(year, start_date[0], start_date[1])
target_year = commit[:date] >= start_new_year ? year : year - 1
hist = histogram[target_year] hist[:commits] += 1 hist[:added_lines] += commit[:added_lines] hist[:removed_lines] += commit[:removed_lines] end
histogram.sort.reverse.to_h end
COLOR_GREEN = 32 COLOR_RED = 31
def colorize(text, color_code) "\e[#{color_code}m#{text}\e[0m" end
def format_added(num) text = format('+%5d', num) colorize(text, COLOR_GREEN) end
def format_removed(num) text = format('-%5d', num) colorize(text, COLOR_RED) end
def format_net(num) color_code = num >= 0 ? COLOR_GREEN : COLOR_RED text = format('%5d', num) colorize(text, color_code) end
def print_yearly_stats(author_name, start_date) commits = get_commit_list(author_name)
histogram = commits_histogram(commits, start_date)
puts "Yearly stats:" total_commits = 0 total_added_lines = 0 total_removed_lines = 0
histogram.each do |year, data| net_color = data[:added_lines] >= data[:removed_lines] ? COLOR_GREEN : COLOR_RED
commits_line = format('%4d: %3d commits; LOC: %s, %s, net: %s', year, data[:commits], format_added(data[:added_lines]), format_removed(data[:removed_lines]), format_net(data[:added_lines] - data[:removed_lines]) ) puts commits_line
total_commits += data[:commits] total_added_lines += data[:added_lines] total_removed_lines += data[:removed_lines] end
puts "====" sum_line = format("Sum: %4d commits; LOC: %s, %s, net: %s", total_commits, format_added(total_added_lines), format_removed(total_removed_lines), format_net(total_added_lines - total_removed_lines) ) puts sum_line end
start_date = [1, 1]
author_name = 'First \(Middle \)\?Last' print_yearly_stats(author_name, start_date)
|