class GitTimeExtractor

Extract Reasonable Developer Time Records from a GIT Repository’s Commit Log

This is inspired by a RAKE task publicly posted by Sharad at www.tatvartha.com/2010/01/generating-time-entry-from-git-log/. However, it has been adapted to run without Rails from the command line.

Portions © 2014 Rietta Inc. and licensed under the terms of the BSD license.

Constants

VERSION

Attributes

authors[RW]
options[RW]
summary[RW]

Public Class Methods

new( opts = { project: "Untitled", path_to_repo: "./", output_file: "-", initial_effort_mins: 30, merge_effort_mins: 30, session_duration_hrs: 3, max_commits: 1000 } ) click to toggle source
# File lib/git_time_extractor.rb, line 18
def initialize( opts = {
                        project: "Untitled",
                        path_to_repo: "./",
                        output_file: "-",
                        initial_effort_mins: 30,
                        merge_effort_mins: 30,
                        session_duration_hrs: 3,
                        max_commits: 1000
                      } )
  @options = opts
  @authors_hash = Hash.new
  @authors      = Array.new
end

Public Instance Methods

distribute_entries_to_authors(log_entries) click to toggle source

Scan through the commit log entries and split into each author’s accounting

# File lib/git_time_extractor.rb, line 54
def distribute_entries_to_authors(log_entries)
  # Go through the GIT commit records and construct the time
  log_entries.each_with_index do |commit, index|
    key = commit.author.email
     if @authors_hash[key].nil?
       @authors_hash[key] = Author.new(@options)
     end
     @authors_hash[key].add_commit(commit)
  end # log_entries.each_with_index

  if @authors_hash
    @authors_hash.each do |key, value|
      if value
        value.tabulate_days
        @authors << value
        #puts "DEBUG: Looking at #{key}, #{value}, with #{value.rows.count} commits"
      end
    end
  end

  #puts "DEBUG: #{@authors.count} authors"

  return @authors
end
load_git_log_entries(path_to_git_repo) click to toggle source
# File lib/git_time_extractor.rb, line 44
def load_git_log_entries(path_to_git_repo)
  # Open the GIT Repository for Reading
  logger = Logger.new(STDOUT)
  logger.level = Logger::WARN
  g = Git.open(path_to_git_repo, :log => logger)
  logs = g.log(@options[:max_commits])
  return logs.entries.reverse
end
path_to_git_repo() click to toggle source
# File lib/git_time_extractor.rb, line 32
def path_to_git_repo
  options[:path_to_repo]
end
path_to_output_file() click to toggle source
# File lib/git_time_extractor.rb, line 36
def path_to_output_file
  options[:output_file]
end
prepare_rows_for_author_summary_csv() click to toggle source
# File lib/git_time_extractor.rb, line 133
def prepare_rows_for_author_summary_csv
  rows = Array.new
  rows << author_summary_header_row_template()
  commits = 0
  hours = 0
  authors = Array.new
  @authors.each do |author|
    rows << [
      author.total_commits(),
      author.total_working_hours(),
      author.commits[0].author.name,
      author.commits[0].author.email,
    ]
  end
  return rows
end
prepare_rows_for_csv() click to toggle source
# File lib/git_time_extractor.rb, line 79
def prepare_rows_for_csv
  rows = Array.new
  rows << header_row_template()
  @authors.each do |author|
    author.rows.each do |author_row|
      rows << author_row
    end
  end
  return rows
end
prepare_rows_for_summary_csv() click to toggle source
# File lib/git_time_extractor.rb, line 105
def prepare_rows_for_summary_csv
  rows = Array.new
  rows << summary_header_row_template()
  commits = 0
  hours = 0
  authors = Array.new
  @authors.each do |author|
    commits += author.total_commits()
    hours += author.total_working_hours()
    authors << author.commits[0].author.name + " (" + author.commits[0].author.email + ")"
  end
  rows << [
    hours,
    commits,
    authors.join(";")
  ]
  return rows
end
process() click to toggle source
# File lib/git_time_extractor.rb, line 158
def process
  if options[:project_total]
    process_git_log_into_summary
  elsif options[:compact]
    process_git_log_into_author_summary
  else
    process_git_log_into_time
  end
end
process_git_log_into_author_summary() click to toggle source

create a summary per author

# File lib/git_time_extractor.rb, line 153
def process_git_log_into_author_summary
  distribute_entries_to_authors( load_git_log_entries( path_to_git_repo ) )
  return prepare_rows_for_author_summary_csv
end
process_git_log_into_summary() click to toggle source

create a summary of the computed times

# File lib/git_time_extractor.rb, line 127
def process_git_log_into_summary
  distribute_entries_to_authors( load_git_log_entries( path_to_git_repo ) )
  return prepare_rows_for_summary_csv
end
process_git_log_into_time() click to toggle source

Go through the GIT commit log, to compute the elapsed working time of each committing developer, based on a few assumptions:

(1) A series of commits within a 3 hour window are part of the same development session (2) A single commit (or the first commit of the session) is considered to represent 30 minutes of work time (3) The more frequent a developer commits to the repository while working, the more accurate the time report will be

# File lib/git_time_extractor.rb, line 99
def process_git_log_into_time
  distribute_entries_to_authors( load_git_log_entries( path_to_git_repo ) )
  return prepare_rows_for_csv
end
project_name() click to toggle source
# File lib/git_time_extractor.rb, line 40
def project_name
  options[:project]
end

Private Instance Methods

author_summary_header_row_template() click to toggle source
# File lib/git_time_extractor.rb, line 188
def author_summary_header_row_template
  [
    'Total Git Commits Count',
    'Total Hours',
    'Person',
    'Email',
    # 'From Date',
    # 'To Date',
  ]
end
header_row_template() click to toggle source
# File lib/git_time_extractor.rb, line 171
def header_row_template
  [
    'Date',
    'Git Commits Count',
    'Pivotal Stories Count',
    'Minutes',
    'Hours',
    'Person',
    'Email',
    'Project',
    'Notes',
    'Pivotal Stories',
    'Week Number',
    'Year'
  ]
end
summary_header_row_template() click to toggle source
# File lib/git_time_extractor.rb, line 199
def summary_header_row_template
  [
    # 'From Date',
    # 'To Date',
    'Total Git Commits Count',
    'Total Hours',
    'Collaborators',
  ]
end