Created
November 14, 2014 15:00
-
-
Save janzikan/1b9be6c7c7f5283b557f to your computer and use it in GitHub Desktop.
Ruby: Git statistics
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env ruby | |
require 'optparse' | |
require 'optparse/date' | |
options = {} | |
parser = OptionParser.new do |opts| | |
opts.banner = 'Usage: git_stats.rb [options]' | |
opts.on('-a', '--after [DATE]', Date, 'Get stats since given date') do |val| | |
options[:after] = val | |
end | |
opts.on('-b', '--before [DATE]', Date, 'Get stats until given date') do |val| | |
options[:before] = val | |
end | |
end | |
begin | |
parser.parse! | |
rescue OptionParser::InvalidArgument | |
puts 'Error: Invalid date' | |
exit | |
end | |
def date_param(date, param) | |
date ? "--#{param} #{date}" : '' | |
end | |
def date_params(after, before) | |
[date_param(after, :after), date_param(before, :before)].join(' ') | |
end | |
def git_authors(after, before) | |
`git log --branches --remotes #{date_params(after, before)} --format='%aN' | sort -u` | |
end | |
# Git information containing commit hash and commit stats on separate lines | |
# Example: | |
# cd10440 | |
# 3 files changed, 17 insertions(+), 1 deletion(-) | |
def git_log_stats(author, after, before) | |
command = "git log --shortstat --pretty=format:\"%h\" --branches --remotes" | |
`#{command} --author=\"#{author}\" #{date_params(after, before)}` | |
end | |
def str_with_stats?(str) | |
str.split(' ').count > 1 | |
end | |
def parse_count(str, substr) | |
str.scan(/(\d+) #{substr}/).flatten.first.to_i | |
end | |
def count_stats(data) | |
commits = files_changed = insertions = deletions = 0 | |
data.split("\n").each do |row| | |
row.chomp! | |
next if row.empty? | |
if str_with_stats?(row) | |
files_changed += parse_count(row, 'file') | |
insertions += parse_count(row, 'insert') | |
deletions += parse_count(row, 'del') | |
else | |
commits += 1 | |
end | |
end | |
{ commits: commits, | |
files_changed: files_changed, | |
insertions: insertions, | |
deletions: deletions } | |
end | |
authors = git_authors(options[:after], options[:before]) | |
authors.split("\n").each do |author| | |
raw_data = git_log_stats(author, options[:after], options[:before]) | |
stats = count_stats(raw_data) | |
puts author | |
puts "#{stats[:commits]} commits" | |
puts "#{stats[:files_changed]} files changed" | |
puts "#{stats[:insertions]} insertions(+)" | |
puts "#{stats[:deletions]} deletions(-)" | |
puts | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment