# File lib/gitlab/graph_commit.rb, line 113 def self.find_free_space(time_range) reserved = [] for day in time_range reserved += @_reserved[day] end space = 1 while reserved.include? space do space += 1 end space 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<GraphCommit>] comits to index
@return [Array<TimeDate>] list of commit dates corelated with time on commits
# File lib/gitlab/graph_commit.rb, line 33 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 @_reserved = {} days.each_index do |i| @_reserved[i] = [] end heads.each do |h| if map.include? h.commit.id then place_chain(map[h.commit.id], map) end end days end
# File lib/gitlab/graph_commit.rb, line 107 def self.mark_reserved(time_range, space) for day in time_range @_reserved[day].push(space) end end
# File lib/gitlab/graph_commit.rb, line 148 def initialize(commit) @_commit = commit @time = -1 @space = 0 end
Add space mark on commit and its parents
@param [GraphCommit] the commit object. @param [Hash<String,GraphCommit>] map of commits
# File lib/gitlab/graph_commit.rb, line 73 def self.place_chain(commit, map, parent_time = nil) leaves = take_left_leaves(commit, map) if leaves.empty? then return end space = find_free_space(leaves.last.time..leaves.first.time) leaves.each{|l| l.space = space} # and mark it as reserved min_time = leaves.last.time parents = leaves.last.parents.collect parents.each do |p| if map.include? p.id then parent = map[p.id] if parent.time < min_time then min_time = parent.time end end end if parent_time.nil? then max_time = leaves.first.time else max_time = parent_time - 1 end mark_reserved(min_time..max_time, space) # Visit branching chains leaves.each do |l| parents = l.parents.collect .select{|p| map.include? p.id and map[p.id].space == 0} for p in parents place_chain(map[p.id], map, l.time) end end end
Takes most left subtree branch of commits which don’t have space mark yet.
@param [GraphCommit] the commit object. @param [Hash<String,GraphCommit>] map of commits
@return [Array<GraphCommit>] list of branch commits
# File lib/gitlab/graph_commit.rb, line 132 def self.take_left_leaves(commit, map) leaves = [] leaves.push(commit) if commit.space == 0 while true parent = commit.parents.collect .select{|p| map.include? p.id and map[p.id].space == 0} if parent.count == 0 then return leaves else commit = map[parent.first.id] leaves.push(commit) end end end
# File lib/gitlab/graph_commit.rb, line 10 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 end
# File lib/gitlab/graph_commit.rb, line 174 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
# File lib/gitlab/graph_commit.rb, line 154 def method_missing(m, *args, &block) @_commit.send(m, *args, &block) end
# File lib/gitlab/graph_commit.rb, line 158 def to_graph_hash h = {} h[:parents] = self.parents.collect do |p| [p.id,0,0] end h[:author] = Gitlab::Encode.utf8(author.name) h[:time] = time h[:space] = space h[:refs] = refs.collect{|r|r.name}.join(" ") unless refs.nil? h[:id] = sha h[:date] = date h[:message] = escape_once(Gitlab::Encode.utf8(message)) h[:login] = author.email h end