Open Ajedi32 opened 11 years ago
Cool. You may be in luck. I spent the weekend working on something along these lines because I needed the same thing.
Also see #96
I've used something like this in capistrano to generate a formatted list of commits that match a certain pattern. You can use this or a variant of this to run metric_fu against certain select commits, with the only changes needed in the code, I think, being where it calls Time.now
, which we'd replace with run_date
or some such
def current_time
Time.now.strftime('%Y-%m-%d %H:%M')
end
# see http://stackoverflow.com/questions/1404796/how-to-get-the-latest-tag-name-in-current-branch-in-git
# see https://www.kernel.org/pub/software/scm/git/docs/git-for-each-ref.html
# see https://www.kernel.org/pub/software/scm/git/docs/git-describe.html
# see https://www.kernel.org/pub/software/scm/git/docs/git-log.html
def change_log
last_deploy_tag = `git for-each-ref #{pattern} --sort=-taggerdate --format='%(objectname:short)' --count=1`.strip
`git log --pretty='%d %s <%an>' --abbrev-commit --graph --decorate #{last_deploy_tag}..HEAD`.strip
end
# matches either tags starting with the stage name
# or containing 'ruby' e.g.
# refs/tags/cruby* or ref/tags/*ruby*
def pattern
"refs/tags/#{defined?(stage) ? stage : '*ruby'}*"
end
def current_hash
`git describe`.strip
end
e.g. on metric_fu
git log --max-count=1 --after=2013-07-24 --before=2013-07-25 --date=iso --format="%H, %ai"
=> 8506d56ffe277b5cbda291b72a42330d7c719040, 2013-07-25 15:48:27 +0200
so or in a ruby script
require 'date'
today=Date.today.strftime('%Y%m%d')
from_date=Date.parse('2013-06-29')
until_date=Date.parse('2013-07-29')
(from_date..until_date).each{|date|
git_log_cmd = "git log --max-count=1 --before=#{date} --after=#{date - 1} --format='%H'"
execute_cmd = "metric_fu && mv tmp/metric_fu/_data/#{today}.yml tmp/metric_fu/_data/#{date.strftime('%Y%m%d')}.yml"
puts "git_log_cmd: #{git_log_cmd}"
hash = `#{git_log_cmd}`.to_s.strip
unless hash == ''
puts "#{date},#{hash}"
puts "execute_cmd: #{execute_cmd}"
`git reset --hard HEAD && git checkout #{hash} && #{execute_cmd} && git checkout -`
end
}; nil
#
# attempt in bash
# ruby -rdate -e "today=Date.today.strftime('%Y%m%d');from_date=Date.parse('2013-06-29');until_date=Date.parse('2013-07-29'); (from_date..until_date).each{|date| `git log --max-count=1 --before=#{date} --after=#{date - 1} --format='%H' | xargs git checkout && metric_fu && mv tmp/metric_fu/_data/#{today}.yml tmp/metric_fu/_data/#{date.strftime('%Y%m%d')}.yml && git checkout -}; nil"
Yeah, I used git rev-list -n 1 --before=#{date} master
where date is end of day on a given day - which gives you the last commit for that day.
Also, remember, you can use a formatter now to save with the appropriate filename:
execute_cmd = "metric_fu --format yaml --out _data/#{date.strftime('%Y%m%d')}.yml"
Totally forgot about that, sweet
# require 'date'
#
# today=Date.today.strftime('%Y%m%d')
# from_date=Date.parse('2013-06-29')
# until_date=Date.parse('2013-07-29')
# (from_date..until_date).each{|date|
# git_log_cmd = "git log --max-count=1 --before=#{date} --after=#{date - 1} --format='%H'"
# puts "git_log_cmd: #{git_log_cmd}"
# hash = `#{git_log_cmd}`.to_s.strip
# process_commit(hash, date.strftime('%Y%m%d'))
# }; nil
def pattern(tag_pattern=nil)
["refs/tags",tag_pattern].compact.join('/')
end
TagRange = Struct.new(:output) do
def tag_name
output.split(',')[1]
end
def date
output.split(',')[0].gsub(/[^\d]/,'')
end
end
# @return
def tag_range(count,tag_pattern=nil)
hash_format = '%(objectname:short)'
ymd_format = '%(taggerdate:short)'
tag_name_format = '%(refname:short)'
format = "#{ymd_format},#{tag_name_format}"
` git for-each-ref #{pattern(tag_pattern)} --sort=-taggerdate --format='#{format}' --count=#{count}`.split(/\n/).map(&:strip).map{|output|TagRange.new(output)}
end
# matches either tags starting with the stage name
# or containing 'ruby' e.g.
# refs/tags/cruby* or ref/tags/*ruby*
def process_commit(hash, date)
execute_cmd = "metric_fu --format yaml --out _data/#{date}.yml"
unless hash == ''
message = "#{date},#{hash}"
puts "BEGIN #{message}"
puts "execute_cmd: #{execute_cmd}"
p `git reset --hard origin/master && git checkout #{hash} && #{execute_cmd}; git checkout master`
puts "END #{message}"
end
end
tag_range(10,'v*').each do |range|
process_commit(range.tag_name,range.date)
end
bump @robincurry
Yeah, I have what was an almost done feature branch for this, but haven't looked at in a bit. I suspect I'll have some rebase work to do to get it up to speed with all the work you've been doing.
Most likely :)
I recently came across this gem and ran it against my codebase. The tool came up with a lot of useful information, but right now the graphs it generated only have one data point. It would be nice if there was some way to build up these graphs with data from old code I have in source control.
Even something as simple as a command-line flag for specifying the commit date of the current state of the repo would be useful. That way I could manually jump to various points in my project's history and generate metrics for those commits.