Tatva-Artha

meaning of "it"

Archive for January, 2010

Generating Time Entry from git log

without comments

Being able to track time automatically based on version control log is a recurring theme. Git makes it possible to generate ever more accurate since you can continue to perform tiny checkins to you local repository and then push it to main when you get a chance. Several folks have attempted to generate an approximation of time-log based on git commit hooks.

I make an attempt that is less intrusive and uses just the git logs. Here is the rake task that does it:

task :timelog => [:environment] do
  require 'logger'
  require '/home/sjain/projects/gems/ruby-git/lib/git'
  require 'fastercsv'
  logger = Logger.new(STDOUT)
  logger.level = Logger::WARN
  g = Git.open(Rails.root.to_s, :log => logger)
  logs = g.log(1000)
  log_entries = logs.entries.reverse
  worklog = {}
  log_entries.each_with_index do |commit, index|
    author_date = commit.author_date.to_date
    daylog = worklog[author_date] || OpenStruct.new(:date => author_date, :duration => 0)
    daylog.message = "#{daylog.message} --- #{commit.message}"
    daylog.duration = daylog.duration + calc_duration(log_entries, index)
    worklog[author_date] = daylog
  end
  FasterCSV.open("time_report.csv", "w") do |csv|
    worklog.keys.sort.each do |date|
      duration_in_hours = (worklog[date].duration/1.hour).round(2)
      puts "#{date.to_s(:db)} #{duration_in_hours}"
      csv << [date.to_s(:db), duration_in_hours, worklog[date].message]
    end
  end
end
 
def calc_duration(log_entries, index)
  commit = log_entries[index]
  if index > 1
    previous_commit = log_entries[index-1]
    duration = commit.author_date - previous_commit.author_date
    # ASSUMPTION: if the gap between 2 commits is more than 3 hours, reduce it to 1-hour
    duration = 0.5.hour if duration > 3.hour
    return duration
  else
    # ASSUMPTION: first commit took 1/2 hour
    0.5.hour
  end
end

There are some sensible assumptions being made to account for that fact that you stopped working at night and continue next day. This script currently looks at all logs by everybody. On a typical project with several developers, we may want to select logs for particular authors. This script needs further enhancement in that sense.

What is nice about this script it doesn’t depend on any git commit hooks and can be run on any git repository, after the fact, to get an approximate hours count.

The more tiny commits you make, the more accurate the result is.
Enjoy!

Note: I used ruby-git for git api.

Written by Sharad

January 23rd, 2010 at 8:11 pm

Posted in All