Permalink
Fetching contributors…
Cannot retrieve contributors at this time
executable file 168 lines (145 sloc) 4.91 KB
#!/usr/bin/env ruby
# Copyright (C) 2010 Gregoire Lejeune <gregoire.lejeune@free.fr>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
require 'rubygems'
require 'getoptlong'
require 'graphviz'
class Git2Gv
def initialize( xGVPath, xOutFile, xOutFormat, bNothugly )
@xGVPath, @xOutFile, @xOutFormat, @bNothugly = xGVPath, xOutFile, xOutFormat.to_sym, bNothugly
end
def run
git = GraphViz.new( :G, :path => @xGVPath )
git.node[:shape => "record"]
branches.each do |branch|
git.add_nodes( branch, :style => "filled", :fillcolor => :lightgrey )
end
commits.each do |commit|
git.add_nodes(
commit[:short],
:style => "filled",
:fillcolor => :lightblue,
:label => "{ #{commit[:long]} |{ #{commit[:comment].gsub(/\{/, "\\{").gsub(/\}/, "\\}").gsub(/\|/, "\\|").gsub(/</, "\\<").gsub(/>/, "\\>")}}| { #{commit[:commiter]} | #{commit[:date]} } }"
)
end
refs.each do |from, to|
git.add_edges( from, to )
end
relations.each do |from, to|
git.add_edges( to, from, :dir => "back" )
end
git.output( @xOutFormat => @xOutFile, :nothugly => @bNothugly )
end
# private
def cmd(c, &blk)
`#{c}`.split($/).map(&blk || proc {|a| a })
end
def commits
@commits ||= begin
data = []
cmd('git log --pretty=format:"%h - %H - %s - %cn - %cd" --date=short').each do |commit|
x = commit.split( " - " )
data << {
:short => x[0],
:long => x[1],
:comment => x[2],
:commiter => x[3],
:date => x[4]
}
end
data
end
end
def relations
@rels ||= cmd("git log --pretty=format:\"%h %p\"") { |l|
c, *parents = l.split
parents.map {|p| [p, c] }
}.flatten(1)
end
def branches
@branches ||= cmd("git branch") {|b| b[2..-1] }
end
def refs
branches.inject({}) {|h,b|
h.tap { h[b] = `git log -1 #{b} --pretty=format:"%h"` }
}
end
def current_branch
cmd("git branch").select {|l| l =~ /^\*/ }.first.strip[2..-1]
end
end
def usage
puts "usage: git2gv [-Tformat] [-ofile] [-h] [-V]"
puts "-T, --output-format format Output format (default: png)"
puts " --nothugly Use nothugly if SVG output"
puts "-o, --output-file file Output file (default: STDOUT)"
puts "-p, --path Graphviz path"
puts "-V, --version Show version"
puts "-h, --help Show this usage message"
end
def version
puts "Git2GraphViz v#{GraphViz::Constants::RGV_VERSION}, (c)2010 Gregoire Lejeune <gregoire.lejeune@free.fr>"
puts ""
puts "This program is free software; you can redistribute it and/or modify"
puts "it under the terms of the GNU General Public License as published by"
puts "the Free Software Foundation; either version 2 of the License, or"
puts "(at your option) any later version."
puts ""
puts "This program is distributed in the hope that it will be useful,"
puts "but WITHOUT ANY WARRANTY; without even the implied warranty of"
puts "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the"
puts "GNU General Public License for more details."
puts ""
puts "You should have received a copy of the GNU General Public License"
puts "along with this program; if not, write to the Free Software"
puts "Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA"
end
oOpt = GetoptLong.new(
['--output-format', '-T', GetoptLong::REQUIRED_ARGUMENT],
['--output-file', '-o', GetoptLong::REQUIRED_ARGUMENT],
['--path', '-p', GetoptLong::REQUIRED_ARGUMENT],
['--nothugly', GetoptLong::NO_ARGUMENT],
['--help', '-h', GetoptLong::NO_ARGUMENT],
['--version', '-V', GetoptLong::NO_ARGUMENT]
)
xOutFormat = "png"
xOutFile = nil
xGVPath = ""
bNothugly = false
begin
oOpt.each_option do |xOpt, xValue|
case xOpt
when '--output-format'
xOutFormat = xValue
when '--output-file'
xOutFile = xValue
when '--path'
xGVPath = xValue
when '--nothugly'
bNothugly = true
when '--help'
usage( )
exit
when '--version'
version( )
exit
end
end
rescue GetoptLong::InvalidOption
usage( )
exit
end
Git2Gv.new( xGVPath, xOutFile, xOutFormat, bNothugly ).run