gitlabhq/lib/graph_commit.rb

121 lines
2.9 KiB
Ruby
Raw Normal View History

2011-11-12 23:30:51 +01:00
require "grit"
class GraphCommit
attr_accessor :time, :space
2011-11-27 16:35:49 +01:00
attr_accessor :refs
2011-11-12 23:30:51 +01:00
2011-11-27 16:35:49 +01:00
def self.to_graph(project)
@repo = project.repo
commits = Grit::Commit.find_all(@repo, nil, {:max_count => 650})
ref_cache = {}
commits.map! {|c| GraphCommit.new(Commit.new(c))}
commits.each { |commit| commit.add_refs(ref_cache, @repo) }
days = GraphCommit.index_commits(commits)
@days_json = days.compact.collect{|d| [d.day, d.strftime("%b")] }.to_json
@commits_json = commits.map(&:to_graph_hash).to_json
return @days_json, @commits_json
2011-11-12 23:30:51 +01:00
end
2011-11-15 09:34:30 +01:00
# Method is adding time and space on the
# list of commits. As well as returns date list
2011-11-12 23:30:51 +01:00
# corelated with time set on commits.
#
# @param [Array<GraphCommit>] comits to index
#
2011-11-15 09:34:30 +01:00
# @return [Array<TimeDate>] list of commit dates corelated with time on commits
2011-11-12 23:30:51 +01:00
def self.index_commits(commits)
days, heads = [], []
map = {}
commits.reverse.each_with_index do |c,i|
c.time = i
2011-11-15 09:34:30 +01:00
days[i] = c.committed_date
2011-11-12 23:30:51 +01:00
map[c.id] = c
heads += c.refs unless c.refs.nil?
end
heads.select!{|h| h.is_a? Grit::Head or h.is_a? Grit::Remote}
# sort heads so the master is top and current branches are closer
heads.sort! do |a,b|
if a.name == "master"
-1
2011-11-15 09:34:30 +01:00
elsif b.name == "master"
2011-11-12 23:30:51 +01:00
1
else
b.commit.committed_date <=> a.commit.committed_date
end
end
j = 0
heads.each do |h|
if map.include? h.commit.id then
2011-11-15 09:34:30 +01:00
j = mark_chain(j+=1, map[h.commit.id], map)
2011-11-12 23:30:51 +01:00
end
end
days
end
# Add space mark on commit and its parents
#
# @param [Fixnum] space (row on the graph) to be set
# @param [GraphCommit] the commit object.
2011-11-15 09:34:30 +01:00
# @param [Hash<String,GraphCommit>] map of commits
2011-11-12 23:30:51 +01:00
#
# @return [Fixnum] max space used.
2011-11-12 23:30:51 +01:00
def self.mark_chain(mark, commit, map)
commit.space = mark if commit.space == 0
m1 = mark - 1
marks = commit.parents.collect do |p|
if map.include? p.id and map[p.id].space == 0 then
2011-11-15 09:34:30 +01:00
mark_chain(m1 += 1, map[p.id],map)
2011-11-12 23:30:51 +01:00
else
m1 + 1
end
end
marks << mark
marks.compact.max
end
2011-11-15 09:34:30 +01:00
2011-11-27 16:35:49 +01:00
def initialize(commit)
@_commit = commit
@time = -1
@space = 0
end
def method_missing(m, *args, &block)
@_commit.send(m, *args, &block)
end
def to_graph_hash
h = {}
h[:parents] = self.parents.collect do |p|
[p.id,0,0]
end
2012-03-12 14:39:41 +01:00
h[:author] = author.name.force_encoding("UTF-8")
2011-11-27 16:35:49 +01:00
h[:time] = time
h[:space] = space
h[:refs] = refs.collect{|r|r.name}.join(" ") unless refs.nil?
h[:id] = sha
h[:date] = date
2012-01-04 00:21:30 +01:00
h[:message] = message.force_encoding("UTF-8")
2011-11-27 16:35:49 +01:00
h[:login] = author.email
h
end
def add_refs(ref_cache, repo)
if ref_cache.empty?
repo.refs.each do |ref|
ref_cache[ref.commit.id] ||= []
ref_cache[ref.commit.id] << ref
end
end
@refs = ref_cache[@_commit.id] if ref_cache.include?(@_commit.id)
@refs ||= []
end
2011-11-12 23:30:51 +01:00
end