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
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Jérome Perrin
gitlab-ce
Commits
6b66a766
Commit
6b66a766
authored
Nov 13, 2011
by
Valery Sizov
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Graph: build json
parent
ef088725
Changes
9
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
9 changed files
with
308 additions
and
1 deletion
+308
-1
.rbenv-version
.rbenv-version
+1
-0
app/assets/javascripts/application.js
app/assets/javascripts/application.js
+3
-1
app/controllers/projects_controller.rb
app/controllers/projects_controller.rb
+40
-0
app/views/layouts/project.html.haml
app/views/layouts/project.html.haml
+1
-0
config/routes.rb
config/routes.rb
+1
-0
lib/assets/javascripts/branch-graph.js
lib/assets/javascripts/branch-graph.js
+170
-0
lib/commit_ext.rb
lib/commit_ext.rb
+3
-0
lib/graph_commit.rb
lib/graph_commit.rb
+82
-0
vendor/assets/javascripts/raphael.js
vendor/assets/javascripts/raphael.js
+7
-0
No files found.
.rbenv-version
0 → 100644
View file @
6b66a766
1.9.2-p290
app/assets/javascripts/application.js
View file @
6b66a766
...
...
@@ -10,6 +10,8 @@
//= require jquery.ui.selectmenu
//= require jquery.tagify
//= require jquery.cookie
//= require raphael
//= require branch-graph
//= require_tree .
$
(
function
(){
...
...
@@ -35,4 +37,4 @@ function showMenu() {
function
resetMenu
()
{
$
(
this
).
removeClass
(
"
hover
"
);
}
\ No newline at end of file
}
app/controllers/projects_controller.rb
View file @
6b66a766
require
File
.
join
(
Rails
.
root
,
'lib'
,
'graph_commit'
)
class
ProjectsController
<
ApplicationController
before_filter
:project
,
:except
=>
[
:index
,
:new
,
:create
]
layout
:determine_layout
...
...
@@ -125,6 +127,36 @@ class ProjectsController < ApplicationController
return
render_404
end
def
graph
@repo
=
project
.
repo
commits
=
Grit
::
Commit
.
find_all
(
@repo
,
nil
,
{
:max_count
=>
650
})
ref_cache
=
{}
commits
.
collect!
do
|
commit
|
add_refs
(
commit
,
ref_cache
)
GraphCommit
.
new
(
commit
)
end
days
=
GraphCommit
.
index_commits
(
commits
)
@days_json
=
days
.
compact
.
collect
{
|
d
|
[
d
.
day
,
d
.
strftime
(
"%b"
)]
}.
to_json
@commits_json
=
commits
.
collect
do
|
c
|
h
=
{}
h
[
:parents
]
=
c
.
parents
.
collect
do
|
p
|
[
p
.
id
,
0
,
0
]
end
h
[
:author
]
=
c
.
author
.
name
.
force_encoding
(
"UTF-8"
)
h
[
:time
]
=
c
.
time
h
[
:space
]
=
c
.
space
h
[
:refs
]
=
c
.
refs
.
collect
{
|
r
|
r
.
name
}.
join
(
" "
)
unless
c
.
refs
.
nil?
h
[
:id
]
=
c
.
sha
h
[
:date
]
=
c
.
date
h
[
:message
]
=
c
.
message
.
force_encoding
(
"UTF-8"
)
h
[
:email
]
=
c
.
author
.
email
h
end
.
to_json
render
:text
=>
@commits_json
end
def
blob
@repo
=
project
.
repo
@commit
=
project
.
commit
(
params
[
:commit_id
])
...
...
@@ -149,6 +181,14 @@ class ProjectsController < ApplicationController
protected
def
add_refs
(
commit
,
ref_cache
)
if
ref_cache
.
empty?
@repo
.
refs
.
each
{
|
ref
|
ref_cache
[
ref
.
commit
.
id
]
||=
[];
ref_cache
[
ref
.
commit
.
id
]
<<
ref
}
end
commit
.
refs
=
ref_cache
[
commit
.
id
]
if
ref_cache
.
include?
commit
.
id
commit
.
refs
||=
[]
end
def
project
@project
||=
Project
.
find_by_code
(
params
[
:id
])
end
...
...
app/views/layouts/project.html.haml
View file @
6b66a766
...
...
@@ -22,6 +22,7 @@
=
link_to
"History"
,
project_path
(
@project
),
:class
=>
current_page?
(
:controller
=>
"projects"
,
:action
=>
"show"
,
:id
=>
@project
)
?
"current"
:
nil
=
link_to
"Tree"
,
tree_project_path
(
@project
),
:class
=>
current_page?
(
:controller
=>
"projects"
,
:action
=>
"tree"
,
:id
=>
@project
)
?
"current"
:
nil
=
link_to
"Commits"
,
project_commits_path
(
@project
),
:class
=>
current_page?
(
:controller
=>
"commits"
,
:action
=>
"index"
,
:project_id
=>
@project
)
?
"current"
:
nil
=
link_to
"Network graph"
,
graph_project_path
(
@project
),
:class
=>
current_page?
(
:controller
=>
"projects"
,
:action
=>
"graph"
,
:project_id
=>
@project
)
?
"current"
:
nil
=
link_to
team_project_path
(
@project
),
:class
=>
(
current_page?
(
:controller
=>
"projects"
,
:action
=>
"team"
,
:id
=>
@project
)
||
controller
.
controller_name
==
"team_members"
)
?
"current"
:
nil
do
Team
-
if
@project
.
users_projects
.
count
>
0
...
...
config/routes.rb
View file @
6b66a766
...
...
@@ -34,6 +34,7 @@ Gitlab::Application.routes.draw do
get
"blob"
get
"team"
get
"wall"
get
"graph"
# tree viewer
get
"tree/:commit_id"
=>
"projects#tree"
...
...
lib/assets/javascripts/branch-graph.js
0 → 100644
View file @
6b66a766
var
commits
=
chunk1
.
commits
,
comms
=
{},
pixelsX
=
[],
pixelsY
=
[],
mmax
=
Math
.
max
,
mtime
=
0
,
mspace
=
0
,
parents
=
{};
for
(
var
i
=
0
,
ii
=
commits
.
length
;
i
<
ii
;
i
++
)
{
for
(
var
j
=
0
,
jj
=
commits
[
i
].
parents
.
length
;
j
<
jj
;
j
++
)
{
parents
[
commits
[
i
].
parents
[
j
][
0
]]
=
true
;
}
mtime
=
Math
.
max
(
mtime
,
commits
[
i
].
time
);
mspace
=
Math
.
max
(
mspace
,
commits
[
i
].
space
);
}
mtime
=
mtime
+
4
;
mspace
=
mspace
+
10
;
for
(
i
=
0
;
i
<
ii
;
i
++
)
{
if
(
commits
[
i
].
id
in
parents
)
{
commits
[
i
].
isParent
=
true
;
}
comms
[
commits
[
i
].
id
]
=
commits
[
i
];
}
var
colors
=
[
"
#000
"
];
for
(
var
k
=
0
;
k
<
mspace
;
k
++
)
{
colors
.
push
(
Raphael
.
getColor
());
}
function
branchGraph
(
holder
)
{
var
ch
=
mspace
*
20
+
20
,
cw
=
mtime
*
20
+
20
,
r
=
Raphael
(
"
holder
"
,
cw
,
ch
),
top
=
r
.
set
();
var
cuday
=
0
,
cumonth
=
""
;
r
.
rect
(
0
,
0
,
days
.
length
*
20
+
20
,
40
).
attr
({
fill
:
"
#999
"
});
for
(
mm
=
0
;
mm
<
days
.
length
;
mm
++
)
{
if
(
days
[
mm
]
!=
null
){
if
(
cuday
!=
days
[
mm
][
0
]){
r
.
text
(
10
+
mm
*
20
,
30
,
days
[
mm
][
0
]).
attr
({
font
:
"
12px Fontin-Sans, Arial
"
,
fill
:
"
#444
"
});
cuday
=
days
[
mm
][
0
]
}
if
(
cumonth
!=
days
[
mm
][
1
]){
r
.
text
(
10
+
mm
*
20
,
10
,
days
[
mm
][
1
]).
attr
({
font
:
"
12px Fontin-Sans, Arial
"
,
fill
:
"
#444
"
});
cumonth
=
days
[
mm
][
1
]
}
}
}
for
(
i
=
0
;
i
<
ii
;
i
++
)
{
var
x
=
10
+
20
*
commits
[
i
].
time
,
y
=
70
+
20
*
commits
[
i
].
space
;
r
.
circle
(
x
,
y
,
3
).
attr
({
fill
:
colors
[
commits
[
i
].
space
],
stroke
:
"
none
"
});
if
(
commits
[
i
].
refs
!=
null
&&
commits
[
i
].
refs
!=
""
)
{
var
longrefs
=
commits
[
i
].
refs
var
shortrefs
=
commits
[
i
].
refs
;
if
(
shortrefs
.
length
>
15
){
shortrefs
=
shortrefs
.
substr
(
0
,
13
)
+
"
...
"
;
}
var
t
=
r
.
text
(
x
+
5
,
y
+
5
,
shortrefs
).
attr
({
font
:
"
12px Fontin-Sans, Arial
"
,
fill
:
"
#666
"
,
title
:
longrefs
,
cursor
:
"
pointer
"
,
rotation
:
"
90
"
});
var
textbox
=
t
.
getBBox
();
t
.
translate
(
textbox
.
height
/-
4
,
textbox
.
width
/
2
);
}
for
(
var
j
=
0
,
jj
=
commits
[
i
].
parents
.
length
;
j
<
jj
;
j
++
)
{
var
c
=
comms
[
commits
[
i
].
parents
[
j
][
0
]];
if
(
c
)
{
var
cx
=
10
+
20
*
c
.
time
,
cy
=
70
+
20
*
c
.
space
;
if
(
c
.
space
==
commits
[
i
].
space
)
{
r
.
path
(
"
M
"
+
(
x
-
5
)
+
"
,
"
+
(
y
+
.
0001
)
+
"
L
"
+
(
15
+
20
*
c
.
time
)
+
"
,
"
+
(
y
+
.
0001
))
.
attr
({
stroke
:
colors
[
c
.
space
],
"
stroke-width
"
:
2
});
}
else
if
(
c
.
space
<
commits
[
i
].
space
)
{
r
.
path
([
"
M
"
,
x
-
5
,
y
+
.
0001
,
"
l-5-2,0,4,5,-2C
"
,
x
-
5
,
y
,
x
-
17
,
y
+
2
,
x
-
20
,
y
-
10
,
"
L
"
,
cx
,
y
-
10
,
cx
,
cy
])
.
attr
({
stroke
:
colors
[
commits
[
i
].
space
],
"
stroke-width
"
:
2
});
}
else
{
r
.
path
([
"
M
"
,
x
-
5
,
y
,
"
l-5-2,0,4,5,-2C
"
,
x
-
5
,
y
,
x
-
17
,
y
-
2
,
x
-
20
,
y
+
10
,
"
L
"
,
cx
,
y
+
10
,
cx
,
cy
])
.
attr
({
stroke
:
colors
[
commits
[
i
].
space
],
"
stroke-width
"
:
2
});
}
}
}
(
function
(
c
,
x
,
y
)
{
top
.
push
(
r
.
circle
(
x
,
y
,
10
).
attr
({
fill
:
"
#000
"
,
opacity
:
0
,
cursor
:
"
pointer
"
})
.
hover
(
function
()
{
var
s
=
r
.
text
(
100
,
100
,
c
.
author
+
"
\n
\n
"
+
c
.
id
+
"
\n
\n
"
+
c
.
message
).
attr
({
fill
:
"
#fff
"
});
this
.
popup
=
r
.
popupit
(
x
,
y
+
5
,
s
,
0
);
top
.
push
(
this
.
popup
.
insertBefore
(
this
));
},
function
()
{
this
.
popup
&&
this
.
popup
.
remove
()
&&
delete
this
.
popup
;
}));
}(
commits
[
i
],
x
,
y
));
}
top
.
toFront
();
var
hw
=
holder
.
offsetWidth
,
hh
=
holder
.
offsetHeight
,
v
=
r
.
rect
(
hw
-
8
,
0
,
4
,
Math
.
pow
(
hh
,
2
)
/
ch
,
2
).
attr
({
fill
:
"
#000
"
,
opacity
:
0
}),
h
=
r
.
rect
(
0
,
hh
-
8
,
Math
.
pow
(
hw
,
2
)
/
cw
,
4
,
2
).
attr
({
fill
:
"
#000
"
,
opacity
:
0
}),
bars
=
r
.
set
(
v
,
h
),
drag
,
dragger
=
function
(
e
)
{
if
(
drag
)
{
e
=
e
||
window
.
event
;
holder
.
scrollLeft
=
drag
.
sl
-
(
e
.
clientX
-
drag
.
x
);
holder
.
scrollTop
=
drag
.
st
-
(
e
.
clientY
-
drag
.
y
);
}
};
holder
.
onmousedown
=
function
(
e
)
{
e
=
e
||
window
.
event
;
drag
=
{
x
:
e
.
clientX
,
y
:
e
.
clientY
,
st
:
holder
.
scrollTop
,
sl
:
holder
.
scrollLeft
};
document
.
onmousemove
=
dragger
;
bars
.
animate
({
opacity
:
.
5
},
300
);
};
document
.
onmouseup
=
function
()
{
drag
=
false
;
document
.
onmousemove
=
null
;
bars
.
animate
({
opacity
:
0
},
300
);
};
holder
.
scrollLeft
=
cw
;
};
Raphael
.
fn
.
popupit
=
function
(
x
,
y
,
set
,
dir
,
size
)
{
dir
=
dir
==
null
?
2
:
dir
;
size
=
size
||
5
;
x
=
Math
.
round
(
x
);
y
=
Math
.
round
(
y
);
var
bb
=
set
.
getBBox
(),
w
=
Math
.
round
(
bb
.
width
/
2
),
h
=
Math
.
round
(
bb
.
height
/
2
),
dx
=
[
0
,
w
+
size
*
2
,
0
,
-
w
-
size
*
2
],
dy
=
[
-
h
*
2
-
size
*
3
,
-
h
-
size
,
0
,
-
h
-
size
],
p
=
[
"
M
"
,
x
-
dx
[
dir
],
y
-
dy
[
dir
],
"
l
"
,
-
size
,
(
dir
==
2
)
*
-
size
,
-
mmax
(
w
-
size
,
0
),
0
,
"
a
"
,
size
,
size
,
0
,
0
,
1
,
-
size
,
-
size
,
"
l
"
,
0
,
-
mmax
(
h
-
size
,
0
),
(
dir
==
3
)
*
-
size
,
-
size
,
(
dir
==
3
)
*
size
,
-
size
,
0
,
-
mmax
(
h
-
size
,
0
),
"
a
"
,
size
,
size
,
0
,
0
,
1
,
size
,
-
size
,
"
l
"
,
mmax
(
w
-
size
,
0
),
0
,
size
,
!
dir
*
-
size
,
size
,
!
dir
*
size
,
mmax
(
w
-
size
,
0
),
0
,
"
a
"
,
size
,
size
,
0
,
0
,
1
,
size
,
size
,
"
l
"
,
0
,
mmax
(
h
-
size
,
0
),
(
dir
==
1
)
*
size
,
size
,
(
dir
==
1
)
*
-
size
,
size
,
0
,
mmax
(
h
-
size
,
0
),
"
a
"
,
size
,
size
,
0
,
0
,
1
,
-
size
,
size
,
"
l
"
,
-
mmax
(
w
-
size
,
0
),
0
,
"
z
"
].
join
(
"
,
"
),
xy
=
[{
x
:
x
,
y
:
y
+
size
*
2
+
h
},
{
x
:
x
-
size
*
2
-
w
,
y
:
y
},
{
x
:
x
,
y
:
y
-
size
*
2
-
h
},
{
x
:
x
+
size
*
2
+
w
,
y
:
y
}][
dir
];
set
.
translate
(
xy
.
x
-
w
-
bb
.
x
,
xy
.
y
-
h
-
bb
.
y
);
return
this
.
set
(
this
.
path
(
p
).
attr
({
fill
:
"
#234
"
,
stroke
:
"
none
"
}).
insertBefore
(
set
.
node
?
set
:
set
[
0
]),
set
);
};
Raphael
.
fn
.
popup
=
function
(
x
,
y
,
text
,
dir
,
size
)
{
dir
=
dir
==
null
?
2
:
dir
>
3
?
3
:
dir
;
size
=
size
||
5
;
text
=
text
||
"
$9.99
"
;
var
res
=
this
.
set
(),
d
=
3
;
res
.
push
(
this
.
path
().
attr
({
fill
:
"
#000
"
,
stroke
:
"
#000
"
}));
res
.
push
(
this
.
text
(
x
,
y
,
text
).
attr
(
this
.
g
.
txtattr
).
attr
({
fill
:
"
#fff
"
,
"
font-family
"
:
"
Helvetica, Arial
"
}));
res
.
update
=
function
(
X
,
Y
,
withAnimation
)
{
X
=
X
||
x
;
Y
=
Y
||
y
;
var
bb
=
this
[
1
].
getBBox
(),
w
=
bb
.
width
/
2
,
h
=
bb
.
height
/
2
,
dx
=
[
0
,
w
+
size
*
2
,
0
,
-
w
-
size
*
2
],
dy
=
[
-
h
*
2
-
size
*
3
,
-
h
-
size
,
0
,
-
h
-
size
],
p
=
[
"
M
"
,
X
-
dx
[
dir
],
Y
-
dy
[
dir
],
"
l
"
,
-
size
,
(
dir
==
2
)
*
-
size
,
-
mmax
(
w
-
size
,
0
),
0
,
"
a
"
,
size
,
size
,
0
,
0
,
1
,
-
size
,
-
size
,
"
l
"
,
0
,
-
mmax
(
h
-
size
,
0
),
(
dir
==
3
)
*
-
size
,
-
size
,
(
dir
==
3
)
*
size
,
-
size
,
0
,
-
mmax
(
h
-
size
,
0
),
"
a
"
,
size
,
size
,
0
,
0
,
1
,
size
,
-
size
,
"
l
"
,
mmax
(
w
-
size
,
0
),
0
,
size
,
!
dir
*
-
size
,
size
,
!
dir
*
size
,
mmax
(
w
-
size
,
0
),
0
,
"
a
"
,
size
,
size
,
0
,
0
,
1
,
size
,
size
,
"
l
"
,
0
,
mmax
(
h
-
size
,
0
),
(
dir
==
1
)
*
size
,
size
,
(
dir
==
1
)
*
-
size
,
size
,
0
,
mmax
(
h
-
size
,
0
),
"
a
"
,
size
,
size
,
0
,
0
,
1
,
-
size
,
size
,
"
l
"
,
-
mmax
(
w
-
size
,
0
),
0
,
"
z
"
].
join
(
"
,
"
),
xy
=
[{
x
:
X
,
y
:
Y
+
size
*
2
+
h
},
{
x
:
X
-
size
*
2
-
w
,
y
:
Y
},
{
x
:
X
,
y
:
Y
-
size
*
2
-
h
},
{
x
:
X
+
size
*
2
+
w
,
y
:
Y
}][
dir
];
xy
.
path
=
p
;
if
(
withAnimation
)
{
this
.
animate
(
xy
,
500
,
"
>
"
);
}
else
{
this
.
attr
(
xy
);
}
return
this
;
};
return
res
.
update
(
x
,
y
);
};
lib/commit_ext.rb
View file @
6b66a766
module
CommitExt
attr_accessor
:refs
def
safe_message
message
.
encode
(
"UTF-8"
,
:invalid
=>
:replace
,
...
...
lib/graph_commit.rb
0 → 100644
View file @
6b66a766
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<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
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<String,GraphCommit>] 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
def
self
.
add_refs
(
commit
,
ref_cache
)
if
ref_cache
.
empty?
@repo
.
refs
.
each
{
|
ref
|
ref_cache
[
ref
.
commit
.
id
]
||=
[];
ref_cache
[
ref
.
commit
.
id
]
<<
ref
}
end
commit
.
refs
=
ref_cache
[
commit
.
id
]
if
ref_cache
.
include?
commit
.
id
commit
.
refs
||=
[]
end
end
vendor/assets/javascripts/raphael.js
0 → 100644
View file @
6b66a766
This diff is collapsed.
Click to expand it.
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