require "grit" class GraphCommit attr_accessor :time, :space def initialize(commit) @_commit = commit @time = -1 @space = 0 end def method_missing(m, *args, &block) @_commit.send(m, *args, &block) end # Method is adding time and space on the # list of commits. As well as returns date list # corelated with time set on commits. # # @param [Array] comits to index # # @return [Array] list of commit dates corelated with time on commits def self.index_commits(commits) days, heads = [], [] map = {} commits.reverse.each_with_index do |c,i| c.time = i days[i] = c.committed_date 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 elsif b.name == "master" 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 j = mark_chain(j+=1, map[h.commit.id], map) 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. # @param [Hash] map of commits # # @return [Fixnum] max space used. 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 mark_chain(m1 += 1, map[p.id],map) else m1 + 1 end end marks << mark marks.compact.max end end