committer_count.rb 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. #!/usr/bin/env ruby
  2. #
  3. # The committer_count.rb is a way to tell who's been active over the last
  4. # given period. It's of course, quite coarse -- someone with 10 commits in a day
  5. # may or may not be more productive than someone with 3, but over long enough
  6. # periods, it's an okay metric to measure involvement with the project, since
  7. # large and small commits will tend to average out.
  8. #
  9. # Note that this includes merge commits by default (which usually means at least
  10. # code review happened, so it's still a measure of work). You can get different
  11. # stats by ignoring merge commits, once option parsing is implemented.
  12. #
  13. # Usage: ./committer_count.rb 2011-01-01 | head -10 # Since a particular date
  14. # ./committer_count.rb 1y | head -10 # Last year
  15. # ./committer_count.rb 6m | head -10 # Last six months
  16. # ./committer_count.rb 12w | head -10 # Last twelve weeks
  17. # ./committer_count.rb 100d | head -10 # Last hundred days
  18. #
  19. #
  20. # History with colors and e-mail addresses (respecting .mailmap):
  21. # git log --pretty=format:"%C(white)%ad %C(yellow)%h %Cblue'%aN' <%aE> %Cgreen%f%Creset" --date=short
  22. #
  23. require 'time'
  24. class GitLogLine < Struct.new(:date, :hash, :author, :message)
  25. end
  26. @history = `git log --pretty=format:"%ad %h '%aN' %f" --date=short --date-order`
  27. @recent_history = []
  28. @commits_by_author = {}
  29. def parse_date(date)
  30. case date
  31. when /([0-9]+)y(ear)?s?/
  32. seconds = $1.to_i* (60*60*24*365.25)
  33. calc_date = (Time.now - seconds).strftime("%Y-%m-%d")
  34. when /([0-9]+)m(onth)?s?/
  35. seconds = $1.to_i* (60*60*24*(365.25 / 12))
  36. calc_date = (Time.now - seconds).strftime("%Y-%m-%d")
  37. when /([0-9]+)w(eek)?s?/
  38. seconds = $1.to_i* (60*60*24*7)
  39. calc_date = (Time.now - seconds).strftime("%Y-%m-%d")
  40. when /([0-9]+)d(ay)?s?/
  41. seconds = $1.to_i* (60*60*24)
  42. calc_date = (Time.now - seconds).strftime("%Y-%m-%d")
  43. else
  44. calc_date = Time.parse(date).strftime("%Y-%m-%d")
  45. end
  46. end
  47. date = ARGV[0] || "2005-03-22" # A day before the first SVN commit.
  48. calc_date = parse_date(date)
  49. @history.each_line do |line|
  50. parsed_line = line.match(/^([^\s+]+)\s(.{7,})\s'(.*)'\s(.*)[\r\n]*$/)
  51. next unless parsed_line
  52. break if calc_date == parsed_line[1]
  53. @recent_history << GitLogLine.new(*parsed_line[1,4])
  54. end
  55. @recent_history.each do |logline|
  56. @commits_by_author[logline.author] ||= []
  57. @commits_by_author[logline.author] << logline.message
  58. end
  59. puts "Commits since #{calc_date}"
  60. puts "-" * 50
  61. @commits_by_author.sort_by {|k,v| v.size}.reverse.each do |k,v|
  62. puts "%-25s %3d" % [k,v.size]
  63. end