Skip to content

Instantly share code, notes, and snippets.

@janzikan
Created November 14, 2014 15:00
Show Gist options
  • Save janzikan/1b9be6c7c7f5283b557f to your computer and use it in GitHub Desktop.
Save janzikan/1b9be6c7c7f5283b557f to your computer and use it in GitHub Desktop.
Ruby: Git statistics
#!/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