Imported Upstream version 8.4.0+dfsg

This commit is contained in:
Praveen Arimbrathodiyil 2016-01-29 22:53:50 +05:30
parent c14cdc3ad7
commit f011be6d2d
177 changed files with 2978 additions and 595 deletions

View file

@ -1,12 +1,17 @@
Please view this file on the master branch, on stable branches it's out of date.
v 8.4.0 (unreleased)
- Allow LDAP users to change their email if it was not set by the LDAP server
- Ensure Gravatar host looks like an actual host
- Consider re-assign as a mention from a notification point of view
- Add pagination headers to already paginated API resources
- Properly generate diff of orphan commits, like the first commit in a repository
- Improve the consistency of commit titles, branch names, tag names, issue/MR titles, on their respective project pages
- Autocomplete data is now always loaded, instead of when focusing a comment text area (Yorick Peterse)
- Improved performance of finding issues for an entire group (Yorick Peterse)
- Added custom application performance measuring system powered by InfluxDB (Yorick Peterse)
- Autocomplete data is now always loaded, instead of when focusing a comment text area
- Improved performance of finding issues for an entire group
- Added custom application performance measuring system powered by InfluxDB
- Add syntax highlighting to diffs
- Gracefully handle invalid UTF-8 sequences in Markdown links (Stan Hu)
- Bump fog to 1.36.0 (Stan Hu)
- Add user's last used IP addresses to admin page (Stan Hu)
- Add housekeeping function to project settings page
@ -57,11 +62,19 @@ v 8.4.0 (unreleased)
- Autosize Markdown textareas
- Import GitHub wiki into GitLab
- Add reporters ability to download and browse build artifacts (Andrew Johnson)
- Autofill referring url in message box when reporting user abuse. (Josh Frye)
- Autofill referring url in message box when reporting user abuse.
- Remove leading comma on award emoji when the user is the first to award the emoji (Zeger-Jan van de Weg)
- Add build artifacts browser
- Improve UX in builds artifacts browser
- Increase default size of `data` column in `events` table when using MySQL
- Expose button to CI Lint tool on project builds page
- Fix: Creator should be added as a master of the project on creation
- Added X-GitLab-... headers to emails from CI and Email On Push services (Anton Baklanov)
- Add IP check against DNSBLs at account sign-up
- Added cache:key to .gitlab-ci.yml allowing to fine tune the caching
v 8.3.4
- Use gitlab-workhorse 0.5.4 (fixes API routing bug)
- Add build artifacts browser
v 8.3.3
- Preserve CE behavior with JIRA integration by only calling API if URL is set
@ -109,6 +122,7 @@ v 8.3.0
- Fix: Assignee selector is empty when 'Unassigned' is selected (Jose Corcuera)
- Add rake tasks for git repository maintainance (Zeger-Jan van de Weg)
- Fix 500 error when update group member permission
- Fix: As an admin, cannot add oneself as a member to a group/project
- Trim leading and trailing whitespace of milestone and issueable titles (Jose Corcuera)
- Recognize issue/MR/snippet/commit links as references
- Backport JIRA features from EE to CE
@ -170,7 +184,6 @@ v 8.2.2
- Fix Error 500 when viewing user's personal projects from admin page (Stan Hu)
- Fix: Raw private snippets access workflow
- Prevent "413 Request entity too large" errors when pushing large files with LFS
- Fix: As an admin, cannot add oneself as a member to a group/project
- Fix invalid links within projects dashboard header
- Make current user the first user in assignee dropdown in issues detail page (Stan Hu)
- Fix: duplicate email notifications on issue comments

View file

@ -1 +1 @@
0.5.4
0.6.1

View file

@ -18,7 +18,7 @@ gem "mysql2", '~> 0.3.16', group: :mysql
gem "pg", '~> 0.18.2', group: :postgres
# Authentication libraries
gem 'devise', '~> 3.5.3'
gem 'devise', '~> 3.5.4'
gem 'devise-async', '~> 0.9.0'
gem 'doorkeeper', '~> 2.2.0'
gem 'omniauth', '~> 1.2.2'
@ -293,6 +293,9 @@ end
group :production do
gem "gitlab_meta", '7.0'
# Sentry integration
gem 'sentry-raven'
end
gem "newrelic_rpm", '~> 3.9.4.245'

View file

@ -157,7 +157,7 @@ GEM
activerecord (>= 3.2.0, < 5.0)
descendants_tracker (0.0.4)
thread_safe (~> 0.3, >= 0.3.1)
devise (3.5.3)
devise (3.5.4)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 3.2.6, < 5)
@ -614,7 +614,7 @@ GEM
thor (>= 0.18.1, < 2.0)
rainbow (2.0.0)
raindrops (0.15.0)
rake (10.4.2)
rake (10.5.0)
raphael-rails (2.1.2)
rb-fsevent (0.9.6)
rb-inotify (0.9.5)
@ -648,8 +648,8 @@ GEM
request_store (1.2.1)
rerun (0.11.0)
listen (~> 3.0)
responders (2.1.0)
railties (>= 4.2.0, < 5)
responders (2.1.1)
railties (>= 4.2.0, < 5.1)
rest-client (1.8.0)
http-cookie (>= 1.0.2, < 2.0)
mime-types (>= 1.16, < 3.0)
@ -725,6 +725,8 @@ GEM
activesupport (>= 3.1, < 4.3)
select2-rails (3.5.9.3)
thor (~> 0.14)
sentry-raven (0.15.3)
faraday (>= 0.7.6)
settingslogic (2.0.9)
sexp_processor (4.6.0)
sham_rack (1.3.6)
@ -911,7 +913,7 @@ DEPENDENCIES
d3_rails (~> 3.5.0)
database_cleaner (~> 1.4.0)
default_value_for (~> 3.0.0)
devise (~> 3.5.3)
devise (~> 3.5.4)
devise-async (~> 0.9.0)
devise-two-factor (~> 2.0.0)
diffy (~> 3.0.3)
@ -1008,6 +1010,7 @@ DEPENDENCIES
sdoc (~> 0.3.20)
seed-fu (~> 2.3.5)
select2-rails (~> 3.5.9)
sentry-raven
settingslogic (~> 2.0.9)
sham_rack
shoulda-matchers (~> 2.8.0)

0
Rakefile Normal file → Executable file
View file

View file

@ -1 +1 @@
8.4.0-rc2
8.4.0

0
app/assets/fonts/OFL.txt Executable file → Normal file
View file

0
app/assets/fonts/SourceSansPro-Black.ttf.woff Executable file → Normal file
View file

0
app/assets/fonts/SourceSansPro-Black.ttf.woff2 Executable file → Normal file
View file

0
app/assets/fonts/SourceSansPro-BlackIt.ttf.woff Executable file → Normal file
View file

0
app/assets/fonts/SourceSansPro-BlackIt.ttf.woff2 Executable file → Normal file
View file

0
app/assets/fonts/SourceSansPro-Bold.ttf.woff Executable file → Normal file
View file

0
app/assets/fonts/SourceSansPro-Bold.ttf.woff2 Executable file → Normal file
View file

0
app/assets/fonts/SourceSansPro-BoldIt.ttf.woff Executable file → Normal file
View file

0
app/assets/fonts/SourceSansPro-BoldIt.ttf.woff2 Executable file → Normal file
View file

0
app/assets/fonts/SourceSansPro-ExtraLight.ttf.woff Executable file → Normal file
View file

0
app/assets/fonts/SourceSansPro-ExtraLight.ttf.woff2 Executable file → Normal file
View file

0
app/assets/fonts/SourceSansPro-ExtraLightIt.ttf.woff Executable file → Normal file
View file

0
app/assets/fonts/SourceSansPro-ExtraLightIt.ttf.woff2 Executable file → Normal file
View file

0
app/assets/fonts/SourceSansPro-It.ttf.woff Executable file → Normal file
View file

0
app/assets/fonts/SourceSansPro-It.ttf.woff2 Executable file → Normal file
View file

0
app/assets/fonts/SourceSansPro-Light.ttf.woff Executable file → Normal file
View file

0
app/assets/fonts/SourceSansPro-Light.ttf.woff2 Executable file → Normal file
View file

0
app/assets/fonts/SourceSansPro-LightIt.ttf.woff Executable file → Normal file
View file

0
app/assets/fonts/SourceSansPro-LightIt.ttf.woff2 Executable file → Normal file
View file

0
app/assets/fonts/SourceSansPro-Regular.ttf.woff Executable file → Normal file
View file

0
app/assets/fonts/SourceSansPro-Regular.ttf.woff2 Executable file → Normal file
View file

0
app/assets/fonts/SourceSansPro-Semibold.ttf.woff Executable file → Normal file
View file

0
app/assets/fonts/SourceSansPro-Semibold.ttf.woff2 Executable file → Normal file
View file

0
app/assets/fonts/SourceSansPro-SemiboldIt.ttf.woff Executable file → Normal file
View file

0
app/assets/fonts/SourceSansPro-SemiboldIt.ttf.woff2 Executable file → Normal file
View file

View file

@ -19,7 +19,7 @@ class @AwardsHandler
@addAwardToEmojiBar(emoji)
$(".emoji-menu").hide()
addAwardToEmojiBar: (emoji) ->
@addEmojiToFrequentlyUsedList(emoji)
@ -44,7 +44,6 @@ class @AwardsHandler
decrementCounter: (emoji) ->
counter = @findEmojiIcon(emoji).siblings(".counter")
emojiIcon = counter.parent()
if parseInt(counter.text()) > 1
counter.text(parseInt(counter.text()) - 1)
emojiIcon.removeClass("active")
@ -60,13 +59,16 @@ class @AwardsHandler
removeMeFromAuthorList: (emoji) ->
award_block = @findEmojiIcon(emoji).parent()
authors = award_block.attr("data-original-title").split(", ")
authors = _.without(authors, "me").join(", ")
award_block.attr("title", authors)
authors.splice(authors.indexOf("me"),1)
award_block.closest(".award").attr("data-original-title", authors.join(", "))
@resetTooltip(award_block)
addMeToAuthorList: (emoji) ->
award_block = @findEmojiIcon(emoji).parent()
authors = award_block.attr("data-original-title").split(", ")
origTitle = award_block.attr("data-original-title").trim()
authors = []
if origTitle
authors = origTitle.split(', ')
authors.push("me")
award_block.attr("title", authors.join(", "))
@resetTooltip(award_block)
@ -78,7 +80,7 @@ class @AwardsHandler
setTimeout (->
award.tooltip()
), 200
createEmoji: (emoji) ->
emojiCssClass = @resolveNameToCssClass(emoji)

View file

@ -0,0 +1,14 @@
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

View file

@ -87,7 +87,6 @@ class Dispatcher
new GroupAvatar()
when 'projects:tree:show'
new TreeView()
shortcut_handler = new ShortcutsTree()
when 'projects:find_file:show'
shortcut_handler = true
when 'projects:blob:show'
@ -101,6 +100,8 @@ class Dispatcher
shortcut_handler = true
when 'projects:forks:new'
new ProjectFork()
when 'projects:artifacts:browse'
new BuildArtifacts()
when 'users:show'
new User()
new Activities()

View file

@ -4,6 +4,7 @@ class @Shortcuts
Mousetrap.reset()
Mousetrap.bind('?', @selectiveHelp)
Mousetrap.bind('s', Shortcuts.focusSearch)
Mousetrap.bind('t', -> Turbolinks.visit(findFileURL)) if findFileURL?
selectiveHelp: (e) =>
Shortcuts.showHelp(e, @enabledHelp)

View file

@ -1,4 +0,0 @@
class @ShortcutsTree extends ShortcutsNavigation
constructor: ->
super()
Mousetrap.bind('t', -> ShortcutsTree.findAndFollowLink('.shortcuts-find-file'))

View file

@ -6,7 +6,7 @@ class @Star
$starIcon = $this.find('i')
toggleStar = (isStarred) ->
$this.parent().find('span.count').text data.star_count
$this.parent().find('.star-count').text data.star_count
if isStarred
$starSpan.removeClass('starred').text 'Star'
$starIcon.removeClass('fa-star').addClass 'fa-star-o'
@ -19,4 +19,4 @@ class @Star
return
).on 'ajax:error', (e, xhr, status, error) ->
new Flash('Star toggle failed. Try again later.', 'alert')
return
return

View file

@ -1,5 +1,5 @@
.filter-item {
margin-right: 15px;
margin-right: 6px;
}
@media (min-width: 800px) {

View file

@ -90,4 +90,22 @@
.vg { color: #cc6666 } /* Name.Variable.Global */
.vi { color: #cc6666 } /* Name.Variable.Instance */
.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);
}
}
}

View file

@ -90,4 +90,22 @@
.gu { color: #75715e; } /* Generic.Subheading & Diff Unified/Comment? */
.gd { color: #f92672; } /* Generic.Deleted & Diff Deleted */
.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);
}
}
}

View file

@ -111,4 +111,22 @@
.vg { color: #268bd2 } /* Name.Variable.Global */
.vi { color: #268bd2 } /* Name.Variable.Instance */
.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);
}
}
}

View file

@ -111,4 +111,23 @@
.vg { color: #268bd2 } /* Name.Variable.Global */
.vi { color: #268bd2 } /* Name.Variable.Instance */
.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);
}
}
}

View file

@ -36,6 +36,10 @@ li.commit {
line-height: 20px;
margin-bottom: 2px;
.btn-clipboard {
margin-top: -1px;
}
.notes_count {
float: right;
margin-right: 10px;

View file

@ -392,3 +392,18 @@
right: 15px;
}
}
@mixin diff_background($r, $g, $b, $custom-border) {
/* Fallback for web browsers that doesn't support RGBa */
background: rgb($r, $g, $b);
/* RGBa with 0.3 opacity */
background: rgba($r, $g, $b, 0.3);
&.new_line, &.old_line {
border-right-color: $custom-border !important;
}
&.line_content span.idiff {
background: rgb($r, $g, $b);
}
}

View file

@ -74,9 +74,13 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:metrics_timeout,
:metrics_method_call_threshold,
:metrics_sample_interval,
:ip_blocking_enabled,
:dnsbl_servers_list,
:recaptcha_enabled,
:recaptcha_site_key,
:recaptcha_private_key,
:sentry_enabled,
:sentry_dsn,
restricted_visibility_levels: [],
import_sources: []
)

View file

@ -15,6 +15,7 @@ class ApplicationController < ActionController::Base
before_action :check_password_expiration
before_action :check_2fa_requirement
before_action :ldap_security_check
before_action :sentry_user_context
before_action :default_headers
before_action :add_gon_variables
before_action :configure_permitted_parameters, if: :devise_controller?
@ -24,6 +25,7 @@ class ApplicationController < ActionController::Base
helper_method :abilities, :can?, :current_application_settings
helper_method :import_sources_enabled?, :github_import_enabled?, :github_import_configured?, :gitlab_import_enabled?, :gitlab_import_configured?, :bitbucket_import_enabled?, :bitbucket_import_configured?, :gitorious_import_enabled?, :google_code_import_enabled?, :fogbugz_import_enabled?, :git_import_enabled?
helper_method :repository
rescue_from Encoding::CompatibilityError do |exception|
log_exception(exception)
@ -41,6 +43,16 @@ class ApplicationController < ActionController::Base
protected
def sentry_user_context
if Rails.env.production? && current_application_settings.sentry_enabled && current_user
Raven.user_context(
id: current_user.id,
email: current_user.email,
username: current_user.username,
)
end
end
# From https://github.com/plataformatec/devise/wiki/How-To:-Simple-Token-Authentication-Example
# https://gist.github.com/josevalim/fb706b1e933ef01e4fb6
def authenticate_user_from_token!

View file

@ -97,7 +97,7 @@ module CreatesCommit
# Merge request from fork to this project
@mr_source_project = @tree_edit_project
@mr_target_project = @project
@mr_target_branch = @mr_target_project.repository.root_ref
@mr_target_branch = @ref
end
end
end

View file

@ -52,7 +52,9 @@ class Projects::BlobController < Projects::ApplicationController
def preview
@content = params[:content]
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
end
@ -65,8 +67,9 @@ class Projects::BlobController < Projects::ApplicationController
end
def diff
@form = UnfoldForm.new(params)
@lines = @blob.data.lines[@form.since - 1..@form.to - 1]
@form = UnfoldForm.new(params)
@lines = Gitlab::Highlight.highlight_lines(repository, @ref, @path)
@lines = @lines[@form.since - 1..@form.to - 1]
if @form.bottom?
@match_line = ''

View file

@ -72,6 +72,7 @@ class Projects::CommitController < Projects::ApplicationController
@diffs = commit.diffs
end
@diff_refs = [commit.parent || commit, commit]
@notes_count = commit.notes.count
@statuses = ci_commit.statuses if ci_commit

View file

@ -21,7 +21,8 @@ class Projects::CompareController < Projects::ApplicationController
@commits = Commit.decorate(compare_result.commits, @project)
@diffs = compare_result.diffs
@commit = @project.commit(head_ref)
@first_commit = @project.commit(base_ref)
@base_commit = @project.commit(base_ref)
@diff_refs = [@base_commit, @commit]
@line_notes = []
end
end

View file

@ -58,7 +58,11 @@ class Projects::MergeRequestsController < Projects::ApplicationController
def diffs
@commit = @merge_request.last_commit
@first_commit = @merge_request.first_commit
@base_commit = @merge_request.diff_base_commit
# MRs created before 8.4 don't have a diff_base_commit,
# but we need it for the "View file @ ..." link by deleted files
@base_commit ||= @merge_request.first_commit.parent || @merge_request.first_commit
@comments_allowed = @reply_allowed = true
@comments_target = {
@ -102,7 +106,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
@source_project = merge_request.source_project
@commits = @merge_request.compare_commits.reverse
@commit = @merge_request.last_commit
@first_commit = @merge_request.first_commit
@base_commit = @merge_request.diff_base_commit
@diffs = @merge_request.compare_diffs
@ci_commit = @merge_request.ci_commit

View file

@ -8,6 +8,11 @@ class RegistrationsController < Devise::RegistrationsController
def create
if !Gitlab::Recaptcha.load_configurations! || verify_recaptcha
if Gitlab::IpCheck.new(request.remote_ip).spam?
flash[:alert] = 'Could not create an account. This IP is listed for spam.'
return render action: 'new'
end
super
else
flash[:alert] = "There was an error with the reCAPTCHA code below. Please re-enter the code."

View file

@ -1,21 +1,10 @@
module BlobHelper
def highlight(blob_name, blob_content, nowrap: false, continue: false)
@formatter ||= Rouge::Formatters::HTMLGitlab.new(
nowrap: nowrap,
cssclass: 'code highlight',
lineanchors: true,
lineanchorsid: 'LC'
)
def highlighter(blob_name, blob_content, nowrap: false)
Gitlab::Highlight.new(blob_name, blob_content, nowrap: nowrap)
end
begin
@lexer ||= Rouge::Lexer.guess(filename: blob_name, source: blob_content).new
result = @formatter.format(@lexer.lex(blob_content, continue: continue)).html_safe
rescue
@lexer = Rouge::Lexers::PlainText
result = @formatter.format(@lexer.lex(blob_content)).html_safe
end
result
def highlight(blob_name, blob_content, nowrap: false)
Gitlab::Highlight.highlight(blob_name, blob_content, nowrap: nowrap)
end
def no_highlight_files
@ -37,10 +26,10 @@ module BlobHelper
tree_join(ref, path),
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' }
elsif can_edit_blob?(blob)
link_to "Edit", edit_path, class: 'btn btn-small'
elsif can_edit_blob?(blob, project, ref)
link_to "Edit", edit_path, class: 'btn'
elsif can?(current_user, :fork_project, project)
continue_params = {
to: edit_path,
@ -50,7 +39,7 @@ module BlobHelper
fork_path = namespace_project_fork_path(project.namespace, project, namespace_key: current_user.namespace.id,
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
@ -61,11 +50,11 @@ module BlobHelper
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' }
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' }
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'
elsif can?(current_user, :fork_project, project)
continue_params = {

View file

@ -166,7 +166,7 @@ module CommitsHelper
link_to(
namespace_project_blob_path(project.namespace, project,
tree_join(commit_sha, diff.new_path)),
class: 'btn btn-small view-file js-view-file'
class: 'btn view-file js-view-file'
) do
raw('View file @') + content_tag(:span, commit_sha[0..6],
class: 'commit-short-id')

View file

@ -19,13 +19,13 @@ module DiffHelper
end
end
def safe_diff_files(diffs)
def safe_diff_files(diffs, diff_refs)
lines = 0
safe_files = []
diffs.first(allowed_diff_size).each do |diff|
lines += diff.diff.lines.count
break if lines > allowed_diff_lines
safe_files << Gitlab::Diff::File.new(diff)
safe_files << Gitlab::Diff::File.new(diff, diff_refs)
end
safe_files
end
@ -43,64 +43,6 @@ module DiffHelper
Gitlab::Diff::LineCode.generate(file_path, line.new_pos, line.old_pos)
end
def parallel_diff(diff_file, index)
lines = []
skip_next = false
# Building array of lines
#
# [
# left_type, left_line_number, left_line_content, left_line_code,
# right_line_type, right_line_number, right_line_content, right_line_code
# ]
#
diff_file.diff_lines.each do |line|
full_line = line.text
type = line.type
line_code = generate_line_code(diff_file.file_path, line)
line_new = line.new_pos
line_old = line.old_pos
next_line = diff_file.next_line(line.index)
if next_line
next_line_code = generate_line_code(diff_file.file_path, next_line)
next_type = next_line.type
next_line = next_line.text
end
if type == 'match' || type.nil?
# line in the right panel is the same as in the left one
line = [type, line_old, full_line, line_code, type, line_new, full_line, line_code]
lines.push(line)
elsif type == 'old'
if next_type == 'new'
# Left side has text removed, right side has text added
line = [type, line_old, full_line, line_code, next_type, line_new, next_line, next_line_code]
lines.push(line)
skip_next = true
elsif next_type == 'old' || next_type.nil?
# Left side has text removed, right side doesn't have any change
# No next line code, no new line number, no new line text
line = [type, line_old, full_line, line_code, next_type, nil, "&nbsp;", nil]
lines.push(line)
end
elsif type == 'new'
if skip_next
# Change has been already included in previous line so no need to do it again
skip_next = false
next
else
# Change is only on the right side, left side has no change
line = [nil, nil, "&nbsp;", line_code, type, line_new, full_line, line_code]
lines.push(line)
end
end
end
lines
end
def unfold_bottom_class(bottom)
(bottom) ? 'js-unfold-bottom' : ''
end
@ -111,9 +53,9 @@ module DiffHelper
def diff_line_content(line)
if line.blank?
" &nbsp;"
" &nbsp;".html_safe
else
line
line.html_safe
end
end
@ -160,8 +102,7 @@ module DiffHelper
def commit_for_diff(diff)
if diff.deleted_file
first_commit = @first_commit || @commit
first_commit.parent || @first_commit
@base_commit || @commit.parent || @commit
else
@commit
end

View file

@ -3,13 +3,26 @@ module Emails
def build_fail_email(build_id, to)
@build = Ci::Build.find(build_id)
@project = @build.project
add_project_headers
add_build_headers
headers['X-GitLab-Build-Status'] = "failed"
mail(to: to, subject: subject("Build failed for #{@project.name}", @build.short_sha))
end
def build_success_email(build_id, to)
@build = Ci::Build.find(build_id)
@project = @build.project
add_project_headers
add_build_headers
headers['X-GitLab-Build-Status'] = "success"
mail(to: to, subject: subject("Build success for #{@project.name}", @build.short_sha))
end
private
def add_build_headers
headers['X-GitLab-Build-Id'] = @build.id
headers['X-GitLab-Build-Ref'] = @build.ref
end
end
end

View file

@ -43,7 +43,7 @@ module Emails
@current_user = @created_by = User.find(created_by_id)
@access_level = access_level
@invite_email = invite_email
@target_url = namespace_project_url(@project.namespace, @project)
mail(to: @created_by.notification_email,
@ -65,6 +65,10 @@ module Emails
# used in notify layout
@target_url = @message.target_url
@project = Project.find project_id
add_project_headers
headers['X-GitLab-Author'] = @message.author_username
mail(from: sender(@message.author_id, @message.send_from_committer_email?),
reply_to: @message.reply_to,

View file

@ -100,12 +100,7 @@ class Notify < BaseMailer
end
def mail_thread(model, headers = {})
if @project
headers['X-GitLab-Project'] = @project.name
headers['X-GitLab-Project-Id'] = @project.id
headers['X-GitLab-Project-Path'] = @project.path_with_namespace
end
add_project_headers
headers["X-GitLab-#{model.class.name}-ID"] = model.id
headers['X-GitLab-Reply-Key'] = reply_key
@ -152,4 +147,12 @@ class Notify < BaseMailer
def reply_key
@reply_key ||= SentNotification.reply_key
end
def add_project_headers
return unless @project
headers['X-GitLab-Project'] = @project.name
headers['X-GitLab-Project-Id'] = @project.id
headers['X-GitLab-Project-Path'] = @project.path_with_namespace
end
end

View file

@ -41,6 +41,10 @@
# recaptcha_site_key :string
# recaptcha_private_key :string
# metrics_port :integer default(8089)
# sentry_enabled :boolean default(FALSE)
# sentry_dsn :string
# ip_blocking_enabled :boolean default(FALSE)
# dns_blacklist_threshold :float default(0.33)
#
class ApplicationSetting < ActiveRecord::Base
@ -82,6 +86,10 @@ class ApplicationSetting < ActiveRecord::Base
presence: true,
if: :recaptcha_enabled
validates :sentry_dsn,
presence: true,
if: :sentry_enabled
validates_each :restricted_visibility_levels do |record, attr, value|
unless value.nil?
value.each do |level|

View file

@ -346,17 +346,17 @@ module Ci
end
def artifacts_browse_url
if artifacts_browser_supported?
if artifacts_metadata?
browse_namespace_project_build_artifacts_path(project.namespace, project, self)
end
end
def artifacts_browser_supported?
def artifacts_metadata?
artifacts? && artifacts_metadata.exists?
end
def artifacts_metadata_entry(path)
Gitlab::Ci::Build::Artifacts::Metadata.new(artifacts_metadata.path, path).to_entry
def artifacts_metadata_entry(path, **options)
Gitlab::Ci::Build::Artifacts::Metadata.new(artifacts_metadata.path, path, **options).to_entry
end
private

View file

@ -91,7 +91,7 @@ class Member < ActiveRecord::Base
member.invite_email = user
end
if can_update_member?(current_user, member)
if can_update_member?(current_user, member) || project_creator?(member, access_level)
member.created_by ||= current_user
member.access_level = access_level
@ -107,6 +107,11 @@ class Member < ActiveRecord::Base
current_user.can?(:update_group_member, member) ||
current_user.can?(:update_project_member, member)
end
def project_creator?(member, access_level)
member.new_record? && member.owner? &&
access_level.to_i == ProjectMember::MASTER
end
end
def invite?

View file

@ -180,6 +180,14 @@ class MergeRequest < ActiveRecord::Base
merge_request_diff ? merge_request_diff.first_commit : compare_commits.first
end
def diff_base_commit
if merge_request_diff
merge_request_diff.base_commit
else
self.target_project.commit(self.target_branch)
end
end
def last_commit_short_sha
last_commit.short_id
end
@ -254,7 +262,7 @@ class MergeRequest < ActiveRecord::Base
end
def mergeable?
return false unless open? && !work_in_progress?
return false unless open? && !work_in_progress? && !broken?
check_if_can_be_merged
@ -477,8 +485,7 @@ class MergeRequest < ActiveRecord::Base
end
def target_sha
@target_sha ||= target_project.
repository.commit(target_branch).sha
@target_sha ||= target_project.repository.commit(target_branch).sha
end
def source_sha
@ -517,4 +524,10 @@ class MergeRequest < ActiveRecord::Base
def ci_commit
@ci_commit ||= source_project.ci_commit(last_commit.id) if last_commit && source_project
end
def diff_refs
return nil unless diff_base_commit
[diff_base_commit, last_commit]
end
end

View file

@ -73,6 +73,12 @@ class MergeRequestDiff < ActiveRecord::Base
commits.last
end
def base_commit
return nil unless self.base_commit_sha
merge_request.target_project.commit(self.base_commit_sha)
end
def last_commit_short_sha
@last_commit_short_sha ||= last_commit.short_id
end
@ -156,6 +162,9 @@ class MergeRequestDiff < ActiveRecord::Base
end
self.st_diffs = new_diffs
self.base_commit_sha = merge_request.target_project.commit(target_branch).try(:sha)
self.save
end

View file

@ -244,7 +244,7 @@ class Note < ActiveRecord::Base
prev_match_line = nil
prev_lines = []
diff_lines.each do |line|
highlighted_diff_lines.each do |line|
if line.type == "match"
prev_lines.clear
prev_match_line = line
@ -261,7 +261,11 @@ class Note < ActiveRecord::Base
end
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
def discussion_id

View file

@ -468,12 +468,9 @@ class Project < ActiveRecord::Base
!external_issue_tracker
end
def external_issues_trackers
services.select(&:issue_tracker?).reject(&:default?)
end
def external_issue_tracker
@external_issues_tracker ||= external_issues_trackers.find(&:activated?)
@external_issue_tracker ||=
services.issue_trackers.active.without_defaults.first
end
def can_have_issues_tracker_id?

View file

@ -23,14 +23,12 @@
# List methods you need to implement to get your CI service
# working with GitLab Merge Requests
class CiService < Service
def category
:ci
end
default_value_for :category, 'ci'
def valid_token?(token)
self.respond_to?(:token) && self.token.present? && self.token == token
end
def supported_events
%w(push)
end

View file

@ -24,9 +24,7 @@ class GitlabIssueTrackerService < IssueTrackerService
prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url
def default?
true
end
default_value_for :default, true
def to_param
'gitlab'

View file

@ -23,12 +23,10 @@ class IssueTrackerService < Service
validates :project_url, :issues_url, :new_issue_url, presence: true, if: :activated?
def category
:issue_tracker
end
default_value_for :category, 'issue_tracker'
def default?
false
default
end
def issue_url(iid)

View file

@ -43,6 +43,9 @@ class Service < ActiveRecord::Base
validates :project_id, presence: true, unless: Proc.new { |service| service.template? }
scope :visible, -> { where.not(type: ['GitlabIssueTrackerService', 'GitlabCiService']) }
scope :issue_trackers, -> { where(category: 'issue_tracker') }
scope :active, -> { where(active: true) }
scope :without_defaults, -> { where(default: false) }
scope :push_hooks, -> { where(push_events: true, active: true) }
scope :tag_push_hooks, -> { where(tag_push_events: true, active: true) }
@ -51,6 +54,8 @@ class Service < ActiveRecord::Base
scope :note_hooks, -> { where(note_events: true, active: true) }
scope :build_hooks, -> { where(build_events: true, active: true) }
default_value_for :category, 'common'
def activated?
active
end
@ -60,7 +65,7 @@ class Service < ActiveRecord::Base
end
def category
:common
read_attribute(:category).to_sym
end
def initialize_properties
@ -153,7 +158,7 @@ class Service < ActiveRecord::Base
# Returns a hash of the properties that have been assigned a new value since last save,
# indicating their original values (attr => original value).
# ActiveRecord does not provide a mechanism to track changes in serialized keys,
# ActiveRecord does not provide a mechanism to track changes in serialized keys,
# so we need a specific implementation for service properties.
# This allows to track changes to properties set with the accessor methods,
# but not direct manipulation of properties hash.
@ -164,7 +169,7 @@ class Service < ActiveRecord::Base
def reset_updated_properties
@updated_properties = nil
end
def async_execute(data)
return unless supported_events.include?(data[:object_kind])

View file

@ -664,7 +664,10 @@ class User < ActiveRecord::Base
end
def all_emails
[self.email, *self.emails.map(&:email)]
all_emails = []
all_emails << self.email unless self.temp_oauth_email?
all_emails.concat(self.emails.map(&:email))
all_emails
end
def hook_attrs

View file

@ -376,10 +376,10 @@ class NotificationService
end
def reassign_resource_email(target, project, current_user, method)
previous_assignee_id = previous_record(target, "assignee_id")
previous_assignee_id = previous_record(target, 'assignee_id')
previous_assignee = User.find_by(id: previous_assignee_id) if previous_assignee_id
recipients = build_recipients(target, project, current_user, [previous_assignee])
recipients = build_recipients(target, project, current_user, action: :reassign, previous_assignee: previous_assignee)
recipients.each do |recipient|
mailer.send(
@ -400,22 +400,27 @@ class NotificationService
end
end
def build_recipients(target, project, current_user, extra_recipients = nil)
def build_recipients(target, project, current_user, action: nil, previous_assignee: nil)
recipients = target.participants(current_user)
recipients = recipients.concat(extra_recipients).compact.uniq if extra_recipients
recipients = add_project_watchers(recipients, project)
recipients = reject_mention_users(recipients, project)
recipients = reject_muted_users(recipients, project)
# Re-assign is considered as a mention of the new assignee so we add the
# new assignee to the list of recipients after we rejected users with
# the "on mention" notification level
if action == :reassign
recipients << previous_assignee if previous_assignee
recipients << target.assignee
end
recipients = reject_muted_users(recipients, project)
recipients = add_subscribed_users(recipients, target)
recipients = reject_unsubscribed_users(recipients, target)
recipients.delete(current_user)
recipients = recipients.uniq
recipients
recipients.uniq
end
def mailer

View file

@ -212,6 +212,22 @@
%fieldset
%legend Spam and Anti-bot Protection
.form-group
.col-sm-offset-2.col-sm-10
.checkbox
= f.label :ip_blocking_enabled do
= f.check_box :ip_blocking_enabled
Enable IP check against blacklist at sign-up
.help-block Helps preventing accounts creation from 'known spam sources'
.form-group
= f.label :dnsbl_servers_list, class: 'control-label col-sm-2' do
DNSBL servers list
.col-sm-10
= f.text_field :dnsbl_servers_list, class: 'form-control'
.help-block
Please enter DNSBL servers separated with comma
.form-group
.col-sm-offset-2.col-sm-10
.checkbox
@ -226,11 +242,30 @@
= f.text_field :recaptcha_site_key, class: 'form-control'
.help-block
Generate site and private keys here:
%a{ href: 'http://www.google.com/recaptcha', target: 'blank'} http://www.google.com/recaptcha
%a{ href: 'http://www.google.com/recaptcha', target: '_blank'} http://www.google.com/recaptcha
.form-group
= f.label :recaptcha_private_key, 'reCAPTCHA Private Key', class: 'control-label col-sm-2'
.col-sm-10
= f.text_field :recaptcha_private_key, class: 'form-control'
%fieldset
%legend Error Reporting and Logging
%p
These settings require a restart to take effect.
.form-group
.col-sm-offset-2.col-sm-10
.checkbox
= f.label :sentry_enabled do
= f.check_box :sentry_enabled
Enable Sentry
.help-block
Sentry is an error reporting and logging tool which is currently not shipped with GitLab, get it here:
%a{ href: 'https://getsentry.com', target: '_blank' } https://getsentry.com
.form-group
= f.label :sentry_dsn, 'Sentry DSN', class: 'control-label col-sm-2'
.col-sm-10
= f.text_field :sentry_dsn, class: 'form-control'
.form-actions
= f.submit 'Save', class: 'btn btn-primary'

View file

@ -37,3 +37,6 @@
%h1.title= title
= render 'shared/outdated_browser'
- if @project && !@project.empty_repo?
:javascript
var findFileURL = "#{namespace_project_find_file_path(@project.namespace, @project, @ref || @project.repository.root_ref)}";

View file

@ -21,10 +21,10 @@
.form-group
= f.label :email, class: "control-label"
.col-sm-10
- if @user.ldap_user?
- if @user.ldap_user? && @user.ldap_email?
= f.text_field :email, class: "form-control", required: true, readonly: true
%span.help-block.light
Email is read-only for LDAP user
Your email address was automatically set based on the LDAP server.
- else
- if @user.temp_oauth_email?
= f.text_field :email, class: "form-control", required: true, value: nil

View file

@ -1,7 +1,8 @@
%tr{ class: 'tree-item' }
- path_to_directory = browse_namespace_project_build_artifacts_path(@project.namespace, @project, @build, path: directory.path)
%tr.tree-item{ 'data-link' => path_to_directory}
%td.tree-item-file-name
= tree_icon('folder', '755', directory.name)
%span.str-truncated
= link_to directory.name, browse_namespace_project_build_artifacts_path(@project.namespace, @project, @build, path: directory.path)
%td
= link_to directory.name, path_to_directory
%td

View file

@ -1,11 +1,9 @@
%tr{ class: 'tree-item' }
- path_to_file = file_namespace_project_build_artifacts_path(@project.namespace, @project, @build, path: file.path)
%tr.tree-item{ 'data-link' => path_to_file }
%td.tree-item-file-name
= tree_icon('file', '664', file.name)
%span.str-truncated
= file.name
= link_to file.name, path_to_file
%td
= number_to_human_size(file.metadata[:size], precision: 2)
%td
= link_to file_namespace_project_build_artifacts_path(@project.namespace, @project, @build, path: file.path),
class: 'btn btn-xs btn-default artifact-download' do
= icon('download')

View file

@ -1,22 +1,20 @@
- page_title 'Artifacts', "#{@build.name} (##{@build.id})", 'Builds'
= render 'projects/builds/header_title'
#tree-holder.tree-holder
.gray-content-block.top-block.clearfix
.pull-right
= link_to download_namespace_project_build_artifacts_path(@project.namespace, @project, @build),
class: 'btn btn-default' do
= icon('download')
Download artifacts archive
.top-block.gray-content-block.clearfix
.pull-right
= link_to download_namespace_project_build_artifacts_path(@project.namespace, @project, @build),
class: 'btn btn-default download' do
= icon('download')
Download artifacts archive
%div.tree-content-holder
.table-holder
%table.table.tree-table.table-striped
.tree-holder
%div.tree-content-holder
%table.table.tree-table
%thead
%tr
%th Name
%th Size
%th Download
= render partial: 'tree_directory', collection: @entry.directories(parent: true), as: :directory
= render partial: 'tree_file', collection: @entry.files, as: :file

View file

@ -15,6 +15,7 @@
.file-content.blame.highlight
%table
- current_line = 1
- blame_highlighter = highlighter(@blob.name, @blob.data, nowrap: true)
- @blame.each do |blame_group|
%tr
%td.blame-commit
@ -41,5 +42,5 @@
%pre{class: 'code highlight white'}
%code
- blame_group[:lines].each do |line|
:erb
<%= highlight(@blob.name, line, nowrap: true, continue: true).html_safe %>
:preserve
#{blame_highlighter.highlight(line)}

View file

@ -11,7 +11,7 @@
%td.old_line.diff-line-num{data: {linenumber: line_old}}
= link_to raw(line_old), "#"
%td.new_line= 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
%tr.line_holder{ id: @form.to }

View file

@ -20,6 +20,6 @@
- else
%td.old_line
%td.new_line
%td.line_content{class: "#{line.type}"}= raw diff_line_content(line.text)
%td.line_content{class: "#{line.type}"}= diff_line_content(line.text)
- else
.nothing-here-block No changes.

View file

@ -96,7 +96,7 @@
.center
.btn-group{ role: :group }
= 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'
.build-widget

View file

@ -9,5 +9,6 @@
= render "ci_menu"
- else
%div.block-connector
= render "projects/diffs/diffs", diffs: @diffs, project: @project
= render "projects/diffs/diffs", diffs: @diffs, project: @project,
diff_refs: @diff_refs
= render "projects/notes/notes_with_form"

View file

@ -9,7 +9,7 @@
- if @commits.present?
.prepend-top-default
= render "projects/commits/commit_list"
= render "projects/diffs/diffs", diffs: @diffs, project: @project
= render "projects/diffs/diffs", diffs: @diffs, project: @project, diff_refs: @diff_refs
- else
.light-well.prepend-top-default
.center

View file

@ -1,7 +1,7 @@
- if diff_view == 'parallel'
- fluid_layout true
- diff_files = safe_diff_files(diffs)
- diff_files = safe_diff_files(diffs, diff_refs)
.content-block.oneline-block
.inline-parallel-buttons

View file

@ -1,39 +1,37 @@
.diff-file{id: "diff-#{i}", data: diff_file_html_data(project, diff_commit, diff_file)}
.diff-header{id: "file-path-#{hexdigest(diff_file.file_path)}"}
.diff-file.file-holder{id: "diff-#{i}", data: diff_file_html_data(project, diff_commit, diff_file)}
.file-title{id: "file-path-#{hexdigest(diff_file.file_path)}"}
- if diff_file.diff.submodule?
%span
= icon('archive fw')
%strong
= submodule_link(blob, @commit.id, project.repository)
- else
%span
= blob_icon blob.mode, blob.name
= link_to "#diff-#{i}" do
%strong
= diff_file.new_path
= blob_icon blob.mode, blob.name
= link_to "#diff-#{i}" do
%strong
= diff_file.new_path
- if diff_file.deleted_file
deleted
- elsif diff_file.renamed_file
renamed from
%strong
= diff_file.old_path
- if diff_file.deleted_file
deleted
- elsif diff_file.renamed_file
renamed from
%strong
= diff_file.old_path
- if diff_file.mode_changed?
%small
= "#{diff_file.diff.a_mode} → #{diff_file.diff.b_mode}"
- if diff_file.mode_changed?
%small
= "#{diff_file.diff.a_mode} → #{diff_file.diff.b_mode}"
.diff-controls
.file-actions.hidden-xs
- 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
%i.fa.fa-comments
&nbsp;
= link_to '#', class: 'js-toggle-diff-comments btn active has_tooltip', title: "Toggle comments for this file" do
= icon('comments')
\
- if editable_diff?(diff_file)
= edit_blob_link(@merge_request.source_project,
@merge_request.source_branch, diff_file.new_path,
from_merge_request_id: @merge_request.id)
&nbsp;
= view_file_btn(diff_commit.id, diff_file, project)

View file

@ -1,42 +1,40 @@
/ Side-by-side diff view
%div.text-file.diff-wrap-lines
%div.text-file.diff-wrap-lines.code.file-content.js-syntax-highlight
%table
- parallel_diff(diff_file, index).each do |line|
- type_left = line[0]
- line_number_left = line[1]
- line_content_left = line[2]
- line_code_left = line[3]
- type_right = line[4]
- line_number_right = line[5]
- line_content_right = line[6]
- line_code_right = line[7]
- diff_file.parallel_diff_lines.each do |line|
- left = line[:left]
- right = line[:right]
%tr.line_holder.parallel
- if type_left == 'match'
= render "projects/diffs/match_line_parallel", { line: line_content_left,
line_old: line_number_left, line_new: line_number_right }
- elsif type_left == 'old' || type_left.nil?
%td.old_line{id: line_code_left, class: "#{type_left}"}
= link_to raw(line_number_left), "##{line_code_left}", id: line_code_left
- if left[:type] == 'match'
= render "projects/diffs/match_line_parallel", { line: left[:text],
line_old: left[:number], line_new: right[:number] }
- elsif left[:type] == 'nonewline'
%td.old_line
%td.line_content.parallel.matched= left[:text]
%td.new_line
%td.line_content.parallel.matched= left[:text]
- else
%td.old_line{id: left[:line_code], class: "#{left[:type]}"}
= link_to raw(left[:number]), "##{left[:line_code]}", id: left[:line_code]
- if @comments_allowed && can?(current_user, :create_note, @project)
= link_to_new_diff_note(line_code_left, 'old')
%td.line_content{class: "parallel noteable_line #{type_left} #{line_code_left}", "line_code" => line_code_left }= raw line_content_left
= 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])
- if type_right == 'new'
- if right[:type] == 'new'
- new_line_class = 'new'
- new_line_code = line_code_right
- new_line_code = right[:line_code]
- else
- new_line_class = nil
- new_line_code = line_code_left
- new_line_code = left[:line_code]
%td.new_line{id: new_line_code, class: "#{new_line_class}", data: { linenumber: line_number_right }}
= link_to raw(line_number_right), "##{new_line_code}", id: new_line_code
%td.new_line{id: new_line_code, class: "#{new_line_class}", data: { linenumber: right[:number] }}
= link_to raw(right[:number]), "##{new_line_code}", id: new_line_code
- if @comments_allowed && can?(current_user, :create_note, @project)
= link_to_new_diff_note(line_code_right, 'new')
%td.line_content.parallel{class: "noteable_line #{new_line_class} #{new_line_code}", "line_code" => new_line_code}= raw line_content_right
= 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])
- if @reply_allowed
- comments_left, comments_right = organize_comments(type_left, type_right, line_code_left, line_code_right)
- comments_left, comments_right = organize_comments(left[:type], right[:type], left[:line_code], right[:line_code])
- if comments_left.present? || comments_right.present?
= render "projects/notes/diff_notes_with_reply_parallel", notes_left: comments_left, notes_right: comments_right

View file

@ -3,9 +3,11 @@
.suppressed-container
%a.show-suppressed-diff.js-show-suppressed-diff Changes suppressed. Click to show.
%table.text-file{class: "#{'hide' if too_big}"}
%table.text-file.code.js-syntax-highlight{ class: too_big ? 'hide' : '' }
- last_line = 0
- diff_file.diff_lines.each_with_index do |line, index|
- raw_diff_lines = diff_file.diff_lines
- diff_file.highlighted_diff_lines.each_with_index do |line, index|
- type = line.type
- last_line = line.new_pos
- line_code = generate_line_code(diff_file.file_path, line)
@ -14,19 +16,23 @@
- if type == "match"
= render "projects/diffs/match_line", {line: line.text,
line_old: line_old, line_new: line.new_pos, bottom: false, new_file: diff_file.new_file}
- elsif type == 'nonewline'
%td.old_line.diff-line-num
%td.new_line.diff-line-num
%td.line_content.matched= line.text
- else
%td.old_line
= link_to raw(type == "new" ? "&nbsp;" : line_old), "##{line_code}", id: line_code
- if @comments_allowed && can?(current_user, :create_note, @project)
= link_to_new_diff_note(line_code)
%td.new_line{data: {linenumber: line.new_pos}}
= link_to raw(type == "old" ? "&nbsp;" : line.new_pos) , "##{line_code}", id: line_code
%td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw diff_line_content(line.text)
= 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)
- if @reply_allowed
- comments = @line_notes.select { |n| n.line_code == line_code && n.active? }.sort_by(&:created_at)
- 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
= render "projects/diffs/match_line", {line: "",

View file

@ -10,7 +10,7 @@
= link_to namespace_project_tree_path(@project.namespace, @project, @ref) do
= @project.path
%li.file-finder
%input#file_find.form-control.file-finder-input{type: "text", placeholder: 'Find by path'}
%input#file_find.form-control.file-finder-input{type: "text", placeholder: 'Find by path', autocomplete: 'off'}
%div.tree-content-holder
.table-holder

View file

@ -38,7 +38,7 @@
= render "projects/merge_requests/show/commits"
#diffs.diffs.tab-pane.active
- if @diffs.present?
= render "projects/diffs/diffs", diffs: @diffs, project: @project
= render "projects/diffs/diffs", diffs: @diffs, project: @project, diff_refs: @merge_request.diff_refs
- elsif @commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE
.alert.alert-danger
%h4 This comparison includes more than #{MergeRequestDiff::COMMITS_SAFE_SIZE} commits.

View file

@ -1,5 +1,6 @@
- if @merge_request_diff.collected?
= render "projects/diffs/diffs", diffs: params[:w] == '1' ? @merge_request.diffs_no_whitespace : @merge_request.diffs, project: @merge_request.project
= render "projects/diffs/diffs", diffs: params[:w] == '1' ? @merge_request.diffs_no_whitespace : @merge_request.diffs,
project: @merge_request.project, diff_refs: @merge_request.diff_refs
- elsif @merge_request_diff.empty?
.nothing-here-block Nothing to merge from #{@merge_request.source_branch} into #{@merge_request.target_branch}
- else

View file

@ -24,7 +24,7 @@
= raw(type == "new" ? "&nbsp;" : line.old_pos)
%td.new_line
= raw(type == "old" ? "&nbsp;" : line.new_pos)
%td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw diff_line_content(line.text)
%td.line_content{class: "noteable_line #{type} #{line_code}", line_code: line_code}= diff_line_content(line.text)
- if line_code == note.line_code
= render "projects/notes/diff_notes_with_reply", notes: discussion_notes

View file

@ -9,5 +9,4 @@
%i.fa.fa-link
= i
.blob-content{data: {blob_id: blob.id}}
:preserve
#{highlight(blob.name, blob.data)}
= highlight(blob.name, blob.data)

View file

@ -7,8 +7,11 @@ if defined?(Unicorn)
# Unicorn self-process killer
require 'unicorn/worker_killer'
min = (ENV['GITLAB_UNICORN_MEMORY_MIN'] || 300 * 1 << 20).to_i
max = (ENV['GITLAB_UNICORN_MEMORY_MAX'] || 350 * 1 << 20).to_i
# Max memory size (RSS) per worker
use Unicorn::WorkerKiller::Oom, (200 * (1 << 20)), (250 * (1 << 20))
use Unicorn::WorkerKiller::Oom, min, max
end
end

View file

@ -9,13 +9,8 @@ class Settings < Settingslogic
gitlab.port.to_i == (gitlab.https ? 443 : 80)
end
# get host without www, thanks to http://stackoverflow.com/a/6674363/1233435
def get_host_without_www(url)
url = CGI.escape(url)
uri = URI.parse(url)
uri = URI.parse("http://#{url}") if uri.scheme.nil?
host = uri.host.downcase
host.start_with?('www.') ? host[4..-1] : host
def host_without_www(url)
host(url).sub('www.', '')
end
def build_gitlab_ci_url
@ -87,6 +82,17 @@ class Settings < Settingslogic
custom_port
]
end
# Extract the host part of the given +url+.
def host(url)
url = url.downcase
url = "http://#{url}" unless url.start_with?('http')
# Get rid of the path so that we don't even have to encode it
url_without_path = url.sub(%r{(https?://[^\/]+)/?.*}, '\1')
URI.parse(url_without_path).host
end
end
end
@ -228,7 +234,7 @@ Settings['gravatar'] ||= Settingslogic.new({})
Settings.gravatar['enabled'] = true if Settings.gravatar['enabled'].nil?
Settings.gravatar['plain_url'] ||= 'http://www.gravatar.com/avatar/%{hash}?s=%{size}&d=identicon'
Settings.gravatar['ssl_url'] ||= 'https://secure.gravatar.com/avatar/%{hash}?s=%{size}&d=identicon'
Settings.gravatar['host'] = Settings.get_host_without_www(Settings.gravatar['plain_url'])
Settings.gravatar['host'] = Settings.host_without_www(Settings.gravatar['plain_url'])
#
# Cron Jobs

View file

@ -0,0 +1,19 @@
# Be sure to restart your server when you modify this file.
require 'gitlab/current_settings'
include Gitlab::CurrentSettings
if Rails.env.production?
# allow it to fail: it may do so when create_from_defaults is executed before migrations are actually done
begin
sentry_enabled = current_application_settings.sentry_enabled
rescue
sentry_enabled = false
end
if sentry_enabled
Raven.configure do |config|
config.dsn = current_application_settings.sentry_dsn
end
end
end

View file

@ -0,0 +1,8 @@
class AddSentryToApplicationSettings < ActiveRecord::Migration
def change
change_table :application_settings do |t|
t.boolean :sentry_enabled, default: false
t.string :sentry_dsn
end
end
end

View file

@ -0,0 +1,6 @@
class AddIpBlockingSettingsToApplicationSettings < ActiveRecord::Migration
def change
add_column :application_settings, :ip_blocking_enabled, :boolean, default: false
add_column :application_settings, :dnsbl_servers_list, :text
end
end

View file

@ -0,0 +1,39 @@
class AddServicesCategory < ActiveRecord::Migration
def up
add_column :services, :category, :string, default: 'common', null: false
category = quote_column_name('category')
type = quote_column_name('type')
execute <<-EOF
UPDATE services
SET #{category} = 'issue_tracker'
WHERE #{type} IN (
'CustomIssueTrackerService',
'GitlabIssueTrackerService',
'IssueTrackerService',
'JiraService',
'RedmineService'
);
EOF
execute <<-EOF
UPDATE services
SET #{category} = 'ci'
WHERE #{type} IN (
'BambooService',
'BuildkiteService',
'CiService',
'DroneCiService',
'GitlabCiService',
'TeamcityService'
);
EOF
add_index :services, :category
end
def down
remove_column :services, :category
end
end

View file

@ -0,0 +1,20 @@
class AddServicesDefault < ActiveRecord::Migration
def up
add_column :services, :default, :boolean, default: false
default = quote_column_name('default')
type = quote_column_name('type')
execute <<-EOF
UPDATE services
SET #{default} = true
WHERE #{type} = 'GitlabIssueTrackerService'
EOF
add_index :services, :default
end
def down
remove_column :services, :default
end
end

View file

@ -0,0 +1,30 @@
class AddLdapEmailToUsers < ActiveRecord::Migration
def up
add_column :users, :ldap_email, :boolean, default: false, null: false
if Gitlab::Database.mysql?
execute %{
UPDATE users, identities
SET users.ldap_email = TRUE
WHERE identities.user_id = users.id
AND users.email LIKE 'temp-email-for-oauth%'
AND identities.provider LIKE 'ldap%'
AND identities.extern_uid IS NOT NULL
}
else
execute %{
UPDATE users
SET ldap_email = TRUE
FROM identities
WHERE identities.user_id = users.id
AND users.email LIKE 'temp-email-for-oauth%'
AND identities.provider LIKE 'ldap%'
AND identities.extern_uid IS NOT NULL
}
end
end
def down
remove_column :users, :ldap_email
end
end

Some files were not shown because too many files have changed in this diff Show more