Commit 492b5adb authored by Valery Sizov's avatar Valery Sizov

Merge remote-tracking branch 'origin/master' into ce_master

parents 90c312e7 0e51ca7c
# This file is generated by GitLab CI image: "ruby:2.1"
services:
- mysql:latest
- postgres:latest
- redis:latest
variables:
MYSQL_ALLOW_EMPTY_PASSWORD: "1"
before_script: before_script:
- ./scripts/prepare_build.sh - ./scripts/prepare_build.sh
- ruby -v - ruby -v
......
...@@ -7,6 +7,7 @@ v 8.5.0 (unreleased) ...@@ -7,6 +7,7 @@ v 8.5.0 (unreleased)
v 8.4.0 (unreleased) v 8.4.0 (unreleased)
- Hide issues settings when issues are disabled (Hannes Rosenögger) - Hide issues settings when issues are disabled (Hannes Rosenögger)
v 8.4.0
- Allow LDAP users to change their email if it was not set by the LDAP server - Allow LDAP users to change their email if it was not set by the LDAP server
- Ensure Gravatar host looks like an actual host - Ensure Gravatar host looks like an actual host
- Consider re-assign as a mention from a notification point of view - Consider re-assign as a mention from a notification point of view
......
File mode changed from 100644 to 100755
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
File mode changed from 100755 to 100644
class @BuildArtifacts
constructor: () ->
@disablePropagation()
@setupEntryClick()
disablePropagation: ->
$('.top-block').on 'click', '.download', (e) ->
e.stopPropagation()
$('.tree-holder').on 'click', 'tr[data-link] a', (e) ->
e.stopImmediatePropagation()
setupEntryClick: ->
$('.tree-holder').on 'click', 'tr[data-link]', (e) ->
window.location = @dataset.link
...@@ -100,6 +100,8 @@ class Dispatcher ...@@ -100,6 +100,8 @@ class Dispatcher
shortcut_handler = true shortcut_handler = true
when 'projects:forks:new' when 'projects:forks:new'
new ProjectFork() new ProjectFork()
when 'projects:artifacts:browse'
new BuildArtifacts()
when 'users:show' when 'users:show'
new User() new User()
new Activities() new Activities()
......
...@@ -120,14 +120,6 @@ span.update-author { ...@@ -120,14 +120,6 @@ span.update-author {
display: inline; display: inline;
} }
.line_holder {
&:hover {
td {
background: #FFFFCF !important;
}
}
}
p.time { p.time {
color: #999; color: #999;
font-size: 90%; font-size: 90%;
......
...@@ -92,15 +92,6 @@ ...@@ -92,15 +92,6 @@
&:last-child { &:last-child {
border-right: none; border-right: none;
} }
background: #fff;
}
.lines {
pre {
padding: 0;
margin: 0;
background: none;
border: none;
}
} }
img.avatar { img.avatar {
border: 0 none; border: 0 none;
...@@ -116,18 +107,18 @@ ...@@ -116,18 +107,18 @@
color: #888; color: #888;
} }
} }
td.blame-numbers { td.line-numbers {
pre { float: none;
color: #AAA;
white-space: pre;
}
background: #f1f1f1;
border-left: 1px solid #DDD; border-left: 1px solid #DDD;
} }
td.lines { td.lines {
padding: 0;
code { code {
font-family: $monospace_font; font-family: $monospace_font;
} }
pre {
margin: 0;
}
} }
} }
......
...@@ -53,3 +53,14 @@ ...@@ -53,3 +53,14 @@
color: #333; color: #333;
} }
} }
.ui-sortable-handle {
cursor: move;
cursor: -webkit-grab;
cursor: -moz-grab;
&:active {
cursor: -webkit-grabbing;
cursor: -moz-grabbing;
}
}
/* https://github.com/MozMorris/tomorrow-pygments */ /* https://github.com/MozMorris/tomorrow-pygments */
.code.dark { .code.dark {
// Line numbers
.line-numbers, .diff-line-num {
background-color: #1d1f21;
}
background-color: #1d1f21 !important; .diff-line-num, .diff-line-num a {
color: #c5c8c6 !important; color: rgba(255, 255, 255, 0.3);
pre.highlight,
.line-numbers,
.line-numbers a {
background-color: #1d1f21 !important;
color: #c5c8c6 !important;
} }
// Code itself
pre.code { pre.code {
border-left: 1px solid #666; border-left: 1px solid #666;
} }
&, pre.code, .line_holder .line_content {
background-color: #1d1f21;
color: #c5c8c6;
}
// Diff line
.line_holder {
.diff-line-num.new, .line_content.new {
@include diff_background(rgba(51, 255, 51, 0.1), rgba(51, 255, 51, 0.3), #808080);
}
.diff-line-num.old, .line_content.old {
@include diff_background(rgba(255, 51, 51, 0.2), rgba(255, 51, 51, 0.3), #808080);
}
.line_content.match {
color: rgba(255, 255, 255, 0.3);
background: rgba(255, 255, 255, 0.1);
}
}
// highlight line via anchor // highlight line via anchor
pre .hll { pre .hll {
background-color: #557 !important; background-color: #557 !important;
...@@ -90,22 +110,4 @@ ...@@ -90,22 +110,4 @@
.vg { color: #cc6666 } /* Name.Variable.Global */ .vg { color: #cc6666 } /* Name.Variable.Global */
.vi { color: #cc6666 } /* Name.Variable.Instance */ .vi { color: #cc6666 } /* Name.Variable.Instance */
.il { color: #de935f } /* Literal.Number.Integer.Long */ .il { color: #de935f } /* Literal.Number.Integer.Long */
.line_holder {
&.parallel .new.new_line,
&.parallel .new.line_content,
&.new .old_line,
&.new .new_line,
&.new .line_content {
@include diff_background(255, 255, 255, #808080);
}
&.parallel .old.old_line,
&.parallel .old.line_content,
&.old .old_line,
&.old .new_line,
&.old .line_content {
@include diff_background(255, 51, 51, #808080);
}
}
} }
/* https://github.com/richleland/pygments-css/blob/master/monokai.css */ /* https://github.com/richleland/pygments-css/blob/master/monokai.css */
.code.monokai { .code.monokai {
// Line numbers
.line-numbers, .diff-line-num {
background-color: #272822;
}
background-color: #272822 !important; .diff-line-num, .diff-line-num a {
color: #f8f8f2 !important; color: rgba(255, 255, 255, 0.3);
pre.highlight,
.line-numbers,
.line-numbers a {
background-color :#272822 !important;
color: #f8f8f2 !important;
} }
// Code itself
pre.code { pre.code {
border-left: 1px solid #555; border-left: 1px solid #555;
} }
&, pre.code, .line_holder .line_content {
background-color: #272822;
color: #f8f8f2;
}
// Diff line
.line_holder {
.diff-line-num.new, .line_content.new {
@include diff_background(rgba(166, 226, 46, 0.2), rgba(166, 226, 46, 0.3), #808080);
}
.diff-line-num.old, .line_content.old {
@include diff_background(rgba(254, 147, 140, 0.2), rgba(254, 147, 140, 0.3), #808080);
}
.line_content.match {
color: rgba(255, 255, 255, 0.3);
background: rgba(255, 255, 255, 0.1);
}
}
// highlight line via anchor // highlight line via anchor
pre .hll { pre .hll {
background-color: #49483e !important; background-color: #49483e !important;
...@@ -90,22 +110,4 @@ ...@@ -90,22 +110,4 @@
.gu { color: #75715e; } /* Generic.Subheading & Diff Unified/Comment? */ .gu { color: #75715e; } /* Generic.Subheading & Diff Unified/Comment? */
.gd { color: #f92672; } /* Generic.Deleted & Diff Deleted */ .gd { color: #f92672; } /* Generic.Deleted & Diff Deleted */
.gi { color: #a6e22e; } /* Generic.Inserted & Diff Inserted */ .gi { color: #a6e22e; } /* Generic.Inserted & Diff Inserted */
.line_holder {
&.parallel .new.new_line,
&.parallel .new.line_content,
&.new .old_line,
&.new .new_line,
&.new .line_content {
@include diff_background(156, 175, 183, #808080);
}
&.parallel .old.old_line,
&.parallel .old.line_content,
&.old .old_line,
&.old .new_line,
&.old .line_content {
@include diff_background(254, 147, 140, #808080);
}
}
} }
/* https://gist.github.com/qguv/7936275 */ /* https://gist.github.com/qguv/7936275 */
.code.solarized-dark { .code.solarized-dark {
// Line numbers
.line-numbers, .diff-line-num {
background-color: #002b36;
}
background-color: #002b36 !important; .diff-line-num, .diff-line-num a {
color: #93a1a1 !important; color: rgba(255, 255, 255, 0.3);
pre.highlight,
.line-numbers,
.line-numbers a {
background-color: #002b36 !important;
color: #93a1a1 !important;
} }
// Code itself
pre.code { pre.code {
border-left: 1px solid #113b46; border-left: 1px solid #113b46;
} }
&, pre.code, .line_holder .line_content {
background-color: #002b36;
color: #93a1a1;
}
// Diff line
.line_holder {
.diff-line-num.new, .line_content.new {
@include diff_background(rgba(133, 153, 0, 0.2), rgba(133, 153, 0, 0.3), #808080);
}
.diff-line-num.old, .line_content.old {
@include diff_background(rgba(220, 50, 47, 0.2), rgba(220, 50, 47, 0.3), #808080);
}
.line_content.match {
color: rgba(255, 255, 255, 0.3);
background: rgba(255, 255, 255, 0.1);
}
}
// highlight line via anchor // highlight line via anchor
pre .hll { pre .hll {
background-color: #174652 !important; background-color: #174652 !important;
...@@ -111,22 +131,4 @@ ...@@ -111,22 +131,4 @@
.vg { color: #268bd2 } /* Name.Variable.Global */ .vg { color: #268bd2 } /* Name.Variable.Global */
.vi { color: #268bd2 } /* Name.Variable.Instance */ .vi { color: #268bd2 } /* Name.Variable.Instance */
.il { color: #2aa198 } /* Literal.Number.Integer.Long */ .il { color: #2aa198 } /* Literal.Number.Integer.Long */
.line_holder {
&.parallel .new.new_line,
&.parallel .new.line_content,
&.new .old_line,
&.new .new_line,
&.new .line_content {
@include diff_background(255, 255, 255, #808080);
}
&.parallel .old.old_line,
&.parallel .old.line_content,
&.old .old_line,
&.old .new_line,
&.old .line_content {
@include diff_background(255, 51, 51, #808080);
}
}
} }
/* https://gist.github.com/qguv/7936275 */ /* https://gist.github.com/qguv/7936275 */
.code.solarized-light { .code.solarized-light {
// Line numbers
.line-numbers, .diff-line-num {
background-color: #fdf6e3;
}
background-color: #fdf6e3 !important; .diff-line-num, .diff-line-num a {
color: #586e75 !important; color: rgba(0, 0, 0, 0.3);
pre.highlight,
.line-numbers,
.line-numbers a {
background-color: #fdf6e3 !important;
color: #586e75 !important;
} }
// Code itself
pre.code { pre.code {
border-left: 1px solid #c5d0d4; border-left: 1px solid #c5d0d4;
} }
&, pre.code, .line_holder .line_content {
background-color: #fdf6e3;
color: #586e75;
}
// Diff line
.line_holder {
.diff-line-num.new, .line_content.new {
@include diff_background(rgba(133, 153, 0, 0.2), rgba(133, 153, 0, 0.3), #FAF3DD);
}
.diff-line-num.old, .line_content.old {
@include diff_background(rgba(220, 50, 47, 0.2), rgba(220, 50, 47, 0.3), #FAF3DD);
}
.line_content.match {
color: rgba(0, 0, 0, 0.3);
background: rgba(255, 255, 255, 0.4);
}
}
// highlight line via anchor // highlight line via anchor
pre .hll { pre .hll {
background-color: #ddd8c5 !important; background-color: #ddd8c5 !important;
...@@ -111,23 +131,4 @@ ...@@ -111,23 +131,4 @@
.vg { color: #268bd2 } /* Name.Variable.Global */ .vg { color: #268bd2 } /* Name.Variable.Global */
.vi { color: #268bd2 } /* Name.Variable.Instance */ .vi { color: #268bd2 } /* Name.Variable.Instance */
.il { color: #2aa198 } /* Literal.Number.Integer.Long */ .il { color: #2aa198 } /* Literal.Number.Integer.Long */
.line_holder {
&.parallel .new.new_line,
&.parallel .new.line_content,
&.new .old_line,
&.new .new_line,
&.new .line_content {
@include diff_background(92, 164, 169, #FAF3DD);
}
&.parallel .old.old_line,
&.parallel .old.line_content,
&.old .old_line,
&.old .new_line,
&.old .line_content {
@include diff_background(237, 106, 90, #FAF3DD);
}
}
} }
/* https://github.com/aahan/pygments-github-style */ /* https://github.com/aahan/pygments-github-style */
.code.white { .code.white {
// Line numbers
.line-numbers, .diff-line-num {
background-color: $background-color;
}
background-color: #f8fafc !important; .diff-line-num, .diff-line-num a {
color: #5b6169 !important; color: rgba(0, 0, 0, 0.3);
pre.highlight,
.line-numbers,
.line-numbers a {
background-color: $background-color !important;
color: $gl-gray !important;
} }
// Code itself
pre.code { pre.code {
border-left: 1px solid $border-color; border-left: 1px solid $border-color;
background-color: #fff !important; }
color: #333 !important;
&, pre.code, .line_holder .line_content {
background-color: #fff;
color: #333;
}
// Diff line
.line_holder {
.diff-line-num {
&.old {
background: #ffdddd;
border-color: #f1c0c0;
}
&.new {
background: #dbffdb;
border-color: #c1e9c1;
}
}
.line_content {
&.old {
background: #ffecec;
span.idiff {
background-color: #f8cbcb;
}
}
&.new {
background: #eaffea;
span.idiff {
background-color: #a6f3a6;
}
}
&.match {
color: rgba(0, 0, 0, 0.3);
background: #fafafa;
}
}
} }
// highlight line via anchor // highlight line via anchor
......
...@@ -32,16 +32,6 @@ ...@@ -32,16 +32,6 @@
background: #FFF; background: #FFF;
color: #333; color: #333;
.old {
span.idiff {
background-color: #f8cbcb;
}
}
.new {
span.idiff {
background-color: #a6f3a6;
}
}
.unfold { .unfold {
cursor: pointer; cursor: pointer;
} }
...@@ -76,7 +66,7 @@ ...@@ -76,7 +66,7 @@
} }
tr.line_holder.parallel { tr.line_holder.parallel {
.old_line, .new_line, .diff_line { .old_line, .new_line {
min-width: 50px; min-width: 50px;
} }
...@@ -85,7 +75,7 @@ ...@@ -85,7 +75,7 @@
} }
} }
.old_line, .new_line, .diff_line { .old_line, .new_line {
margin: 0px; margin: 0px;
padding: 0px; padding: 0px;
border: none; border: none;
...@@ -107,43 +97,12 @@ ...@@ -107,43 +97,12 @@
text-decoration: underline; text-decoration: underline;
} }
} }
&.new {
background: #CFD;
}
&.old {
background: #FDD;
}
}
.diff_line {
padding: 0;
}
.line_holder {
&.old .old_line,
&.old .new_line {
background: #ffdddd;
border-color: #f1c0c0;
}
&.new .old_line,
&.new .new_line {
background: #dbffdb;
border-color: #c1e9c1;
}
} }
.line_content { .line_content {
display: block; display: block;
margin: 0px; margin: 0px;
padding: 0px 0.5em; padding: 0px 0.5em;
border: none; border: none;
&.new {
background: #eaffea;
}
&.old {
background: #ffecec;
}
&.matched {
color: $border-color;
background: #fafafa;
}
&.parallel { &.parallel {
display: table-cell; display: table-cell;
} }
...@@ -394,17 +353,14 @@ ...@@ -394,17 +353,14 @@
} }
} }
@mixin diff_background($r, $g, $b, $custom-border) { @mixin diff_background($background, $idiff, $border) {
/* Fallback for web browsers that doesn't support RGBa */ background: $background;
background: rgb($r, $g, $b);
/* RGBa with 0.3 opacity */
background: rgba($r, $g, $b, 0.3);
&.new_line, &.old_line { &.line_content span.idiff {
border-right-color: $custom-border !important; background: $idiff;
} }
&.line_content span.idiff { &.diff-line-num {
background: rgb($r, $g, $b); border-color: $border;
} }
} }
...@@ -10,18 +10,6 @@ ...@@ -10,18 +10,6 @@
margin: 10px $gl-padding; margin: 10px $gl-padding;
} }
.diff-file .diff-content { .diff-file .diff-content {
tr.line_holder:hover {
&> td.line_content {
background: $hover !important;
border-color: darken($hover, 10%) !important;
}
&> td.new_line,
&> td.old_line {
background: darken($hover, 4%) !important;
border-color: darken($hover, 10%) !important;
}
}
tr.line_holder:hover > td .line_note_link { tr.line_holder:hover > td .line_note_link {
opacity: 1.0; opacity: 1.0;
filter: alpha(opacity=100); filter: alpha(opacity=100);
......
...@@ -242,11 +242,8 @@ ul.notes { ...@@ -242,11 +242,8 @@ ul.notes {
// "show" the icon also if we just hover somewhere over the line // "show" the icon also if we just hover somewhere over the line
&:hover > td { &:hover > td {
background: $hover !important;
.add-diff-note { .add-diff-note {
@include show-add-diff-note; @include show-add-diff-note;
} }
} }
} }
...@@ -97,7 +97,7 @@ module CreatesCommit ...@@ -97,7 +97,7 @@ module CreatesCommit
# Merge request from fork to this project # Merge request from fork to this project
@mr_source_project = @tree_edit_project @mr_source_project = @tree_edit_project
@mr_target_project = @project @mr_target_project = @project
@mr_target_branch = @mr_target_project.repository.root_ref @mr_target_branch = @ref
end end
end end
end end
...@@ -52,7 +52,9 @@ class Projects::BlobController < Projects::ApplicationController ...@@ -52,7 +52,9 @@ class Projects::BlobController < Projects::ApplicationController
def preview def preview
@content = params[:content] @content = params[:content]
diffy = Diffy::Diff.new(@blob.data, @content, diff: '-U 3', include_diff_info: true) diffy = Diffy::Diff.new(@blob.data, @content, diff: '-U 3', include_diff_info: true)
@diff_lines = Gitlab::Diff::Parser.new.parse(diffy.diff.scan(/.*\n/)) diff_lines = diffy.diff.scan(/.*\n/)[2..-1]
diff_lines = Gitlab::Diff::Parser.new.parse(diff_lines)
@diff_lines = Gitlab::Diff::Highlight.new(diff_lines).highlight
render layout: false render layout: false
end end
......
...@@ -26,10 +26,10 @@ module BlobHelper ...@@ -26,10 +26,10 @@ module BlobHelper
tree_join(ref, path), tree_join(ref, path),
link_opts) link_opts)
if !on_top_of_branch? if !on_top_of_branch?(project, ref)
button_tag "Edit", class: "btn btn-default disabled has_tooltip", title: "You can only edit files when you are on a branch", data: { container: 'body' } button_tag "Edit", class: "btn btn-default disabled has_tooltip", title: "You can only edit files when you are on a branch", data: { container: 'body' }
elsif can_edit_blob?(blob) elsif can_edit_blob?(blob, project, ref)
link_to "Edit", edit_path, class: 'btn btn-small' link_to "Edit", edit_path, class: 'btn'
elsif can?(current_user, :fork_project, project) elsif can?(current_user, :fork_project, project)
continue_params = { continue_params = {
to: edit_path, to: edit_path,
...@@ -39,7 +39,7 @@ module BlobHelper ...@@ -39,7 +39,7 @@ module BlobHelper
fork_path = namespace_project_fork_path(project.namespace, project, namespace_key: current_user.namespace.id, fork_path = namespace_project_fork_path(project.namespace, project, namespace_key: current_user.namespace.id,
continue: continue_params) continue: continue_params)
link_to "Edit", fork_path, class: 'btn btn-small', method: :post link_to "Edit", fork_path, class: 'btn', method: :post
end end
end end
...@@ -50,11 +50,11 @@ module BlobHelper ...@@ -50,11 +50,11 @@ module BlobHelper
return unless blob return unless blob
if !on_top_of_branch? if !on_top_of_branch?(project, ref)
button_tag label, class: "btn btn-#{btn_class} disabled has_tooltip", title: "You can only #{action} files when you are on a branch", data: { container: 'body' } button_tag label, class: "btn btn-#{btn_class} disabled has_tooltip", title: "You can only #{action} files when you are on a branch", data: { container: 'body' }
elsif blob.lfs_pointer? elsif blob.lfs_pointer?
button_tag label, class: "btn btn-#{btn_class} disabled has_tooltip", title: "It is not possible to #{action} files that are stored in LFS using the web interface", data: { container: 'body' } button_tag label, class: "btn btn-#{btn_class} disabled has_tooltip", title: "It is not possible to #{action} files that are stored in LFS using the web interface", data: { container: 'body' }
elsif can_edit_blob?(blob) elsif can_edit_blob?(blob, project, ref)
button_tag label, class: "btn btn-#{btn_class}", 'data-target' => "#modal-#{modal_type}-blob", 'data-toggle' => 'modal' button_tag label, class: "btn btn-#{btn_class}", 'data-target' => "#modal-#{modal_type}-blob", 'data-toggle' => 'modal'
elsif can?(current_user, :fork_project, project) elsif can?(current_user, :fork_project, project)
continue_params = { continue_params = {
......
...@@ -166,7 +166,7 @@ module CommitsHelper ...@@ -166,7 +166,7 @@ module CommitsHelper
link_to( link_to(
namespace_project_blob_path(project.namespace, project, namespace_project_blob_path(project.namespace, project,
tree_join(commit_sha, diff.new_path)), tree_join(commit_sha, diff.new_path)),
class: 'btn btn-small view-file js-view-file' class: 'btn view-file js-view-file'
) do ) do
raw('View file @') + content_tag(:span, commit_sha[0..6], raw('View file @') + content_tag(:span, commit_sha[0..6],
class: 'commit-short-id') class: 'commit-short-id')
......
...@@ -347,17 +347,17 @@ module Ci ...@@ -347,17 +347,17 @@ module Ci
end end
def artifacts_browse_url def artifacts_browse_url
if artifacts_browser_supported? if artifacts_metadata?
browse_namespace_project_build_artifacts_path(project.namespace, project, self) browse_namespace_project_build_artifacts_path(project.namespace, project, self)
end end
end end
def artifacts_browser_supported? def artifacts_metadata?
artifacts? && artifacts_metadata.exists? artifacts? && artifacts_metadata.exists?
end end
def artifacts_metadata_entry(path) def artifacts_metadata_entry(path, **options)
Gitlab::Ci::Build::Artifacts::Metadata.new(artifacts_metadata.path, path).to_entry Gitlab::Ci::Build::Artifacts::Metadata.new(artifacts_metadata.path, path, **options).to_entry
end end
private private
......
...@@ -84,7 +84,7 @@ class ProjectMember < Member ...@@ -84,7 +84,7 @@ class ProjectMember < Member
def truncate_teams(project_ids) def truncate_teams(project_ids)
ProjectMember.transaction do ProjectMember.transaction do
members = ProjectMember.where(source_id: project_ids) members = ProjectMember.where(source_id: project_ids)
members.each do |member| members.each do |member|
member.destroy member.destroy
end end
...@@ -133,7 +133,7 @@ class ProjectMember < Member ...@@ -133,7 +133,7 @@ class ProjectMember < Member
event_service.join_project(self.project, self.user) event_service.join_project(self.project, self.user)
notification_service.new_project_member(self) unless @skip_notification notification_service.new_project_member(self) unless @skip_notification
end end
super super
end end
......
...@@ -246,7 +246,7 @@ class Note < ActiveRecord::Base ...@@ -246,7 +246,7 @@ class Note < ActiveRecord::Base
prev_match_line = nil prev_match_line = nil
prev_lines = [] prev_lines = []
diff_lines.each do |line| highlighted_diff_lines.each do |line|
if line.type == "match" if line.type == "match"
prev_lines.clear prev_lines.clear
prev_match_line = line prev_match_line = line
...@@ -263,7 +263,11 @@ class Note < ActiveRecord::Base ...@@ -263,7 +263,11 @@ class Note < ActiveRecord::Base
end end
def diff_lines def diff_lines
@diff_lines ||= Gitlab::Diff::Parser.new.parse(diff.diff.lines.to_a) @diff_lines ||= Gitlab::Diff::Parser.new.parse(diff.diff.lines)
end
def highlighted_diff_lines
Gitlab::Diff::Highlight.new(diff_lines).highlight
end end
def discussion_id def discussion_id
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
.top-block.gray-content-block.clearfix .top-block.gray-content-block.clearfix
.pull-right .pull-right
= link_to download_namespace_project_build_artifacts_path(@project.namespace, @project, @build), = link_to download_namespace_project_build_artifacts_path(@project.namespace, @project, @build),
class: 'btn btn-default' do class: 'btn btn-default download' do
= icon('download') = icon('download')
Download artifacts archive Download artifacts archive
...@@ -20,12 +20,3 @@ ...@@ -20,12 +20,3 @@
- if @entry.empty? - if @entry.empty?
.center Empty .center Empty
:javascript
$('.tree-holder').on('click', 'tr[data-link] a', function(e) {
e.stopImmediatePropagation();
});
$('.tree-holder').on('click', 'tr[data-link]', function(e) {
window.location = this.dataset.link;
});
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
%small= number_to_human_size @blob.size %small= number_to_human_size @blob.size
.file-actions .file-actions
= render "projects/blob/actions" = render "projects/blob/actions"
.file-content.blame.highlight .file-content.blame.code.js-syntax-highlight
%table %table
- current_line = 1 - current_line = 1
- blame_highlighter = highlighter(@blob.name, @blob.data, nowrap: true) - blame_highlighter = highlighter(@blob.name, @blob.data, nowrap: true)
...@@ -31,15 +31,14 @@ ...@@ -31,15 +31,14 @@
= commit_author_link(commit, avatar: false) = commit_author_link(commit, avatar: false)
authored authored
#{time_ago_with_tooltip(commit.committed_date, skip_js: true)} #{time_ago_with_tooltip(commit.committed_date, skip_js: true)}
%td.lines.blame-numbers %td.line-numbers
%pre - line_count = blame_group[:lines].count
- line_count = blame_group[:lines].count - (current_line...(current_line + line_count)).each do |i|
- (current_line...(current_line + line_count)).each do |i| %a.diff-line-num= i
= i \
\ - current_line += line_count
- current_line += line_count
%td.lines %td.lines
%pre{class: 'code highlight white'} %pre{class: 'code highlight'}
%code %code
- blame_group[:lines].each do |line| - blame_group[:lines].each do |line|
:preserve :preserve
......
...@@ -10,7 +10,8 @@ ...@@ -10,7 +10,8 @@
%tr.line_holder %tr.line_holder
%td.old_line.diff-line-num{data: {linenumber: line_old}} %td.old_line.diff-line-num{data: {linenumber: line_old}}
= link_to raw(line_old), "#" = link_to raw(line_old), "#"
%td.new_line= link_to raw(line_new) , "#" %td.new_line.diff-line-num
= link_to raw(line_new) , "#"
%td.line_content.noteable_line==#{' ' * @form.indent}#{line} %td.line_content.noteable_line==#{' ' * @form.indent}#{line}
- if @form.unfold? && @form.bottom? && @form.to < @blob.loc - if @form.unfold? && @form.bottom? && @form.to < @blob.loc
......
...@@ -14,12 +14,12 @@ ...@@ -14,12 +14,12 @@
- @diff_lines.each do |line| - @diff_lines.each do |line|
%tr.line_holder{ class: "#{line.type}" } %tr.line_holder{ class: "#{line.type}" }
- if line.type == "match" - if line.type == "match"
%td.old_line= "..." %td.old_line.diff-line-num= "..."
%td.new_line= "..." %td.new_line.diff-line-num= "..."
%td.line_content.matched= line.text %td.line_content.match= line.text
- else - else
%td.old_line %td.old_line.diff-line-num
%td.new_line %td.new_line.diff-line-num
%td.line_content{class: "#{line.type}"}= diff_line_content(line.text) %td.line_content{class: "#{line.type}"}= diff_line_content(line.text)
- else - else
.nothing-here-block No changes. .nothing-here-block No changes.
...@@ -96,7 +96,7 @@ ...@@ -96,7 +96,7 @@
.center .center
.btn-group{ role: :group } .btn-group{ role: :group }
= link_to "Download", @build.artifacts_download_url, class: 'btn btn-sm btn-primary' = link_to "Download", @build.artifacts_download_url, class: 'btn btn-sm btn-primary'
- if @build.artifacts_browser_supported? - if @build.artifacts_metadata?
= link_to "Browse", @build.artifacts_browse_url, class: 'btn btn-sm btn-primary' = link_to "Browse", @build.artifacts_browse_url, class: 'btn btn-sm btn-primary'
.build-widget .build-widget
......
.diff-file{id: "diff-#{i}", data: diff_file_html_data(project, diff_commit, diff_file)} .diff-file.file-holder{id: "diff-#{i}", data: diff_file_html_data(project, diff_commit, diff_file)}
.diff-header{id: "file-path-#{hexdigest(diff_file.file_path)}"} .file-title{id: "file-path-#{hexdigest(diff_file.file_path)}"}
- if diff_file.diff.submodule? - if diff_file.diff.submodule?
%span %span
= icon('archive fw') = icon('archive fw')
%strong %strong
= submodule_link(blob, @commit.id, project.repository) = submodule_link(blob, @commit.id, project.repository)
- else - else
%span = blob_icon blob.mode, blob.name
= blob_icon blob.mode, blob.name = link_to "#diff-#{i}" do
= link_to "#diff-#{i}" do %strong
%strong = diff_file.new_path
= diff_file.new_path
- if diff_file.deleted_file - if diff_file.deleted_file
deleted deleted
- elsif diff_file.renamed_file - elsif diff_file.renamed_file
renamed from renamed from
%strong %strong
= diff_file.old_path = diff_file.old_path
- if diff_file.mode_changed? - if diff_file.mode_changed?
%small %small
= "#{diff_file.diff.a_mode}#{diff_file.diff.b_mode}" = "#{diff_file.diff.a_mode}#{diff_file.diff.b_mode}"
.diff-controls .file-actions.hidden-xs
- if blob_text_viewable?(blob) - if blob_text_viewable?(blob)
= link_to '#', class: 'js-toggle-diff-comments btn btn-sm active has_tooltip', title: "Toggle comments for this file" do = link_to '#', class: 'js-toggle-diff-comments btn active has_tooltip', title: "Toggle comments for this file" do
%i.fa.fa-comments = icon('comments')
&nbsp; \
- if editable_diff?(diff_file) - if editable_diff?(diff_file)
= edit_blob_link(@merge_request.source_project, = edit_blob_link(@merge_request.source_project,
@merge_request.source_branch, diff_file.new_path, @merge_request.source_branch, diff_file.new_path,
from_merge_request_id: @merge_request.id) from_merge_request_id: @merge_request.id)
&nbsp;
= view_file_btn(diff_commit.id, diff_file, project) = view_file_btn(diff_commit.id, diff_file, project)
......
...@@ -4,4 +4,4 @@ ...@@ -4,4 +4,4 @@
%td.new_line.diff-line-num{data: {linenumber: line_new}, %td.new_line.diff-line-num{data: {linenumber: line_new},
class: [unfold_bottom_class(bottom), unfold_class(!new_file)]} class: [unfold_bottom_class(bottom), unfold_class(!new_file)]}
\... \...
%td.line_content.matched= line %td.line_content.match= line
%td.old_line %td.old_line.diff-line-num
%td.line_content.parallel.matched= line %td.line_content.parallel.match= line
%td.new_line %td.new_line.diff-line-num
%td.line_content.parallel.matched= line %td.line_content.parallel.match= line
...@@ -9,16 +9,16 @@ ...@@ -9,16 +9,16 @@
= render "projects/diffs/match_line_parallel", { line: left[:text], = render "projects/diffs/match_line_parallel", { line: left[:text],
line_old: left[:number], line_new: right[:number] } line_old: left[:number], line_new: right[:number] }
- elsif left[:type] == 'nonewline' - elsif left[:type] == 'nonewline'
%td.old_line %td.old_line.diff-line-num
%td.line_content.parallel.matched= left[:text] %td.line_content.parallel.match= left[:text]
%td.new_line %td.new_line.diff-line-num
%td.line_content.parallel.matched= left[:text] %td.line_content.parallel.match= left[:text]
- else - else
%td.old_line{id: left[:line_code], class: "#{left[:type]}"} %td.old_line.diff-line-num{id: left[:line_code], class: "#{left[:type]}"}
= link_to raw(left[:number]), "##{left[:line_code]}", id: left[:line_code] = link_to raw(left[:number]), "##{left[:line_code]}", id: left[:line_code]
- if @comments_allowed && can?(current_user, :create_note, @project) - if @comments_allowed && can?(current_user, :create_note, @project)
= link_to_new_diff_note(left[:line_code], 'old') = link_to_new_diff_note(left[:line_code], 'old')
%td.line_content{class: "parallel noteable_line #{left[:type]} #{left[:line_code]}", data: { line_code: left[:line_code] }}= diff_line_content(left[:text]) %td.line_content{class: "parallel noteable_line #{left[:type]} #{left[:line_code]}", data: { line_code: left[:line_code] }}= diff_line_content(left[:text])
- if right[:type] == 'new' - if right[:type] == 'new'
- new_line_class = 'new' - new_line_class = 'new'
...@@ -27,11 +27,11 @@ ...@@ -27,11 +27,11 @@
- new_line_class = nil - new_line_class = nil
- new_line_code = left[:line_code] - new_line_code = left[:line_code]
%td.new_line{id: new_line_code, class: "#{new_line_class}", data: { linenumber: right[:number] }} %td.new_line.diff-line-num{id: new_line_code, class: "#{new_line_class}", data: { linenumber: right[:number] }}
= link_to raw(right[:number]), "##{new_line_code}", id: new_line_code = link_to raw(right[:number]), "##{new_line_code}", id: new_line_code
- if @comments_allowed && can?(current_user, :create_note, @project) - if @comments_allowed && can?(current_user, :create_note, @project)
= link_to_new_diff_note(right[:line_code], 'new') = link_to_new_diff_note(right[:line_code], 'new')
%td.line_content.parallel{class: "noteable_line #{new_line_class} #{new_line_code}", data: { line_code: new_line_code }}= diff_line_content(right[:text]) %td.line_content.parallel{class: "noteable_line #{new_line_class} #{new_line_code}", data: { line_code: new_line_code }}= diff_line_content(right[:text])
- if @reply_allowed - if @reply_allowed
- comments_left, comments_right = organize_comments(left[:type], right[:type], left[:line_code], right[:line_code]) - comments_left, comments_right = organize_comments(left[:type], right[:type], left[:line_code], right[:line_code])
......
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
%table.text-file.code.js-syntax-highlight{ class: too_big ? 'hide' : '' } %table.text-file.code.js-syntax-highlight{ class: too_big ? 'hide' : '' }
- last_line = 0 - last_line = 0
- raw_diff_lines = diff_file.diff_lines
- diff_file.highlighted_diff_lines.each_with_index do |line, index| - diff_file.highlighted_diff_lines.each_with_index do |line, index|
- type = line.type - type = line.type
- last_line = line.new_pos - last_line = line.new_pos
...@@ -18,20 +19,20 @@ ...@@ -18,20 +19,20 @@
- elsif type == 'nonewline' - elsif type == 'nonewline'
%td.old_line.diff-line-num %td.old_line.diff-line-num
%td.new_line.diff-line-num %td.new_line.diff-line-num
%td.line_content.matched= line.text %td.line_content.match= line.text
- else - else
%td.old_line %td.old_line.diff-line-num{class: type}
= link_to raw(type == "new" ? "&nbsp;" : line_old), "##{line_code}", id: line_code = link_to raw(type == "new" ? "&nbsp;" : line_old), "##{line_code}", id: line_code
- if @comments_allowed && can?(current_user, :create_note, @project) - if @comments_allowed && can?(current_user, :create_note, @project)
= link_to_new_diff_note(line_code) = link_to_new_diff_note(line_code)
%td.new_line{data: {linenumber: line.new_pos}} %td.new_line.diff-line-num{class: type, data: {linenumber: line.new_pos}}
= link_to raw(type == "old" ? "&nbsp;" : line.new_pos), "##{line_code}", id: line_code = link_to raw(type == "old" ? "&nbsp;" : line.new_pos), "##{line_code}", id: line_code
%td.line_content{class: "noteable_line #{type} #{line_code}", data: { line_code: line_code }}= diff_line_content(line.text) %td.line_content{class: "noteable_line #{type} #{line_code}", data: { line_code: line_code }}= diff_line_content(line.text)
- if @reply_allowed - if @reply_allowed
- comments = @line_notes.select { |n| n.line_code == line_code && n.active? }.sort_by(&:created_at) - comments = @line_notes.select { |n| n.line_code == line_code && n.active? }.sort_by(&:created_at)
- unless comments.empty? - unless comments.empty?
= render "projects/notes/diff_notes_with_reply", notes: comments, line: line.text = render "projects/notes/diff_notes_with_reply", notes: comments, line: raw_diff_lines[index].text
- if last_line > 0 - if last_line > 0
= render "projects/diffs/match_line", {line: "", = render "projects/diffs/match_line", {line: "",
......
...@@ -16,13 +16,13 @@ ...@@ -16,13 +16,13 @@
- line_code = generate_line_code(note.file_path, line) - line_code = generate_line_code(note.file_path, line)
%tr.line_holder{ id: line_code, class: "#{type}" } %tr.line_holder{ id: line_code, class: "#{type}" }
- if type == "match" - if type == "match"
%td.old_line= "..." %td.old_line.diff-line-num= "..."
%td.new_line= "..." %td.new_line.diff-line-num= "..."
%td.line_content.matched= line.text %td.line_content.match= line.text
- else - else
%td.old_line %td.old_line.diff-line-num
= raw(type == "new" ? "&nbsp;" : line.old_pos) = raw(type == "new" ? "&nbsp;" : line.old_pos)
%td.new_line %td.new_line.diff-line-num
= raw(type == "old" ? "&nbsp;" : line.new_pos) = raw(type == "old" ? "&nbsp;" : line.new_pos)
%td.line_content{class: "noteable_line #{type} #{line_code}", line_code: line_code}= diff_line_content(line.text) %td.line_content{class: "noteable_line #{type} #{line_code}", line_code: line_code}= diff_line_content(line.text)
......
...@@ -22,29 +22,27 @@ ...@@ -22,29 +22,27 @@
.file-content.code .file-content.code
.nothing-here-block Empty file .nothing-here-block Empty file
- else - else
.file-content.code .file-content.code.js-syntax-highlight
%div.highlighted-data{ class: user_color_scheme } .line-numbers
.line-numbers - snippet_blob[:snippet_chunks].each do |snippet|
- unless snippet[:data].empty?
- snippet[:data].lines.to_a.size.times do |index|
- offset = defined?(snippet[:start_line]) ? snippet[:start_line] : 1
- i = index + offset
= link_to snippet_path+"#L#{i}", id: "L#{i}", rel: "#L#{i}", class: "diff-line-num" do
%i.fa.fa-link
= i
- unless snippet == snippet_blob[:snippet_chunks].last
%a.diff-line-num
= "."
%pre.code
%code
- snippet_blob[:snippet_chunks].each do |snippet| - snippet_blob[:snippet_chunks].each do |snippet|
- unless snippet[:data].empty? - unless snippet[:data].empty?
- snippet[:data].lines.to_a.size.times do |index| = snippet[:data]
- offset = defined?(snippet[:start_line]) ? snippet[:start_line] : 1
- i = index + offset
= link_to snippet_path+"#L#{i}", id: "L#{i}", rel: "#L#{i}" do
%i.fa.fa-link
= i
- unless snippet == snippet_blob[:snippet_chunks].last - unless snippet == snippet_blob[:snippet_chunks].last
%a %a
= "." = "..."
.highlight.term - else
%pre .file-content.code
%code .nothing-here-block Empty file
- snippet_blob[:snippet_chunks].each do |snippet|
- unless snippet[:data].empty?
= snippet[:data]
- unless snippet == snippet_blob[:snippet_chunks].last
%a
= "..."
- else
.file-content.code
.nothing-here-block Empty file
.file-content.code.js-syntax-highlight{ class: user_color_scheme } .file-content.code.js-syntax-highlight
.line-numbers .line-numbers
- if blob.data.present? - if blob.data.present?
- blob.data.lines.each_index do |index| - blob.data.lines.each_index do |index|
- offset = defined?(first_line_number) ? first_line_number : 1 - offset = defined?(first_line_number) ? first_line_number : 1
- i = index + offset - i = index + offset
-# We're not using `link_to` because it is too slow once we get to thousands of lines. -# We're not using `link_to` because it is too slow once we get to thousands of lines.
%a{href: "#L#{i}", id: "L#{i}", 'data-line-number' => i} %a.diff-line-num{href: "#L#{i}", id: "L#{i}", 'data-line-number' => i}
%i.fa.fa-link %i.fa.fa-link
= i = i
.blob-content{data: {blob_id: blob.id}} .blob-content{data: {blob_id: blob.id}}
......
...@@ -32,6 +32,7 @@ ...@@ -32,6 +32,7 @@
- [User permissions](ci/permissions/README.md) - [User permissions](ci/permissions/README.md)
- [API](ci/api/README.md) - [API](ci/api/README.md)
- [Triggering builds through the API](ci/triggers/README.md) - [Triggering builds through the API](ci/triggers/README.md)
- [Build artifacts](ci/build_artifacts/README.md)
### CI Languages ### CI Languages
...@@ -60,6 +61,7 @@ ...@@ -60,6 +61,7 @@
- [Git Hooks](git_hooks/git_hooks.md) Advanced push rules for your project. - [Git Hooks](git_hooks/git_hooks.md) Advanced push rules for your project.
- [Help message](customization/help_message.md) Set information about administrators of your GitLab instance. - [Help message](customization/help_message.md) Set information about administrators of your GitLab instance.
- [Install](install/README.md) Requirements, directory structures and installation from source. - [Install](install/README.md) Requirements, directory structures and installation from source.
- [Restart GitLab](administration/restart_gitlab.md) Learn how to restart GitLab and its components
- [Installing your license](license/README.md) - [Installing your license](license/README.md)
- [Integration](integration/README.md) How to integrate with systems such as JIRA, Redmine, LDAP and Twitter. - [Integration](integration/README.md) How to integrate with systems such as JIRA, Redmine, LDAP and Twitter.
- [Issue closing](customization/issue_closing.md) Customize how to close an issue from commit messages. - [Issue closing](customization/issue_closing.md) Customize how to close an issue from commit messages.
...@@ -76,6 +78,7 @@ ...@@ -76,6 +78,7 @@
- [Migrate GitLab CI to CE/EE](migrate_ci_to_ce/README.md) Follow this guide to migrate your existing GitLab CI data to GitLab CE/EE. - [Migrate GitLab CI to CE/EE](migrate_ci_to_ce/README.md) Follow this guide to migrate your existing GitLab CI data to GitLab CE/EE.
- [Downgrade back to CE](downgrade_ee_to_ce/README.md) Follow this guide if you need to downgrade from EE to CE. - [Downgrade back to CE](downgrade_ee_to_ce/README.md) Follow this guide if you need to downgrade from EE to CE.
- [Git LFS configuration](workflow/lfs/lfs_administration.md) - [Git LFS configuration](workflow/lfs/lfs_administration.md)
- [Housekeeping](administration/housekeeping.md) Keep your Git repository tidy and fast.
- [GitLab Pages configuration](pages/administration.md) - [GitLab Pages configuration](pages/administration.md)
- [Elasticsearch (EE-only)](integration/elasticsearch.md) Enable Elasticsearch - [Elasticsearch (EE-only)](integration/elasticsearch.md) Enable Elasticsearch
- [GitLab Performance Monitoring](monitoring/performance/introduction.md) Configure GitLab and InfluxDB for measuring performance metrics - [GitLab Performance Monitoring](monitoring/performance/introduction.md) Configure GitLab and InfluxDB for measuring performance metrics
......
# Housekeeping
_**Note:** This feature was [introduced][ce-2371] in GitLab 8.4_
---
The housekeeping function runs [`git gc`][man] on the current project Git
repository.
`git gc` runs a number of housekeeping tasks, such as compressing file
revisions (to reduce disk space and increase performance) and removing
unreachable objects which may have been created from prior invocations of
`git add`.
You can find this option under your **[Project] > Settings**.
---
![Housekeeping settings](img/housekeeping_settings.png)
[ce-2371]: https://gitlab.com/gitlab-org/gitlab-ce/merge_requests/2371 "Housekeeping merge request"
[man]: https://www.kernel.org/pub/software/scm/git/docs/git-gc.html "git gc man page"
# How to restart GitLab
Depending on how you installed GitLab, there are different methods to restart
its service(s).
If you want the TL;DR versions, jump to:
- [Omnibus GitLab restart](#omnibus-gitlab-restart)
- [Omnibus GitLab reconfigure](#omnibus-gitlab-reconfigure)
- [Source installation restart](#installations-from-source)
## Omnibus installations
If you have used the [Omnibus packages][omnibus-dl] to install GitLab, then
you should already have `gitlab-ctl` in your `PATH`.
`gitlab-ctl` interacts with the Omnibus packages and can be used to restart the
GitLab Rails application (Unicorn) as well as the other components, like:
- GitLab Workhorse
- Sidekiq
- PostgreSQL (if you are using the bundled one)
- NGINX (if you are using the bundled one)
- Redis (if you are using the bundled one)
- [Mailroom][]
- Logrotate
### Omnibus GitLab restart
There may be times in the documentation where you will be asked to _restart_
GitLab. In that case, you need to run the following command:
```bash
sudo gitlab-ctl restart
```
The output should be similar to this:
```
ok: run: gitlab-workhorse: (pid 11291) 1s
ok: run: logrotate: (pid 11299) 0s
ok: run: mailroom: (pid 11306) 0s
ok: run: nginx: (pid 11309) 0s
ok: run: postgresql: (pid 11316) 1s
ok: run: redis: (pid 11325) 0s
ok: run: sidekiq: (pid 11331) 1s
ok: run: unicorn: (pid 11338) 0s
```
To restart a component separately, you can append its service name to the
`restart` command. For example, to restart **only** NGINX you would run:
```bash
sudo gitlab-ctl restart nginx
```
To check the status of GitLab services, run:
```bash
sudo gitlab-ctl status
```
Notice that all services say `ok: run`.
Sometimes, components time out during the restart and sometimes they get stuck.
In that case, you can use `gitlab-ctl kill <service>` to send the `SIGKILL`
signal to the service, for example `sidekiq`. After that, a restart should
perform fine.
As a last resort, you can try to
[reconfigure GitLab](#omnibus-gitlab-reconfigure) instead.
### Omnibus GitLab reconfigure
There may be times in the documentation where you will be asked to _reconfigure_
GitLab. Remember that this method applies only for the Omnibus packages.
Reconfigure Omnibus GitLab with:
```bash
sudo gitlab-ctl reconfigure
```
Reconfiguring GitLab should occur in the event that something in its
configuration (`/etc/gitlab/gitlab.rb`) has changed.
When you run this command, [Chef], the underlying configuration management
application that powers Omnibus GitLab, will make sure that all directories,
permissions, services, etc., are in place and in the same shape that they were
initially shipped.
It will also restart GitLab components where needed, if any of their
configuration files have changed.
If you manually edit any files in `/var/opt/gitlab` that are managed by Chef,
running reconfigure will revert the changes AND restart the services that
depend on those files.
## Installations from source
If you have followed the official installation guide to [install GitLab from
source][install], run the following command to restart GitLab:
```
sudo service gitlab restart
```
The output should be similar to this:
```
Shutting down GitLab Unicorn
Shutting down GitLab Sidekiq
Shutting down GitLab Workhorse
Shutting down GitLab MailRoom
...
GitLab is not running.
Starting GitLab Unicorn
Starting GitLab Sidekiq
Starting GitLab Workhorse
Starting GitLab MailRoom
...
The GitLab Unicorn web server with pid 28059 is running.
The GitLab Sidekiq job dispatcher with pid 28176 is running.
The GitLab Workhorse with pid 28122 is running.
The GitLab MailRoom email processor with pid 28114 is running.
GitLab and all its components are up and running.
```
This should restart Unicorn, Sidekiq, GitLab Workhorse and [Mailroom][]
(if enabled). The init service file that does all the magic can be found on
your server in `/etc/init.d/gitlab`.
---
If you are using other init systems, like systemd, you can check the
[GitLab Recipes][gl-recipes] repository for some unofficial services. These are
**not** officially supported so use them at your own risk.
[omnibus-dl]: https://about.gitlab.com/downloads/ "Download the Omnibus packages"
[install]: ../install/installation.md "Documentation to install GitLab from source"
[mailroom]: ../incoming_email/README.md "Used for replying by email in GitLab issues and merge requests"
[chef]: https://www.chef.io/chef/ "Chef official website"
[src-service]: https://gitlab.com/gitlab-org/gitlab-ce/blob/master/lib/support/init.d/gitlab "GitLab init service file"
[gl-recipes]: https://gitlab.com/gitlab-org/gitlab-recipes/tree/master/init "GitLab Recipes repository"
...@@ -8,10 +8,16 @@ Get a list of repository commits in a project. ...@@ -8,10 +8,16 @@ Get a list of repository commits in a project.
GET /projects/:id/repository/commits GET /projects/:id/repository/commits
``` ```
Parameters: | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project |
| `ref_name` | string | no | The name of a repository branch or tag or if not given the default branch |
```bash
curl -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects/5/repository/commits"
```
- `id` (required) - The ID of a project Example response:
- `ref_name` (optional) - The name of a repository branch or tag or if not given the default branch
```json ```json
[ [
...@@ -48,8 +54,16 @@ GET /projects/:id/repository/commits/:sha ...@@ -48,8 +54,16 @@ GET /projects/:id/repository/commits/:sha
Parameters: Parameters:
- `id` (required) - The ID of a project | Attribute | Type | Required | Description |
- `sha` (required) - The commit hash or name of a repository branch or tag | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project |
| `sha` | string | yes | The commit hash or name of a repository branch or tag |
```bash
curl -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects/5/repository/commits/master
```
Example response:
```json ```json
{ {
...@@ -79,8 +93,16 @@ GET /projects/:id/repository/commits/:sha/diff ...@@ -79,8 +93,16 @@ GET /projects/:id/repository/commits/:sha/diff
Parameters: Parameters:
- `id` (required) - The ID of a project | Attribute | Type | Required | Description |
- `sha` (required) - The name of a repository branch or tag or if not given the default branch | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project |
| `sha` | string | yes | The commit hash or name of a repository branch or tag |
```bash
curl -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects/5/repository/commits/master/diff"
```
Example response:
```json ```json
[ [
...@@ -107,8 +129,16 @@ GET /projects/:id/repository/commits/:sha/comments ...@@ -107,8 +129,16 @@ GET /projects/:id/repository/commits/:sha/comments
Parameters: Parameters:
- `id` (required) - The ID of a project | Attribute | Type | Required | Description |
- `sha` (required) - The name of a repository branch or tag or if not given the default branch | --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project |
| `sha` | string | yes | The commit hash or name of a repository branch or tag |
```bash
curl -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects/5/repository/commits/master/comments"
```
Example response:
```json ```json
[ [
...@@ -128,39 +158,65 @@ Parameters: ...@@ -128,39 +158,65 @@ Parameters:
## Post comment to commit ## Post comment to commit
Adds a comment to a commit. Optionally you can post comments on a specific line of a commit. Therefor both `path`, `line_new` and `line_old` are required. Adds a comment to a commit.
In order to post a comment in a particular line of a particular file, you must
specify the full commit SHA, the `path`, the `line` and `line_type` should be
`new`.
The comment will be added at the end of the last commit if at least one of the
cases below is valid:
- the `sha` is instead a branch or a tag and the `line` or `path` are invalid
- the `line` number is invalid (does not exist)
- the `path` is invalid (does not exist)
In any of the above cases, the response of `line`, `line_type` and `path` is
set to `null`.
``` ```
POST /projects/:id/repository/commits/:sha/comments POST /projects/:id/repository/commits/:sha/comments
``` ```
Parameters: | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project |
| `sha` | string | yes | The commit SHA or name of a repository branch or tag |
| `note` | string | yes | The text of the comment |
| `path` | string | no | The file path relative to the repository |
| `line` | integer | no | The line number where the comment should be placed |
| `line_type` | string | no | The line type. Takes `new` or `old` as arguments |
```bash
curl -X POST -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" -F "note=Nice picture man\!" -F "path=dudeism.md" -F "line=11" -F "line_type=new" https://gitlab.example.com/api/v3/projects/17/repository/commits/18f3e63d05582537db6d183d9d557be09e1f90c8/comments
```
- `id` (required) - The ID of a project Example response:
- `sha` (required) - The name of a repository branch or tag or if not given the default branch
- `note` (required) - Text of comment
- `path` (optional) - The file path
- `line` (optional) - The line number
- `line_type` (optional) - The line type (new or old)
```json ```json
{ {
"author": { "author" : {
"id": 1, "web_url" : "https://gitlab.example.com/u/thedude",
"username": "admin", "avatar_url" : "https://gitlab.example.com/uploads/user/avatar/28/The-Big-Lebowski-400-400.png",
"email": "admin@local.host", "username" : "thedude",
"name": "Administrator", "state" : "active",
"blocked": false, "name" : "Jeff Lebowski",
"created_at": "2012-04-29T08:46:00Z" "id" : 28
}, },
"note": "text1", "created_at" : "2016-01-19T09:44:55.600Z",
"path": "example.rb", "line_type" : "new",
"line": 5, "path" : "dudeism.md",
"line_type": "new" "line" : 11,
"note" : "Nice picture man!"
} }
``` ```
## Get the status of a commit ## Commit status
Since GitLab 8.1, this is the new commit status API. The documentation in
[ci/api/commits](../ci/api/commits.md) is deprecated.
### Get the status of a commit
Get the statuses of a commit in a project. Get the statuses of a commit in a project.
...@@ -168,75 +224,116 @@ Get the statuses of a commit in a project. ...@@ -168,75 +224,116 @@ Get the statuses of a commit in a project.
GET /projects/:id/repository/commits/:sha/statuses GET /projects/:id/repository/commits/:sha/statuses
``` ```
Parameters: | Attribute | Type | Required | Description |
| --------- | ---- | -------- | ----------- |
| `id` | integer | yes | The ID of a project
| `sha` | string | yes | The commit SHA
| `ref_name`| string | no | The name of a repository branch or tag or, if not given, the default branch
| `stage` | string | no | Filter by [build stage](../ci/yaml/README.md#stages), e.g., `test`
| `name` | string | no | Filter by [job name](../ci/yaml/README.md#jobs), e.g., `bundler:audit`
| `all` | boolean | no | Return all statuses, not only the latest ones
```bash
curl -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects/17/repository/commits/18f3e63d05582537db6d183d9d557be09e1f90c8/statuses
```
- `id` (required) - The ID of a project Example response:
- `sha` (required) - The commit SHA
- `ref` (optional) - Filter by ref name, it can be branch or tag
- `stage` (optional) - Filter by stage
- `name` (optional) - Filer by status name, eg. jenkins
- `all` (optional) - The flag to return all statuses, not only latest ones
```json ```json
[ [
{ ...
"id": 13,
"sha": "b0b3a907f41409829b307a28b82fdbd552ee5a27", {
"ref": "test", "status" : "pending",
"status": "success", "created_at" : "2016-01-19T08:40:25.934Z",
"name": "ci/jenkins", "started_at" : null,
"target_url": "http://jenkins/project/url", "name" : "bundler:audit",
"description": "Jenkins success", "allow_failure" : true,
"created_at": "2015-10-12T09:47:16.250Z", "author" : {
"started_at": "2015-10-12T09:47:16.250Z", "username" : "thedude",
"finished_at": "2015-10-12T09:47:16.262Z", "state" : "active",
"author": { "web_url" : "https://gitlab.example.com/u/thedude",
"id": 1, "avatar_url" : "https://gitlab.example.com/uploads/user/avatar/28/The-Big-Lebowski-400-400.png",
"username": "admin", "id" : 28,
"email": "admin@local.host", "name" : "Jeff Lebowski"
"name": "Administrator", },
"blocked": false, "description" : null,
"created_at": "2012-04-29T08:46:00Z" "sha" : "18f3e63d05582537db6d183d9d557be09e1f90c8",
} "target_url" : "https://gitlab.example.com/thedude/gitlab-ce/builds/91",
} "finished_at" : null,
"id" : 91,
"ref" : "master"
},
{
"started_at" : null,
"name" : "flay",
"allow_failure" : false,
"status" : "pending",
"created_at" : "2016-01-19T08:40:25.832Z",
"target_url" : "https://gitlab.example.com/thedude/gitlab-ce/builds/90",
"id" : 90,
"finished_at" : null,
"ref" : "master",
"sha" : "18f3e63d05582537db6d183d9d557be09e1f90c8",
"author" : {
"id" : 28,
"name" : "Jeff Lebowski",
"username" : "thedude",
"web_url" : "https://gitlab.example.com/u/thedude",
"state" : "active",
"avatar_url" : "https://gitlab.example.com/uploads/user/avatar/28/The-Big-Lebowski-400-400.png"
},
"description" : null
},
...
] ]
``` ```
## Post the status to commit ### Post the build status to a commit
Adds or updates a status of a commit. Adds or updates a build status of a commit.
``` ```
POST /projects/:id/statuses/:sha POST /projects/:id/statuses/:sha
``` ```
- `id` (required) - The ID of a project | Attribute | Type | Required | Description |
- `sha` (required) - The commit SHA | --------- | ---- | -------- | ----------- |
- `state` (required) - The state of the status. Can be: pending, running, success, failed, canceled | `id` | integer | yes | The ID of a project
- `ref` (optional) - The ref (branch or tag) to which the status refers | `sha` | string | yes | The commit SHA
- `name` or `context` (optional) - The label to differentiate this status from the status of other systems. Default: "default" | `state` | string | yes | The state of the status. Can be one of the following: `pending`, `running`, `success`, `failed`, `canceled`
- `target_url` (optional) - The target URL to associate with this status | `ref` | string | no | The `ref` (branch or tag) to which the status refers
- `description` (optional) - The short description of the status | `name` or `context` | string | no | The label to differentiate this status from the status of other systems. Default value is `default`
| `target_url` | string | no | The target URL to associate with this status
| `description` | string | no | The short description of the status
```bash
curl -X POST -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" "https://gitlab.example.com/api/v3/projects/17/statuses/18f3e63d05582537db6d183d9d557be09e1f90c8?state=success"
```
Example response:
```json ```json
{ {
"id": 13, "author" : {
"sha": "b0b3a907f41409829b307a28b82fdbd552ee5a27", "web_url" : "https://gitlab.example.com/u/thedude",
"ref": "test", "name" : "Jeff Lebowski",
"status": "success", "avatar_url" : "https://gitlab.example.com/uploads/user/avatar/28/The-Big-Lebowski-400-400.png",
"name": "ci/jenkins", "username" : "thedude",
"target_url": "http://jenkins/project/url", "state" : "active",
"description": "Jenkins success", "id" : 28
"created_at": "2015-10-12T09:47:16.250Z", },
"started_at": "2015-10-12T09:47:16.250Z", "name" : "default",
"finished_at": "2015-10-12T09:47:16.262Z", "sha" : "18f3e63d05582537db6d183d9d557be09e1f90c8",
"author": { "status" : "success",
"id": 1, "description" : null,
"username": "admin", "id" : 93,
"email": "admin@local.host", "target_url" : null,
"name": "Administrator", "ref" : null,
"blocked": false, "started_at" : null,
"created_at": "2012-04-29T08:46:00Z" "created_at" : "2016-01-19T09:05:50.355Z",
} "allow_failure" : false,
"finished_at" : "2016-01-19T09:05:50.365Z"
} }
``` ```
...@@ -12,6 +12,7 @@ ...@@ -12,6 +12,7 @@
* [Using Variables](variables/README.md) * [Using Variables](variables/README.md)
* [Using SSH keys](ssh_keys/README.md) * [Using SSH keys](ssh_keys/README.md)
* [Triggering builds through the API](triggers/README.md) * [Triggering builds through the API](triggers/README.md)
* [Build artifacts](build_artifacts/README.md)
### Languages ### Languages
......
# Commits API # Commits API
**DEPRECATED**
Since GitLab 8.1, there is a new commit status API. Please see the [revised
documentation](../../api/commits.md#commit-status).
---
__Authentication is done by GitLab CI project token__ __Authentication is done by GitLab CI project token__
## Commits ## Commits
......
# Introduction to build artifacts
Artifacts is a list of files and directories which are attached to a build
after it completes successfully.
Since GitLab 8.2 and [GitLab Runner] 0.7.0, build artifacts that are created by
GitLab Runner are uploaded to GitLab and are downloadable as a single archive
(`tar.gz`) using the GitLab UI.
Starting from GitLab 8.4 and GitLab Runner 1.0, the artifacts archive format
changed to `ZIP`, and it is now possible to browse its contents, with the added
ability of downloading the files separately.
## Enabling build artifacts
_If you are searching for ways to use artifacts, jump to
[Defining artifacts in `.gitlab-ci.yml`](#defining-artifacts-in-gitlab-ciyml)._
The artifacts feature is enabled by default in all GitLab installations.
To disable it site-wide, follow the steps below.
---
**In Omnibus installations:**
1. Edit `/etc/gitlab/gitlab.rb` and add the following line:
```ruby
gitlab_rails['artifacts_enabled'] = false
```
1. Save the file and [reconfigure GitLab][] for the changes to take effect.
---
**In installations from source:**
1. Edit `/home/git/gitlab/config/gitlab.yml` and add or amend the following lines:
```yaml
artifacts:
enabled: false
```
1. Save the file and [restart GitLab][] for the changes to take effect.
## Defining artifacts in `.gitlab-ci.yml`
A simple example of using the artifacts definition in `.gitlab-ci.yml` would be
the following:
```yaml
pdf:
script: xelatex mycv.tex
artifacts:
paths:
- mycv.pdf
```
A job named `pdf` calls the `xelatex` command in order to build a pdf file from
the latex source file `mycv.tex`. We then define the `artifacts` paths which in
turn are defined with the `paths` keyword. All paths to files and directories
are relative to the repository that was cloned during the build.
For more examples on artifacts, follow the
[separate artifacts yaml documentation](../yaml/README.md#artifacts).
## Storing build artifacts
After a successful build, GitLab Runner uploads an archive containing the build
artifacts to GitLab.
To change the location where the artifacts are stored, follow the steps below.
---
**In Omnibus installations:**
_The artifacts are stored by default in
`/var/opt/gitlab/gitlab-rails/shared/artifacts`._
1. To change the storage path for example to `/mnt/storage/artifacts`, edit
`/etc/gitlab/gitlab.rb` and add the following line:
```ruby
gitlab_rails['artifacts_path'] = "/mnt/storage/artifacts"
```
1. Save the file and [reconfigure GitLab][] for the changes to take effect.
---
**In installations from source:**
_The artifacts are stored by default in
`/home/git/gitlab/shared/artifacts`._
1. To change the storage path for example to `/mnt/storage/artifacts`, edit
`/home/git/gitlab/config/gitlab.yml` and add or amend the following lines:
```yaml
artifacts:
enabled: true
path: /mnt/storage/artifacts
```
1. Save the file and [restart GitLab][] for the changes to take effect.
## Browsing build artifacts
When GitLab receives an artifacts archive, an archive metadata file is also
generated. This metadata file describes all the entries that are located in the
artifacts archive itself. The metadata file is in a binary format, with
additional GZIP compression.
GitLab does not extract the artifacts archive in order to save space, memory
and disk I/O. It instead inspects the metadata file which contains all the
relevant information. This is especially important when there is a lot of
artifacts, or an archive is a very large file.
---
After a successful build, if you visit the build's specific page, you can see
that there are two buttons.
One is for downloading the artifacts archive and the other for browsing its
contents.
![Build artifacts browser button](img/build_artifacts_browser_button.png)
---
The archive browser shows the name and the actual file size of each file in the
archive. If your artifacts contained directories, then you are also able to
browse inside them.
Below you can see an image of three different file formats, as well as two
directories.
![Build artifacts browser](img/build_artifacts_browser.png)
---
## Downloading build artifacts
If you need to download the whole archive, there are buttons in various places
inside GitLab that make that possible.
1. While on the builds page, you can see the download icon for each build's
artifacts archive in the right corner
1. While inside a specific build, you are presented with a download button
along with the one that browses the archive
1. And finally, when browsing and archive you can see the download button at
the top right corner
---
Note that GitLab does not extract the entire artifacts archive to send just a
single file to the user.
When clicking on a specific file, [GitLab Workhorse] extracts it from the
archive and the download begins.
This implementation saves space, memory and disk I/O.
[gitlab runner]: https://gitlab.com/gitlab-org/gitlab-ci-multi-runner "GitLab Runner repository"
[reconfigure gitlab]: ../../administration/restart_gitlab.md "How to restart GitLab documentation"
[restart gitlab]: ../../administration/restart_gitlab.md "How to restart GitLab documentation"
[gitlab workhorse]: https://gitlab.com/gitlab-org/gitlab-workhorse "GitLab Workhorse repository"
...@@ -12,7 +12,7 @@ configuration from the developer. To overcome this we will be using the ...@@ -12,7 +12,7 @@ configuration from the developer. To overcome this we will be using the
official [PHP docker image][php-hub] that can be found in Docker Hub. official [PHP docker image][php-hub] that can be found in Docker Hub.
This will allow us to test PHP projects against different versions of PHP. This will allow us to test PHP projects against different versions of PHP.
However, not everything is plug 'n' play, you still need to onfigure some However, not everything is plug 'n' play, you still need to configure some
things manually. things manually.
As with every build, you need to create a valid `.gitlab-ci.yml` describing the As with every build, you need to create a valid `.gitlab-ci.yml` describing the
......
...@@ -159,50 +159,55 @@ The `key` directive allows you to define the affinity of caching ...@@ -159,50 +159,55 @@ The `key` directive allows you to define the affinity of caching
between jobs, allowing to have a single cache for all jobs, between jobs, allowing to have a single cache for all jobs,
cache per-job, cache per-branch or any other way you deem proper. cache per-job, cache per-branch or any other way you deem proper.
This allows you to fine tune caching, allowing you to cache data between different jobs or even different branches. This allows you to fine tune caching, allowing you to cache data between
The `cache:key` variable can use any of the [predefined variables](../variables/README.md): different jobs or even different branches.
Example configurations: The `cache:key` variable can use any of the [predefined variables](../variables/README.md).
---
**Example configurations**
To enable per-job caching: To enable per-job caching:
```yaml ```yaml
cache: cache:
key: "$CI_BUILD_NAME" key: "$CI_BUILD_NAME"
untracked: true untracked: true
``` ```
To enable per-branch caching: To enable per-branch caching:
```yaml ```yaml
cache: cache:
key: "$CI_BUILD_REF_NAME" key: "$CI_BUILD_REF_NAME"
untracked: true untracked: true
``` ```
To enable per-job and per-branch caching: To enable per-job and per-branch caching:
```yaml ```yaml
cache: cache:
key: "$CI_BUILD_NAME/$CI_BUILD_REF_NAME" key: "$CI_BUILD_NAME/$CI_BUILD_REF_NAME"
untracked: true untracked: true
``` ```
To enable per-branch and per-stage caching: To enable per-branch and per-stage caching:
```yaml ```yaml
cache: cache:
key: "$CI_BUILD_STAGE/$CI_BUILD_REF_NAME" key: "$CI_BUILD_STAGE/$CI_BUILD_REF_NAME"
untracked: true untracked: true
``` ```
If you use **Windows Batch** to run your shell scripts you need to replace the `$` with `%`: If you use **Windows Batch** to run your shell scripts you need to replace
`$` with `%`:
```yaml ```yaml
cache: cache:
key: "%CI_BUILD_STAGE%/%CI_BUILD_REF_NAME%" key: "%CI_BUILD_STAGE%/%CI_BUILD_REF_NAME%"
untracked: true untracked: true
``` ```
## Jobs ## Jobs
......
...@@ -103,6 +103,23 @@ Inside the document: ...@@ -103,6 +103,23 @@ Inside the document:
`_**Note:** This feature was introduced in GitLab EE 8.3_`. Otherwise, leave `_**Note:** This feature was introduced in GitLab EE 8.3_`. Otherwise, leave
this mention out this mention out
## References
- **GitLab Restart:**
There are many cases that a restart/reconfigure of GitLab is required. To
avoid duplication, link to the special document that can be found in
[`doc/administration/restart_gitlab.md`][doc-restart]. Usually the text will
read like:
```
Save the file and [reconfigure GitLab](../administration/restart_gitlab.md)
for the changes to take effect.
```
If the document you are editing resides in a place other than the GitLab CE/EE
`doc/` directory, instead of the relative link, use the full path:
`http://doc.gitlab.com/ce/administration/restart_gitlab.html`.
Replace `reconfigure` with `restart` where appropriate.
## API ## API
Here is a list of must-have items. Use them in the exact order that appears Here is a list of must-have items. Use them in the exact order that appears
...@@ -229,3 +246,4 @@ curl -X PUT -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" -d "restricted_signup_domai ...@@ -229,3 +246,4 @@ curl -X PUT -H "PRIVATE-TOKEN: 9koXpg98eAheJpvBs5tK" -d "restricted_signup_domai
[cURL]: http://curl.haxx.se/ "cURL website" [cURL]: http://curl.haxx.se/ "cURL website"
[single spaces]: http://www.slate.com/articles/technology/technology/2011/01/space_invaders.html [single spaces]: http://www.slate.com/articles/technology/technology/2011/01/space_invaders.html
[gfm]: http://doc.gitlab.com/ce/markdown/markdown.html#newlines "GitLab flavored markdown documentation" [gfm]: http://doc.gitlab.com/ce/markdown/markdown.html#newlines "GitLab flavored markdown documentation"
[doc-restart]: ../administration/restart_gitlab.md "GitLab restart documentation"
...@@ -20,7 +20,13 @@ In the Admin area under **Settings** (`/admin/application_settings`), look for ...@@ -20,7 +20,13 @@ In the Admin area under **Settings** (`/admin/application_settings`), look for
the "Sign-in Restrictions" area, where you can configure both. the "Sign-in Restrictions" area, where you can configure both.
If you want 2FA enforcement to take effect on next login, change the grace If you want 2FA enforcement to take effect on next login, change the grace
period to `0` period to `0`.
---
![Two factor authentication admin settings](img/two_factor_authentication_settings.png)
---
## Disabling 2FA for everyone ## Disabling 2FA for everyone
...@@ -28,11 +34,12 @@ There may be some special situations where you want to disable 2FA for everyone ...@@ -28,11 +34,12 @@ There may be some special situations where you want to disable 2FA for everyone
even when forced 2FA is disabled. There is a rake task for that: even when forced 2FA is disabled. There is a rake task for that:
``` ```
# use this command if you've installed GitLab with the Omnibus package # Omnibus installations
sudo gitlab-rake gitlab:two_factor:disable_for_all_users sudo gitlab-rake gitlab:two_factor:disable_for_all_users
# if you've installed GitLab from source # Installations from source
sudo -u git -H bundle exec rake gitlab:two_factor:disable_for_all_users RAILS_ENV=production sudo -u git -H bundle exec rake gitlab:two_factor:disable_for_all_users RAILS_ENV=production
``` ```
**IMPORTANT: this is a permanent and irreversible action. Users will have to reactivate 2FA from scratch if they want to use it again.** **IMPORTANT: this is a permanent and irreversible action. Users will have to
reactivate 2FA from scratch if they want to use it again.**
...@@ -37,7 +37,7 @@ sudo -u git -H git checkout 8-4-stable-ee ...@@ -37,7 +37,7 @@ sudo -u git -H git checkout 8-4-stable-ee
```bash ```bash
cd /home/git/gitlab-shell cd /home/git/gitlab-shell
sudo -u git -H git fetch --all sudo -u git -H git fetch --all
sudo -u git -H git checkout v2.6.9 sudo -u git -H git checkout v2.6.10
``` ```
### 5. Update gitlab-workhorse ### 5. Update gitlab-workhorse
...@@ -48,7 +48,7 @@ which should already be on your system from GitLab 8.1. ...@@ -48,7 +48,7 @@ which should already be on your system from GitLab 8.1.
```bash ```bash
cd /home/git/gitlab-workhorse cd /home/git/gitlab-workhorse
sudo -u git -H git fetch --all sudo -u git -H git fetch --all
sudo -u git -H git checkout 0.6.0 sudo -u git -H git checkout 0.6.1
sudo -u git -H make sudo -u git -H make
``` ```
...@@ -104,10 +104,7 @@ via [/etc/default/gitlab]. ...@@ -104,10 +104,7 @@ via [/etc/default/gitlab].
#### Init script #### Init script
We updated the init script for GitLab in order to pass new We updated the init script for GitLab in order to set a specific PATH for gitlab-workhorse.
configuration options to gitlab-workhorse. We let gitlab-workhorse
connect to the Rails application via a Unix domain socket and we tell
it where the 'public' directory of GitLab is.
``` ```
cd /home/git/gitlab cd /home/git/gitlab
......
...@@ -7,6 +7,7 @@ ...@@ -7,6 +7,7 @@
- [Groups](groups.md) - [Groups](groups.md)
- [Importing to GitLab](doc/importing/README.md) - [Importing to GitLab](doc/importing/README.md)
- [Keyboard shortcuts](shortcuts.md) - [Keyboard shortcuts](shortcuts.md)
- [File finder](file_finder.md)
- [Labels](labels.md) - [Labels](labels.md)
- [Issue weight](issue_weight.md) - [Issue weight](issue_weight.md)
- [Manage large binaries with git annex](git_annex.md) - [Manage large binaries with git annex](git_annex.md)
......
# File finder
_**Note:** This feature was [introduced][gh-9889] in GitLab 8.4._
---
The file finder feature allows you to quickly shortcut your way when you are
searching for a file in a repository using the GitLab UI.
You can find the **Find File** button when in the **Files** section of a
project.
![Find file button](img/file_finder_find_button.png)
---
For those who prefer to keep their fingers on the keyboard, there is a
[shortcut button](shortcuts.md) as well, which you can invoke from _anywhere_
in a project.
Press `t` to launch the File search function when in **Issues**,
**Merge requests**, **Milestones**, even the project's settings.
Start typing what you are searching for and watch the magic happen. With the
up/down arrows, you go up and down the results, with `Esc` you close the search
and go back to **Files**.
## How it works
The File finder feature is powered by the [Fuzzy filter] library.
It implements a fuzzy search with highlight, and tries to provide intuitive
results by recognizing patterns that people use while searching.
For example, consider the [GitLab CE repository][ce] and that we want to open
the `app/controllers/admin/deploy_keys_controller.rb` file.
Using fuzzy search, we start by typing letters that get us closer to the file.
**Protip:** To narrow down your search, include `/` in your search terms.
![Find file button](img/file_finder_find_file.png)
[gh-9889]: https://github.com/gitlabhq/gitlabhq/pull/9889 "File finder pull request"
[fuzzy filter]: https://github.com/jeancroy/fuzzaldrin-plus "fuzzaldrin-plus on GitHub"
[ce]: https://gitlab.com/gitlab-org/gitlab-ce/tree/master "GitLab CE repository"
...@@ -13,8 +13,8 @@ module Gitlab ...@@ -13,8 +13,8 @@ module Gitlab
attr_reader :file, :path, :full_version attr_reader :file, :path, :full_version
def initialize(file, path) def initialize(file, path, **opts)
@file, @path = file, path @file, @path, @opts = file, path, opts
@full_version = read_version @full_version = read_version
end end
...@@ -52,7 +52,9 @@ module Gitlab ...@@ -52,7 +52,9 @@ module Gitlab
def match_entries(gz) def match_entries(gz)
entries = {} entries = {}
match_pattern = %r{^#{Regexp.escape(@path)}[^/]*/?$}
child_pattern = '[^/]*/?$' unless @opts[:recursive]
match_pattern = /^#{Regexp.escape(@path)}#{child_pattern}/
until gz.eof? do until gz.eof? do
begin begin
......
...@@ -95,6 +95,13 @@ module Gitlab ...@@ -95,6 +95,13 @@ module Gitlab
children.empty? children.empty?
end end
def total_size
descendant_pattern = %r{^#{Regexp.escape(@path)}}
entries.sum do |path, entry|
(entry[:size] if path =~ descendant_pattern).to_i
end
end
def to_s def to_s
@path @path
end end
......
module Gitlab module Gitlab
module Diff module Diff
class Highlight class Highlight
attr_reader :diff_file attr_reader :diff_file, :diff_lines, :raw_lines
delegate :old_path, :new_path, :old_ref, :new_ref, to: :diff_file, prefix: :diff delegate :old_path, :new_path, :old_ref, :new_ref, to: :diff_file, prefix: :diff
def initialize(diff_file) def initialize(diff_lines)
@diff_file = diff_file if diff_lines.is_a?(Gitlab::Diff::File)
@diff_lines = diff_file.diff_lines @diff_file = diff_lines
@diff_lines = @diff_file.diff_lines
else
@diff_lines = diff_lines
end
@raw_lines = @diff_lines.map(&:text) @raw_lines = @diff_lines.map(&:text)
end end
def highlight def highlight
@diff_lines.each_with_index do |diff_line, i| @diff_lines.map.with_index do |diff_line, i|
diff_line = diff_line.dup
# ignore highlighting for "match" lines # ignore highlighting for "match" lines
next if diff_line.type == 'match' || diff_line.type == 'nonewline' next diff_line if diff_line.type == 'match' || diff_line.type == 'nonewline'
rich_line = highlight_line(diff_line, i) rich_line = highlight_line(diff_line, i)
...@@ -23,15 +28,15 @@ module Gitlab ...@@ -23,15 +28,15 @@ module Gitlab
end end
diff_line.text = rich_line.html_safe diff_line.text = rich_line.html_safe
end
@diff_lines diff_line
end
end end
private private
def highlight_line(diff_line, index) def highlight_line(diff_line, index)
return html_escape(diff_line.text) unless diff_file.diff_refs return html_escape(diff_line.text) unless diff_file && diff_file.diff_refs
line_prefix = diff_line.text.match(/\A(.)/) ? $1 : ' ' line_prefix = diff_line.text.match(/\A(.)/) ? $1 : ' '
...@@ -52,10 +57,12 @@ module Gitlab ...@@ -52,10 +57,12 @@ module Gitlab
end end
def old_lines def old_lines
return unless diff_file
@old_lines ||= Gitlab::Highlight.highlight_lines(*processing_args(:old)) @old_lines ||= Gitlab::Highlight.highlight_lines(*processing_args(:old))
end end
def new_lines def new_lines
return unless diff_file
@new_lines ||= Gitlab::Highlight.highlight_lines(*processing_args(:new)) @new_lines ||= Gitlab::Highlight.highlight_lines(*processing_args(:new))
end end
......
...@@ -11,7 +11,8 @@ module Gitlab ...@@ -11,7 +11,8 @@ module Gitlab
lines = [] lines = []
skip_next = false skip_next = false
diff_file.highlighted_diff_lines.each do |line| highlighted_diff_lines = diff_file.highlighted_diff_lines
highlighted_diff_lines.each do |line|
full_line = line.text full_line = line.text
type = line.type type = line.type
line_code = generate_line_code(diff_file.file_path, line) line_code = generate_line_code(diff_file.file_path, line)
...@@ -21,6 +22,7 @@ module Gitlab ...@@ -21,6 +22,7 @@ module Gitlab
next_line = diff_file.next_line(line.index) next_line = diff_file.next_line(line.index)
if next_line if next_line
next_line = highlighted_diff_lines[next_line.index]
next_line_code = generate_line_code(diff_file.file_path, next_line) next_line_code = generate_line_code(diff_file.file_path, next_line)
next_type = next_line.type next_type = next_line.type
next_line = next_line.text next_line = next_line.text
......
...@@ -82,8 +82,12 @@ module Gitlab ...@@ -82,8 +82,12 @@ module Gitlab
end end
true true
rescue Gitlab::Shell::Error rescue Gitlab::Shell::Error => e
false if e.message =~ /repository not exported/
true
else
false
end
end end
end end
end end
......
...@@ -38,6 +38,7 @@ web_server_pid_path="$pid_path/unicorn.pid" ...@@ -38,6 +38,7 @@ web_server_pid_path="$pid_path/unicorn.pid"
sidekiq_pid_path="$pid_path/sidekiq.pid" sidekiq_pid_path="$pid_path/sidekiq.pid"
mail_room_enabled=false mail_room_enabled=false
mail_room_pid_path="$pid_path/mail_room.pid" mail_room_pid_path="$pid_path/mail_room.pid"
gitlab_workhorse_dir=$(cd $app_root/../gitlab-workhorse && pwd)
gitlab_workhorse_pid_path="$pid_path/gitlab-workhorse.pid" gitlab_workhorse_pid_path="$pid_path/gitlab-workhorse.pid"
gitlab_workhorse_options="-listenUmask 0 -listenNetwork unix -listenAddr $socket_path/gitlab-workhorse.socket -authBackend http://127.0.0.1:8080 -authSocket $rails_socket -documentRoot $app_root/public" gitlab_workhorse_options="-listenUmask 0 -listenNetwork unix -listenAddr $socket_path/gitlab-workhorse.socket -authBackend http://127.0.0.1:8080 -authSocket $rails_socket -documentRoot $app_root/public"
gitlab_workhorse_log="$app_root/log/gitlab-workhorse.log" gitlab_workhorse_log="$app_root/log/gitlab-workhorse.log"
...@@ -233,10 +234,12 @@ start_gitlab() { ...@@ -233,10 +234,12 @@ start_gitlab() {
if [ "$gitlab_workhorse_status" = "0" ]; then if [ "$gitlab_workhorse_status" = "0" ]; then
echo "The gitlab-workhorse is already running with pid $spid, not restarting" echo "The gitlab-workhorse is already running with pid $spid, not restarting"
else else
# No need to remove a socket, gitlab-workhorse does this itself # No need to remove a socket, gitlab-workhorse does this itself.
# Because gitlab-workhorse has multiple executables we need to fix
# the PATH.
$app_root/bin/daemon_with_pidfile $gitlab_workhorse_pid_path \ $app_root/bin/daemon_with_pidfile $gitlab_workhorse_pid_path \
$app_root/../gitlab-workhorse/gitlab-workhorse \ /usr/bin/env PATH=$gitlab_workhorse_dir:$PATH \
$gitlab_workhorse_options \ gitlab-workhorse $gitlab_workhorse_options \
>> $gitlab_workhorse_log 2>&1 & >> $gitlab_workhorse_log 2>&1 &
fi fi
......
...@@ -30,6 +30,9 @@ web_server_pid_path="$pid_path/unicorn.pid" ...@@ -30,6 +30,9 @@ web_server_pid_path="$pid_path/unicorn.pid"
# The default is "$pid_path/sidekiq.pid" # The default is "$pid_path/sidekiq.pid"
sidekiq_pid_path="$pid_path/sidekiq.pid" sidekiq_pid_path="$pid_path/sidekiq.pid"
# The directory where the gitlab-workhorse binaries are. Usually
# /home/git/gitlab-workhorse .
gitlab_workhorse_dir=$(cd $app_root/../gitlab-workhorse && pwd)
gitlab_workhorse_pid_path="$pid_path/gitlab-workhorse.pid" gitlab_workhorse_pid_path="$pid_path/gitlab-workhorse.pid"
# The -listenXxx settings determine where gitlab-workhorse # The -listenXxx settings determine where gitlab-workhorse
# listens for connections from NGINX. To listen on localhost:8181, write # listens for connections from NGINX. To listen on localhost:8181, write
......
...@@ -4,13 +4,13 @@ describe Gitlab::Ci::Build::Artifacts::Metadata::Entry do ...@@ -4,13 +4,13 @@ describe Gitlab::Ci::Build::Artifacts::Metadata::Entry do
let(:entries) do let(:entries) do
{ 'path/' => {}, { 'path/' => {},
'path/dir_1/' => {}, 'path/dir_1/' => {},
'path/dir_1/file_1' => {}, 'path/dir_1/file_1' => { size: 10 },
'path/dir_1/file_b' => {}, 'path/dir_1/file_b' => { size: 10 },
'path/dir_1/subdir/' => {}, 'path/dir_1/subdir/' => {},
'path/dir_1/subdir/subfile' => {}, 'path/dir_1/subdir/subfile' => { size: 10 },
'path/second_dir' => {}, 'path/second_dir' => {},
'path/second_dir/dir_3/file_2' => {}, 'path/second_dir/dir_3/file_2' => { size: 10 },
'path/second_dir/dir_3/file_3'=> {}, 'path/second_dir/dir_3/file_3'=> { size: 10 },
'another_directory/'=> {}, 'another_directory/'=> {},
'another_file' => {}, 'another_file' => {},
'/file/with/absolute_path' => {} } '/file/with/absolute_path' => {} }
...@@ -112,6 +112,11 @@ describe Gitlab::Ci::Build::Artifacts::Metadata::Entry do ...@@ -112,6 +112,11 @@ describe Gitlab::Ci::Build::Artifacts::Metadata::Entry do
subject { |example| path(example).empty? } subject { |example| path(example).empty? }
it { is_expected.to be false } it { is_expected.to be false }
end end
describe '#total_size' do
subject { |example| path(example).total_size }
it { is_expected.to eq(30) }
end
end end
end end
......
require 'spec_helper' require 'spec_helper'
describe Gitlab::Ci::Build::Artifacts::Metadata do describe Gitlab::Ci::Build::Artifacts::Metadata do
def metadata(path = '') def metadata(path = '', **opts)
described_class.new(metadata_file_path, path) described_class.new(metadata_file_path, path, **opts)
end end
let(:metadata_file_path) do let(:metadata_file_path) do
...@@ -51,6 +51,19 @@ describe Gitlab::Ci::Build::Artifacts::Metadata do ...@@ -51,6 +51,19 @@ describe Gitlab::Ci::Build::Artifacts::Metadata do
end end
end end
describe '#find_entries! recursively for other_artifacts_0.1.2/' do
subject { metadata('other_artifacts_0.1.2/', recursive: true).find_entries! }
it 'matches correct paths' do
expect(subject.keys).
to contain_exactly 'other_artifacts_0.1.2/',
'other_artifacts_0.1.2/doc_sample.txt',
'other_artifacts_0.1.2/another-subdirectory/',
'other_artifacts_0.1.2/another-subdirectory/empty_directory/',
'other_artifacts_0.1.2/another-subdirectory/banana_sample.gif'
end
end
describe '#to_entry' do describe '#to_entry' do
subject { metadata('').to_entry } subject { metadata('').to_entry }
it { is_expected.to be_an_instance_of(Gitlab::Ci::Build::Artifacts::Metadata::Entry) } it { is_expected.to be_an_instance_of(Gitlab::Ci::Build::Artifacts::Metadata::Entry) }
......
...@@ -362,12 +362,12 @@ describe Ci::Build, models: true do ...@@ -362,12 +362,12 @@ describe Ci::Build, models: true do
subject { build.artifacts_browse_url } subject { build.artifacts_browse_url }
it "should be nil if artifacts browser is unsupported" do it "should be nil if artifacts browser is unsupported" do
allow(build).to receive(:artifacts_browser_supported?).and_return(false) allow(build).to receive(:artifacts_metadata?).and_return(false)
is_expected.to be_nil is_expected.to be_nil
end end
it 'should not be nil if artifacts browser is supported' do it 'should not be nil if artifacts browser is supported' do
allow(build).to receive(:artifacts_browser_supported?).and_return(true) allow(build).to receive(:artifacts_metadata?).and_return(true)
is_expected.to_not be_nil is_expected.to_not be_nil
end end
end end
...@@ -391,8 +391,8 @@ describe Ci::Build, models: true do ...@@ -391,8 +391,8 @@ describe Ci::Build, models: true do
end end
describe :artifacts_browser_supported? do describe :artifacts_metadata? do
subject { build.artifacts_browser_supported? } subject { build.artifacts_metadata? }
context 'artifacts metadata does not exist' do context 'artifacts metadata does not exist' do
it { is_expected.to be_falsy } it { is_expected.to be_falsy }
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment