Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
G
gitlab-ce
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
gitlab-ce
Commits
f082c8ae
Commit
f082c8ae
authored
Nov 04, 2012
by
randx
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Decouple and refactor GraphCommit
parent
f8e27b92
Changes
7
Show whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
393 additions
and
201 deletions
+393
-201
app/controllers/projects_controller.rb
app/controllers/projects_controller.rb
+4
-2
features/steps/project/project_network_graph.rb
features/steps/project/project_network_graph.rb
+2
-2
features/steps/shared/paths.rb
features/steps/shared/paths.rb
+2
-2
lib/gitlab/graph/'
lib/gitlab/graph/'
+165
-0
lib/gitlab/graph/commit.rb
lib/gitlab/graph/commit.rb
+48
-0
lib/gitlab/graph/json_builder.rb
lib/gitlab/graph/json_builder.rb
+172
-0
lib/gitlab/graph_commit.rb
lib/gitlab/graph_commit.rb
+0
-195
No files found.
app/controllers/projects_controller.rb
View file @
f082c8ae
require
Rails
.
root
.
join
(
'lib'
,
'gitlab'
,
'graph
_commit
'
)
require
Rails
.
root
.
join
(
'lib'
,
'gitlab'
,
'graph
'
,
'json_builder
'
)
class
ProjectsController
<
ProjectResourceController
skip_before_filter
:project
,
only:
[
:new
,
:create
]
...
...
@@ -79,7 +79,9 @@ class ProjectsController < ProjectResourceController
end
def
graph
@days_json
,
@commits_json
=
Gitlab
::
GraphCommit
.
to_graph
(
project
)
graph
=
Gitlab
::
Graph
::
JsonBuilder
.
new
(
project
)
@days_json
,
@commits_json
=
graph
.
days_json
,
graph
.
commits_json
end
def
destroy
...
...
features/steps/project/project_network_graph.rb
View file @
f082c8ae
...
...
@@ -11,8 +11,8 @@ class ProjectNetworkGraph < Spinach::FeatureSteps
end
And
'I visit project "Shop" network page'
do
# Stub Graph
Commit
max_size to speed up test (10 commits vs. 650)
Gitlab
::
Graph
Commit
.
stub
(
max_count:
10
)
# Stub Graph
::JsonBuilder
max_size to speed up test (10 commits vs. 650)
Gitlab
::
Graph
::
JsonBuilder
.
stub
(
max_count:
10
)
project
=
Project
.
find_by_name
(
"Shop"
)
visit
graph_project_path
(
project
)
...
...
features/steps/shared/paths.rb
View file @
f082c8ae
...
...
@@ -126,8 +126,8 @@ module SharedPaths
end
Given
"I visit my project's network page"
do
# Stub Graph
Commit
max_size to speed up test (10 commits vs. 650)
Gitlab
::
Graph
Commit
.
stub
(
max_count:
10
)
# Stub Graph
::JsonBuilder
max_size to speed up test (10 commits vs. 650)
Gitlab
::
Graph
::
JsonBuilder
.
stub
(
max_count:
10
)
visit
graph_project_path
(
@project
)
end
...
...
lib/gitlab/graph/'
0 → 100644
View file @
f082c8ae
require "grit"
module Gitlab
module Graph
class JsonBuilder
attr_accessor :max_count, :days, :commits
def initialize project
@project = project
@repo = project.repo
@commits = collect_commits(@repo).dup
@ref_cache = {}
@commits.map! { |commit| Graph::Commit.new(Commit.new(commit))}
@commits.each { |commit| commit.add_refs(ref_cache, @repo) }
days = Graph::Commit.index_commits(@commits)
return @days_json, @commits_json
end
def collect_commits
end
def days_json
@days_json = @days.compact.map { |d| [d.day, d.strftime("%b")] }.to_json
end
def commits_json
@commits_json = @commits.map(&:to_graph_hash).to_json
end
# Get commits from repository
#
def collect_commits repo
Grit::Commit.find_all(repo, nil, {max_count: self.max_count})
end
def max_count
@max_count ||= 650
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<Graph::Commit>] comits to index
#
# @return [Array<TimeDate>] list of commit dates corelated with time on commits
def 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
# Add space mark on commit and its parents
#
# @param [Graph::Commit] the commit object.
# @param [Hash<String,Graph::Commit>] map of commits
def 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
def mark_reserved(time_range, space)
for day in time_range
@_reserved[day].push(space)
end
end
def 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
# Takes most left subtree branch of commits
# which don't have space mark yet.
#
# @param [Graph::Commit] the commit object.
# @param [Hash<String,Graph::Commit>] map of commits
#
# @return [Array<Graph::Commit>] list of branch commits
def take_left_leaves(commit, map)
leaves = []
leaves.push(commit) if commit.space == 0
while true
parent = commit.parents.collect
self.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
end
end
end
lib/gitlab/graph/commit.rb
0 → 100644
View file @
f082c8ae
require
"grit"
module
Gitlab
module
Graph
class
Commit
include
ActionView
::
Helpers
::
TagHelper
attr_accessor
:time
,
:space
,
:refs
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
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
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
end
end
end
lib/gitlab/graph/json_builder.rb
0 → 100644
View file @
f082c8ae
require
"grit"
module
Gitlab
module
Graph
class
JsonBuilder
attr_accessor
:days
,
:commits
,
:ref_cache
,
:repo
def
self
.
max_count
@max_count
||=
650
end
def
initialize
project
@project
=
project
@repo
=
project
.
repo
@ref_cache
=
{}
@commits
=
collect_commits
@days
=
index_commits
end
def
days_json
@days_json
=
@days
.
compact
.
map
{
|
d
|
[
d
.
day
,
d
.
strftime
(
"%b"
)]
}.
to_json
end
def
commits_json
@commits_json
=
@commits
.
map
(
&
:to_graph_hash
).
to_json
end
protected
# Get commits from repository
#
def
collect_commits
@commits
=
Grit
::
Commit
.
find_all
(
repo
,
nil
,
{
max_count:
self
.
class
.
max_count
}).
dup
# Decorate with app/models/commit.rb
@commits
.
map!
{
|
commit
|
::
Commit
.
new
(
commit
)
}
# Decorate with lib/gitlab/graph/commit.rb
@commits
.
map!
{
|
commit
|
Gitlab
::
Graph
::
Commit
.
new
(
commit
)
}
# add refs to each commit
@commits
.
each
{
|
commit
|
commit
.
add_refs
(
ref_cache
,
repo
)
}
@commits
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<Graph::Commit>] comits to index
#
# @return [Array<TimeDate>] list of commit dates corelated with time on commits
def
index_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
# Add space mark on commit and its parents
#
# @param [Graph::Commit] the commit object.
# @param [Hash<String,Graph::Commit>] map of commits
def
place_chain
(
commit
,
map
,
parent_time
=
nil
)
leaves
=
take_left_leaves
(
commit
,
map
)
if
leaves
.
empty?
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
parent
=
map
[
p
.
id
]
if
parent
.
time
<
min_time
min_time
=
parent
.
time
end
end
end
if
parent_time
.
nil?
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
def
mark_reserved
(
time_range
,
space
)
for
day
in
time_range
@_reserved
[
day
].
push
(
space
)
end
end
def
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
# Takes most left subtree branch of commits
# which don't have space mark yet.
#
# @param [Graph::Commit] the commit object.
# @param [Hash<String,Graph::Commit>] map of commits
#
# @return [Array<Graph::Commit>] list of branch commits
def
take_left_leaves
(
commit
,
map
)
leaves
=
[]
leaves
.
push
(
commit
)
if
commit
.
space
.
zero?
while
true
parent
=
commit
.
parents
.
collect
.
select
do
|
p
|
map
.
include?
p
.
id
and
map
[
p
.
id
].
space
==
0
end
return
leaves
if
parent
.
count
.
zero?
commit
=
map
[
parent
.
first
.
id
]
leaves
.
push
(
commit
)
end
end
end
end
end
lib/gitlab/graph_commit.rb
deleted
100644 → 0
View file @
f8e27b92
require
"grit"
module
Gitlab
class
GraphCommit
attr_accessor
:time
,
:space
,
:refs
include
ActionView
::
Helpers
::
TagHelper
def
self
.
to_graph
(
project
)
@repo
=
project
.
repo
commits
=
collect_commits
(
@repo
).
dup
ref_cache
=
{}
commits
.
map!
{
|
commit
|
GraphCommit
.
new
(
Commit
.
new
(
commit
))}
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
# Get commits from repository
#
def
self
.
collect_commits
repo
Grit
::
Commit
.
find_all
(
repo
,
nil
,
{
max_count:
self
.
max_count
})
end
def
self
.
max_count
@max_count
||=
650
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
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
# Add space mark on commit and its parents
#
# @param [GraphCommit] the commit object.
# @param [Hash<String,GraphCommit>] map of commits
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
def
self
.
mark_reserved
(
time_range
,
space
)
for
day
in
time_range
@_reserved
[
day
].
push
(
space
)
end
end
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
# 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
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
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
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
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
end
end
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment