Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/assets/images/bg-header.pngbin90 -> 0 bytes
-rw-r--r--app/assets/images/bg_fallback.pngbin167 -> 0 bytes
-rw-r--r--app/assets/images/chosen-sprite.pngbin367 -> 0 bytes
-rw-r--r--app/assets/images/diff_note_add.pngbin418 -> 0 bytes
-rw-r--r--app/assets/images/icon-search.pngbin222 -> 0 bytes
-rw-r--r--app/assets/images/icon_sprite.pngbin2636 -> 0 bytes
-rw-r--r--app/assets/images/images.pngbin5806 -> 0 bytes
-rw-r--r--app/assets/images/move.pngbin197 -> 0 bytes
-rw-r--r--app/assets/images/progress_bar.gifbin494 -> 0 bytes
-rw-r--r--app/assets/images/slider_handles.pngbin1341 -> 0 bytes
-rw-r--r--app/assets/javascripts/application.js6
-rw-r--r--app/assets/javascripts/diff.js29
-rw-r--r--app/assets/javascripts/dispatcher.js4
-rw-r--r--app/assets/javascripts/gl_dropdown.js46
-rw-r--r--app/assets/javascripts/lib/utils/datetime_utility.js38
-rw-r--r--app/assets/javascripts/project.js10
-rw-r--r--app/assets/javascripts/protected_branch_access_dropdown.js.es624
-rw-r--r--app/assets/javascripts/protected_branch_create.js.es656
-rw-r--r--app/assets/javascripts/protected_branch_dropdown.js.es675
-rw-r--r--app/assets/javascripts/protected_branch_edit.js.es661
-rw-r--r--app/assets/javascripts/protected_branch_edit_list.js.es617
-rw-r--r--app/assets/javascripts/protected_branch_select.js72
-rw-r--r--app/assets/javascripts/protected_branches_access_select.js.es663
-rw-r--r--app/assets/javascripts/users_select.js38
-rw-r--r--app/assets/stylesheets/framework/dropdowns.scss8
-rw-r--r--app/assets/stylesheets/framework/lists.scss11
-rw-r--r--app/assets/stylesheets/framework/panels.scss5
-rw-r--r--app/assets/stylesheets/framework/variables.scss1
-rw-r--r--app/assets/stylesheets/pages/groups.scss8
-rw-r--r--app/assets/stylesheets/pages/labels.scss11
-rw-r--r--app/assets/stylesheets/pages/projects.scss31
-rw-r--r--app/controllers/concerns/diff_for_path.rb6
-rw-r--r--app/controllers/import/gitlab_projects_controller.rb7
-rw-r--r--app/controllers/profiles/passwords_controller.rb1
-rw-r--r--app/controllers/projects/badges_controller.rb3
-rw-r--r--app/controllers/projects/blob_controller.rb2
-rw-r--r--app/controllers/projects/commit_controller.rb2
-rw-r--r--app/controllers/projects/compare_controller.rb16
-rw-r--r--app/controllers/projects/deploy_keys_controller.rb20
-rw-r--r--app/controllers/projects/git_http_controller.rb39
-rw-r--r--app/controllers/projects/merge_requests_controller.rb11
-rw-r--r--app/controllers/projects/pipelines_settings_controller.rb2
-rw-r--r--app/controllers/projects_controller.rb2
-rw-r--r--app/controllers/registrations_controller.rb2
-rw-r--r--app/controllers/sessions_controller.rb2
-rw-r--r--app/helpers/application_helper.rb8
-rw-r--r--app/helpers/avatars_helper.rb2
-rw-r--r--app/helpers/commits_helper.rb4
-rw-r--r--app/helpers/diff_helper.rb43
-rw-r--r--app/helpers/explore_helper.rb2
-rw-r--r--app/helpers/search_helper.rb2
-rw-r--r--app/helpers/tree_helper.rb18
-rw-r--r--app/models/ability.rb4
-rw-r--r--app/models/commit.rb12
-rw-r--r--app/models/compare.rb66
-rw-r--r--app/models/concerns/faster_cache_keys.rb16
-rw-r--r--app/models/issue.rb1
-rw-r--r--app/models/legacy_diff_note.rb4
-rw-r--r--app/models/members/project_member.rb6
-rw-r--r--app/models/merge_request.rb14
-rw-r--r--app/models/merge_request_diff.rb10
-rw-r--r--app/models/note.rb1
-rw-r--r--app/models/project.rb28
-rw-r--r--app/models/project_team.rb2
-rw-r--r--app/models/repository.rb8
-rw-r--r--app/services/compare_service.rb6
-rw-r--r--app/services/delete_user_service.rb2
-rw-r--r--app/services/destroy_group_service.rb2
-rw-r--r--app/services/import_export_clean_up_service.rb24
-rw-r--r--app/services/merge_requests/build_service.rb2
-rw-r--r--app/services/merge_requests/merge_request_diff_cache_service.rb8
-rw-r--r--app/services/projects/destroy_service.rb8
-rw-r--r--app/services/projects/enable_deploy_key_service.rb17
-rw-r--r--app/services/repository_archive_clean_up_service.rb4
-rw-r--r--app/views/admin/application_settings/_form.html.haml9
-rw-r--r--app/views/admin/dashboard/index.html.haml2
-rw-r--r--app/views/admin/users/show.html.haml8
-rw-r--r--app/views/devise/sessions/_new_crowd.html.haml2
-rw-r--r--app/views/devise/shared/_omniauth_box.html.haml2
-rw-r--r--app/views/import/github/status.html.haml4
-rw-r--r--app/views/notify/new_issue_email.text.erb2
-rw-r--r--app/views/notify/new_merge_request_email.text.erb2
-rw-r--r--app/views/profiles/accounts/show.html.haml2
-rw-r--r--app/views/projects/badges/badge.svg.erb36
-rw-r--r--app/views/projects/blob/diff.html.haml34
-rw-r--r--app/views/projects/ci/pipelines/_pipeline.html.haml2
-rw-r--r--app/views/projects/commit/_ci_menu.html.haml2
-rw-r--r--app/views/projects/commit/show.html.haml2
-rw-r--r--app/views/projects/compare/show.html.haml2
-rw-r--r--app/views/projects/diffs/_content.html.haml2
-rw-r--r--app/views/projects/diffs/_diffs.html.haml19
-rw-r--r--app/views/projects/diffs/_file.html.haml8
-rw-r--r--app/views/projects/diffs/_line.html.haml3
-rw-r--r--app/views/projects/diffs/_match_line.html.haml7
-rw-r--r--app/views/projects/diffs/_parallel_view.html.haml10
-rw-r--r--app/views/projects/diffs/_text_file.html.haml5
-rw-r--r--app/views/projects/merge_requests/_new_submit.html.haml2
-rw-r--r--app/views/projects/merge_requests/_show.html.haml2
-rw-r--r--app/views/projects/merge_requests/show/_diffs.html.haml3
-rw-r--r--app/views/projects/new.html.haml38
-rw-r--r--app/views/projects/protected_branches/_branches_list.html.haml50
-rw-r--r--app/views/projects/protected_branches/_create_protected_branch.html.haml36
-rw-r--r--app/views/projects/protected_branches/_dropdown.html.haml12
-rw-r--r--app/views/projects/protected_branches/_protected_branch.html.haml17
-rw-r--r--app/views/projects/protected_branches/index.html.haml36
-rw-r--r--app/views/projects/tree/_tree_row.html.haml6
-rw-r--r--app/views/shared/_labels_row.html.haml6
-rw-r--r--app/views/shared/projects/_project.html.haml2
-rw-r--r--app/views/shared/web_hooks/_form.html.haml2
-rw-r--r--app/workers/emails_on_push_worker.rb19
-rw-r--r--app/workers/import_export_project_cleanup_worker.rb (renamed from app/workers/gitlab_remove_project_export_worker.rb)4
-rw-r--r--app/workers/irker_worker.rb6
-rw-r--r--app/workers/post_receive.rb4
-rw-r--r--app/workers/project_destroy_worker.rb2
114 files changed, 908 insertions, 557 deletions
diff --git a/app/assets/images/bg-header.png b/app/assets/images/bg-header.png
deleted file mode 100644
index 639271c6faf..00000000000
--- a/app/assets/images/bg-header.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/bg_fallback.png b/app/assets/images/bg_fallback.png
deleted file mode 100644
index 5c55bc79dec..00000000000
--- a/app/assets/images/bg_fallback.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/chosen-sprite.png b/app/assets/images/chosen-sprite.png
deleted file mode 100644
index 3d936b07d44..00000000000
--- a/app/assets/images/chosen-sprite.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/diff_note_add.png b/app/assets/images/diff_note_add.png
deleted file mode 100644
index 0084422e330..00000000000
--- a/app/assets/images/diff_note_add.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icon-search.png b/app/assets/images/icon-search.png
deleted file mode 100644
index 3c1c146541d..00000000000
--- a/app/assets/images/icon-search.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/icon_sprite.png b/app/assets/images/icon_sprite.png
deleted file mode 100644
index 2e7a5023398..00000000000
--- a/app/assets/images/icon_sprite.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/images.png b/app/assets/images/images.png
deleted file mode 100644
index bd60de994c4..00000000000
--- a/app/assets/images/images.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/move.png b/app/assets/images/move.png
deleted file mode 100644
index 6a0567f8f25..00000000000
--- a/app/assets/images/move.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/progress_bar.gif b/app/assets/images/progress_bar.gif
deleted file mode 100644
index c3d43fa40b2..00000000000
--- a/app/assets/images/progress_bar.gif
+++ /dev/null
Binary files differ
diff --git a/app/assets/images/slider_handles.png b/app/assets/images/slider_handles.png
deleted file mode 100644
index 52ad11ab7a1..00000000000
--- a/app/assets/images/slider_handles.png
+++ /dev/null
Binary files differ
diff --git a/app/assets/javascripts/application.js b/app/assets/javascripts/application.js
index 127e568adc9..f1aab067351 100644
--- a/app/assets/javascripts/application.js
+++ b/app/assets/javascripts/application.js
@@ -287,7 +287,7 @@
$('.page-with-sidebar').toggleClass('page-sidebar-collapsed page-sidebar-expanded').removeClass('page-sidebar-pinned');
$('.navbar-fixed-top').removeClass('header-pinned-nav');
}
- return $document.off('click', '.js-nav-pin').on('click', '.js-nav-pin', function(e) {
+ $document.off('click', '.js-nav-pin').on('click', '.js-nav-pin', function(e) {
var $page, $pinBtn, $tooltip, $topNav, doPinNav, tooltipText;
e.preventDefault();
$pinBtn = $(e.currentTarget);
@@ -315,6 +315,8 @@
$tooltip.find('.tooltip-inner').text(tooltipText);
return $pinBtn.attr('title', tooltipText).tooltip('fixTitle');
});
- });
+ // Custom time ago
+ gl.utils.shortTimeAgo($('.js-short-timeago'));
+ });
}).call(this);
diff --git a/app/assets/javascripts/diff.js b/app/assets/javascripts/diff.js
index 298f3852085..3dd7ceba92f 100644
--- a/app/assets/javascripts/diff.js
+++ b/app/assets/javascripts/diff.js
@@ -10,7 +10,7 @@
$(document).off('click', '.js-unfold');
$(document).on('click', '.js-unfold', (function(_this) {
return function(event) {
- var line_number, link, offset, old_line, params, prev_new_line, prev_old_line, ref, ref1, since, target, to, unfold, unfoldBottom;
+ var line_number, link, file, offset, old_line, params, prev_new_line, prev_old_line, ref, ref1, since, target, to, unfold, unfoldBottom;
target = $(event.target);
unfoldBottom = target.hasClass('js-unfold-bottom');
unfold = true;
@@ -31,14 +31,16 @@
unfold = false;
}
}
- link = target.parents('.diff-file').attr('data-blob-diff-path');
+ file = target.parents('.diff-file');
+ link = file.data('blob-diff-path');
params = {
since: since,
to: to,
bottom: unfoldBottom,
offset: offset,
unfold: unfold,
- indent: 1
+ indent: 1,
+ view: file.data('view')
};
return $.get(link, params, function(response) {
return target.parent().replaceWith(response);
@@ -48,26 +50,13 @@
}
Diff.prototype.lineNumbers = function(line) {
- var i, l, len, line_number, line_numbers, lines, results;
if (!line.children().length) {
return [0, 0];
}
- lines = line.children().slice(0, 2);
- line_numbers = (function() {
- var i, len, results;
- results = [];
- for (i = 0, len = lines.length; i < len; i++) {
- l = lines[i];
- results.push($(l).attr('data-linenumber'));
- }
- return results;
- })();
- results = [];
- for (i = 0, len = line_numbers.length; i < len; i++) {
- line_number = line_numbers[i];
- results.push(parseInt(line_number));
- }
- return results;
+
+ return line.find('.diff-line-num').map(function() {
+ return parseInt($(this).data('linenumber'));
+ });
};
return Diff;
diff --git a/app/assets/javascripts/dispatcher.js b/app/assets/javascripts/dispatcher.js
index 9e6901962c6..20f2b1d69b5 100644
--- a/app/assets/javascripts/dispatcher.js
+++ b/app/assets/javascripts/dispatcher.js
@@ -173,8 +173,8 @@
new Search();
break;
case 'projects:protected_branches:index':
- new ProtectedBranchesAccessSelect($(".new_protected_branch"), false, true);
- new ProtectedBranchesAccessSelect($(".protected-branches-list"), true, false);
+ new gl.ProtectedBranchCreate();
+ new gl.ProtectedBranchEditList();
break;
}
switch (path.first()) {
diff --git a/app/assets/javascripts/gl_dropdown.js b/app/assets/javascripts/gl_dropdown.js
index c5d92831fbe..d3394fae3f9 100644
--- a/app/assets/javascripts/gl_dropdown.js
+++ b/app/assets/javascripts/gl_dropdown.js
@@ -28,38 +28,43 @@
};
})(this));
timeout = "";
- this.input.on("keyup", (function(_this) {
- return function(e) {
+ this.input
+ .on('keydown', function (e) {
+ var keyCode = e.which;
+
+ if (keyCode === 13) {
+ e.preventDefault()
+ }
+ })
+ .on('keyup', function(e) {
var keyCode;
keyCode = e.which;
if (ARROW_KEY_CODES.indexOf(keyCode) >= 0) {
return;
}
- if (_this.input.val() !== "" && !$inputContainer.hasClass(HAS_VALUE_CLASS)) {
+ if (this.input.val() !== "" && !$inputContainer.hasClass(HAS_VALUE_CLASS)) {
$inputContainer.addClass(HAS_VALUE_CLASS);
- } else if (_this.input.val() === "" && $inputContainer.hasClass(HAS_VALUE_CLASS)) {
+ } else if (this.input.val() === "" && $inputContainer.hasClass(HAS_VALUE_CLASS)) {
$inputContainer.removeClass(HAS_VALUE_CLASS);
}
if (keyCode === 13) {
return false;
}
- if (_this.options.remote) {
+ if (this.options.remote) {
clearTimeout(timeout);
return timeout = setTimeout(function() {
- var blur_field;
- blur_field = _this.shouldBlur(keyCode);
- if (blur_field && _this.filterInputBlur) {
- _this.input.blur();
+ var blurField = this.shouldBlur(keyCode);
+ if (blurField && this.filterInputBlur) {
+ this.input.blur();
}
- return _this.options.query(_this.input.val(), function(data) {
- return _this.options.callback(data);
- });
- }, 250);
+ return this.options.query(this.input.val(), function(data) {
+ return this.options.callback(data);
+ }.bind(this));
+ }.bind(this), 250);
} else {
- return _this.filter(_this.input.val());
+ return this.filter(this.input.val());
}
- };
- })(this));
+ }.bind(this));
}
GitLabDropdownFilter.prototype.shouldBlur = function(keyCode) {
@@ -382,6 +387,7 @@
GitLabDropdown.prototype.opened = function() {
var contentHtml;
+ currentIndex = -1;
this.addArrowKeyEvent();
if (this.options.setIndeterminateIds) {
this.options.setIndeterminateIds.call(this);
@@ -601,7 +607,7 @@
return this.dropdown.before($input);
};
- GitLabDropdown.prototype.selectRowAtIndex = function(e, index) {
+ GitLabDropdown.prototype.selectRowAtIndex = function(index) {
var $el, selector;
selector = ".dropdown-content li:not(.divider,.dropdown-header,.separator):eq(" + index + ") a";
if (this.dropdown.find(".dropdown-toggle-page").length) {
@@ -609,8 +615,6 @@
}
$el = $(selector, this.dropdown);
if ($el.length) {
- e.preventDefault();
- e.stopImmediatePropagation();
return $el.first().trigger('click');
}
};
@@ -619,7 +623,7 @@
var $input, ARROW_KEY_CODES, selector;
ARROW_KEY_CODES = [38, 40];
$input = this.dropdown.find(".dropdown-input-field");
- selector = '.dropdown-content li:not(.divider,.dropdown-header,.separator)';
+ selector = '.dropdown-content li:not(.divider,.dropdown-header,.separator):visible';
if (this.dropdown.find(".dropdown-toggle-page").length) {
selector = ".dropdown-page-one " + selector;
}
@@ -647,7 +651,7 @@
return false;
}
if (currentKeyCode === 13 && currentIndex !== -1) {
- return _this.selectRowAtIndex(e, currentIndex);
+ return _this.selectRowAtIndex($('.is-focused', _this.dropdown).closest('li').index() - 1);
}
};
})(this));
diff --git a/app/assets/javascripts/lib/utils/datetime_utility.js b/app/assets/javascripts/lib/utils/datetime_utility.js
index e817261f210..10afa7e4329 100644
--- a/app/assets/javascripts/lib/utils/datetime_utility.js
+++ b/app/assets/javascripts/lib/utils/datetime_utility.js
@@ -8,13 +8,16 @@
base.utils = {};
}
w.gl.utils.days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
+
w.gl.utils.formatDate = function(datetime) {
return dateFormat(datetime, 'mmm d, yyyy h:MMtt Z');
};
+
w.gl.utils.getDayName = function(date) {
return this.days[date.getDay()];
};
- return w.gl.utils.localTimeAgo = function($timeagoEls, setTimeago) {
+
+ w.gl.utils.localTimeAgo = function($timeagoEls, setTimeago) {
if (setTimeago == null) {
setTimeago = true;
}
@@ -31,6 +34,39 @@
});
}
};
+
+ w.gl.utils.shortTimeAgo = function($el) {
+ var shortLocale, tmpLocale;
+ shortLocale = {
+ prefixAgo: null,
+ prefixFromNow: null,
+ suffixAgo: 'ago',
+ suffixFromNow: 'from now',
+ seconds: '1 min',
+ minute: '1 min',
+ minutes: '%d mins',
+ hour: '1 hr',
+ hours: '%d hrs',
+ day: '1 day',
+ days: '%d days',
+ month: '1 month',
+ months: '%d months',
+ year: '1 year',
+ years: '%d years',
+ wordSeparator: ' ',
+ numbers: []
+ };
+ tmpLocale = $.timeago.settings.strings;
+ $el.each(function(el) {
+ var $el1;
+ $el1 = $(this);
+ return $el1.attr('title', gl.utils.formatDate($el.attr('datetime')));
+ });
+ $.timeago.settings.strings = shortLocale;
+ $el.timeago();
+ $.timeago.settings.strings = tmpLocale;
+ };
+
})(window);
}).call(this);
diff --git a/app/assets/javascripts/project.js b/app/assets/javascripts/project.js
index e6663177161..b97f6d22715 100644
--- a/app/assets/javascripts/project.js
+++ b/app/assets/javascripts/project.js
@@ -89,8 +89,14 @@
toggleLabel: function(obj, $el) {
return $el.text().trim();
},
- clicked: function(e) {
- return $dropdown.closest('form').submit();
+ clicked: function(selected, $el, e) {
+ e.preventDefault()
+ if ($('input[name="ref"]').length) {
+ var $form = $dropdown.closest('form'),
+ action = $form.attr('action'),
+ divider = action.indexOf('?') < 0 ? '?' : '&';
+ Turbolinks.visit(action + '' + divider + '' + $form.serialize());
+ }
}
});
});
diff --git a/app/assets/javascripts/protected_branch_access_dropdown.js.es6 b/app/assets/javascripts/protected_branch_access_dropdown.js.es6
new file mode 100644
index 00000000000..2fbb088fa04
--- /dev/null
+++ b/app/assets/javascripts/protected_branch_access_dropdown.js.es6
@@ -0,0 +1,24 @@
+(global => {
+ global.gl = global.gl || {};
+
+ gl.ProtectedBranchAccessDropdown = class {
+ constructor(options) {
+ const { $dropdown, data, onSelect } = options;
+
+ $dropdown.glDropdown({
+ data: data,
+ selectable: true,
+ inputId: $dropdown.data('input-id'),
+ fieldName: $dropdown.data('field-name'),
+ toggleLabel(item) {
+ return item.text;
+ },
+ clicked(item, $el, e) {
+ e.preventDefault();
+ onSelect();
+ }
+ });
+ }
+ }
+
+})(window);
diff --git a/app/assets/javascripts/protected_branch_create.js.es6 b/app/assets/javascripts/protected_branch_create.js.es6
new file mode 100644
index 00000000000..00e20a03b04
--- /dev/null
+++ b/app/assets/javascripts/protected_branch_create.js.es6
@@ -0,0 +1,56 @@
+(global => {
+ global.gl = global.gl || {};
+
+ gl.ProtectedBranchCreate = class {
+ constructor() {
+ this.$wrap = this.$form = $('#new_protected_branch');
+ this.buildDropdowns();
+ }
+
+ buildDropdowns() {
+ const $allowedToMergeDropdown = this.$wrap.find('.js-allowed-to-merge');
+ const $allowedToPushDropdown = this.$wrap.find('.js-allowed-to-push');
+
+ // Cache callback
+ this.onSelectCallback = this.onSelect.bind(this);
+
+ // Allowed to Merge dropdown
+ new gl.ProtectedBranchAccessDropdown({
+ $dropdown: $allowedToMergeDropdown,
+ data: gon.merge_access_levels,
+ onSelect: this.onSelectCallback
+ });
+
+ // Allowed to Push dropdown
+ new gl.ProtectedBranchAccessDropdown({
+ $dropdown: $allowedToPushDropdown,
+ data: gon.push_access_levels,
+ onSelect: this.onSelectCallback
+ });
+
+ // Select default
+ $allowedToPushDropdown.data('glDropdown').selectRowAtIndex(0);
+ $allowedToMergeDropdown.data('glDropdown').selectRowAtIndex(0);
+
+ // Protected branch dropdown
+ new ProtectedBranchDropdown({
+ $dropdown: this.$wrap.find('.js-protected-branch-select'),
+ onSelect: this.onSelectCallback
+ });
+ }
+
+ // This will run after clicked callback
+ onSelect() {
+
+ // Enable submit button
+ const $branchInput = this.$wrap.find('input[name="protected_branch[name]"]');
+ const $allowedToMergeInput = this.$wrap.find('input[name="protected_branch[merge_access_level_attributes][access_level]"]');
+ const $allowedToPushInput = this.$wrap.find('input[name="protected_branch[push_access_level_attributes][access_level]"]');
+
+ if ($branchInput.val() && $allowedToMergeInput.val() && $allowedToPushInput.val()){
+ this.$form.find('input[type="submit"]').removeAttr('disabled');
+ }
+ }
+ }
+
+})(window);
diff --git a/app/assets/javascripts/protected_branch_dropdown.js.es6 b/app/assets/javascripts/protected_branch_dropdown.js.es6
new file mode 100644
index 00000000000..6738dc8862d
--- /dev/null
+++ b/app/assets/javascripts/protected_branch_dropdown.js.es6
@@ -0,0 +1,75 @@
+class ProtectedBranchDropdown {
+ constructor(options) {
+ this.onSelect = options.onSelect;
+ this.$dropdown = options.$dropdown;
+ this.$dropdownContainer = this.$dropdown.parent();
+ this.$dropdownFooter = this.$dropdownContainer.find('.dropdown-footer');
+ this.$protectedBranch = this.$dropdownContainer.find('.create-new-protected-branch');
+
+ this.buildDropdown();
+ this.bindEvents();
+
+ // Hide footer
+ this.$dropdownFooter.addClass('hidden');
+ }
+
+ buildDropdown() {
+ this.$dropdown.glDropdown({
+ data: this.getProtectedBranches.bind(this),
+ filterable: true,
+ remote: false,
+ search: {
+ fields: ['title']
+ },
+ selectable: true,
+ toggleLabel(selected) {
+ return (selected && 'id' in selected) ? selected.title : 'Protected Branch';
+ },
+ fieldName: 'protected_branch[name]',
+ text(protectedBranch) {
+ return _.escape(protectedBranch.title);
+ },
+ id(protectedBranch) {
+ return _.escape(protectedBranch.id);
+ },
+ onFilter: this.toggleCreateNewButton.bind(this),
+ clicked: (item, $el, e) => {
+ e.preventDefault();
+ this.onSelect();
+ }
+ });
+ }
+
+ bindEvents() {
+ this.$protectedBranch.on('click', this.onClickCreateWildcard.bind(this));
+ }
+
+ onClickCreateWildcard() {
+ this.$dropdown.data('glDropdown').remote.execute();
+ this.$dropdown.data('glDropdown').selectRowAtIndex(0);
+ }
+
+ getProtectedBranches(term, callback) {
+ if (this.selectedBranch) {
+ callback(gon.open_branches.concat(this.selectedBranch));
+ } else {
+ callback(gon.open_branches);
+ }
+ }
+
+ toggleCreateNewButton(branchName) {
+ this.selectedBranch = {
+ title: branchName,
+ id: branchName,
+ text: branchName
+ };
+
+ if (branchName) {
+ this.$dropdownContainer
+ .find('.create-new-protected-branch code')
+ .text(branchName);
+ }
+
+ this.$dropdownFooter.toggleClass('hidden', !branchName);
+ }
+}
diff --git a/app/assets/javascripts/protected_branch_edit.js.es6 b/app/assets/javascripts/protected_branch_edit.js.es6
new file mode 100644
index 00000000000..8d42e268ebc
--- /dev/null
+++ b/app/assets/javascripts/protected_branch_edit.js.es6
@@ -0,0 +1,61 @@
+(global => {
+ global.gl = global.gl || {};
+
+ gl.ProtectedBranchEdit = class {
+ constructor(options) {
+ this.$wrap = options.$wrap;
+ this.$allowedToMergeDropdown = this.$wrap.find('.js-allowed-to-merge');
+ this.$allowedToPushDropdown = this.$wrap.find('.js-allowed-to-push');
+
+ this.buildDropdowns();
+ }
+
+ buildDropdowns() {
+
+ // Allowed to merge dropdown
+ new gl.ProtectedBranchAccessDropdown({
+ $dropdown: this.$allowedToMergeDropdown,
+ data: gon.merge_access_levels,
+ onSelect: this.onSelect.bind(this)
+ });
+
+ // Allowed to push dropdown
+ new gl.ProtectedBranchAccessDropdown({
+ $dropdown: this.$allowedToPushDropdown,
+ data: gon.push_access_levels,
+ onSelect: this.onSelect.bind(this)
+ });
+ }
+
+ onSelect() {
+ const $allowedToMergeInput = this.$wrap.find(`input[name="${this.$allowedToMergeDropdown.data('fieldName')}"]`);
+ const $allowedToPushInput = this.$wrap.find(`input[name="${this.$allowedToPushDropdown.data('fieldName')}"]`);
+
+ $.ajax({
+ type: 'POST',
+ url: this.$wrap.data('url'),
+ dataType: 'json',
+ data: {
+ _method: 'PATCH',
+ id: this.$wrap.data('banchId'),
+ protected_branch: {
+ merge_access_level_attributes: {
+ access_level: $allowedToMergeInput.val()
+ },
+ push_access_level_attributes: {
+ access_level: $allowedToPushInput.val()
+ }
+ }
+ },
+ success: () => {
+ this.$wrap.effect('highlight');
+ },
+ error() {
+ $.scrollTo(0);
+ new Flash('Failed to update branch!');
+ }
+ });
+ }
+ }
+
+})(window);
diff --git a/app/assets/javascripts/protected_branch_edit_list.js.es6 b/app/assets/javascripts/protected_branch_edit_list.js.es6
new file mode 100644
index 00000000000..9ff0fd12c76
--- /dev/null
+++ b/app/assets/javascripts/protected_branch_edit_list.js.es6
@@ -0,0 +1,17 @@
+(global => {
+ global.gl = global.gl || {};
+
+ gl.ProtectedBranchEditList = class {
+ constructor() {
+ this.$wrap = $('.protected-branches-list');
+
+ // Build edit forms
+ this.$wrap.find('.js-protected-branch-edit-form').each((i, el) => {
+ new gl.ProtectedBranchEdit({
+ $wrap: $(el)
+ });
+ });
+ }
+ }
+
+})(window);
diff --git a/app/assets/javascripts/protected_branch_select.js b/app/assets/javascripts/protected_branch_select.js
deleted file mode 100644
index 3a47fc972dc..00000000000
--- a/app/assets/javascripts/protected_branch_select.js
+++ /dev/null
@@ -1,72 +0,0 @@
-(function() {
- var bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; };
-
- this.ProtectedBranchSelect = (function() {
- function ProtectedBranchSelect(currentProject) {
- this.toggleCreateNewButton = bind(this.toggleCreateNewButton, this);
- this.getProtectedBranches = bind(this.getProtectedBranches, this);
- $('.dropdown-footer').hide();
- this.dropdown = $('.js-protected-branch-select').glDropdown({
- data: this.getProtectedBranches,
- filterable: true,
- remote: false,
- search: {
- fields: ['title']
- },
- selectable: true,
- toggleLabel: function(selected) {
- if (selected && 'id' in selected) {
- return selected.title;
- } else {
- return 'Protected Branch';
- }
- },
- fieldName: 'protected_branch[name]',
- text: function(protected_branch) {
- return _.escape(protected_branch.title);
- },
- id: function(protected_branch) {
- return _.escape(protected_branch.id);
- },
- onFilter: this.toggleCreateNewButton,
- clicked: function() {
- return $('.protect-branch-btn').attr('disabled', false);
- }
- });
- $('.create-new-protected-branch').on('click', (function(_this) {
- return function(event) {
- _this.dropdown.data('glDropdown').remote.execute();
- return _this.dropdown.data('glDropdown').selectRowAtIndex(event, 0);
- };
- })(this));
- }
-
- ProtectedBranchSelect.prototype.getProtectedBranches = function(term, callback) {
- if (this.selectedBranch) {
- return callback(gon.open_branches.concat(this.selectedBranch));
- } else {
- return callback(gon.open_branches);
- }
- };
-
- ProtectedBranchSelect.prototype.toggleCreateNewButton = function(branchName) {
- this.selectedBranch = {
- title: branchName,
- id: branchName,
- text: branchName
- };
- if (branchName === '') {
- $('.protected-branch-select-footer-list').addClass('hidden');
- return $('.dropdown-footer').hide();
- } else {
- $('.create-new-protected-branch').text("Create Protected Branch: " + branchName);
- $('.protected-branch-select-footer-list').removeClass('hidden');
- return $('.dropdown-footer').show();
- }
- };
-
- return ProtectedBranchSelect;
-
- })();
-
-}).call(this);
diff --git a/app/assets/javascripts/protected_branches_access_select.js.es6 b/app/assets/javascripts/protected_branches_access_select.js.es6
deleted file mode 100644
index e98312bbf37..00000000000
--- a/app/assets/javascripts/protected_branches_access_select.js.es6
+++ /dev/null
@@ -1,63 +0,0 @@
-class ProtectedBranchesAccessSelect {
- constructor(container, saveOnSelect, selectDefault) {
- this.container = container;
- this.saveOnSelect = saveOnSelect;
-
- this.container.find(".allowed-to-merge").each((i, element) => {
- var fieldName = $(element).data('field-name');
- var dropdown = $(element).glDropdown({
- data: gon.merge_access_levels,
- selectable: true,
- fieldName: fieldName,
- clicked: _.chain(this.onSelect).partial(element).bind(this).value()
- });
-
- if (selectDefault) {
- dropdown.data('glDropdown').selectRowAtIndex(document.createEvent("Event"), 0);
- }
- });
-
-
- this.container.find(".allowed-to-push").each((i, element) => {
- var fieldName = $(element).data('field-name');
- var dropdown = $(element).glDropdown({
- data: gon.push_access_levels,
- selectable: true,
- fieldName: fieldName,
- clicked: _.chain(this.onSelect).partial(element).bind(this).value()
- });
-
- if (selectDefault) {
- dropdown.data('glDropdown').selectRowAtIndex(document.createEvent("Event"), 0);
- }
- });
- }
-
- onSelect(dropdown, selected, element, e) {
- $(dropdown).find('.dropdown-toggle-text').text(selected.text);
- if (this.saveOnSelect) {
- return $.ajax({
- type: "POST",
- url: $(dropdown).data('url'),
- dataType: "json",
- data: {
- _method: 'PATCH',
- id: $(dropdown).data('id'),
- protected_branch: {
- ["" + ($(dropdown).data('type')) + "_attributes"]: {
- "access_level": selected.id
- }
- }
- },
- success: function() {
- var row;
- row = $(e.target);
- return row.closest('tr').effect('highlight');
- },
- error: function() {
- return new Flash("Failed to update branch!", "alert");
- }
- });
- }
- }
-}
diff --git a/app/assets/javascripts/users_select.js b/app/assets/javascripts/users_select.js
index 4af2a214e12..65d362e072c 100644
--- a/app/assets/javascripts/users_select.js
+++ b/app/assets/javascripts/users_select.js
@@ -13,14 +13,15 @@
}
$('.js-user-search').each((function(_this) {
return function(i, dropdown) {
+ var options = {};
var $block, $collapsedSidebar, $dropdown, $loading, $selectbox, $value, abilityName, assignTo, assigneeTemplate, collapsedAssigneeTemplate, defaultLabel, firstUser, issueURL, selectedId, showAnyUser, showNullUser;
$dropdown = $(dropdown);
- _this.projectId = $dropdown.data('project-id');
- _this.showCurrentUser = $dropdown.data('current-user');
+ options.projectId = $dropdown.data('project-id');
+ options.showCurrentUser = $dropdown.data('current-user');
showNullUser = $dropdown.data('null-user');
showAnyUser = $dropdown.data('any-user');
firstUser = $dropdown.data('first-user');
- _this.authorId = $dropdown.data('author-id');
+ options.authorId = $dropdown.data('author-id');
selectedId = $dropdown.data('selected');
defaultLabel = $dropdown.data('default-label');
issueURL = $dropdown.data('issueUpdate');
@@ -75,7 +76,7 @@
data: function(term, callback) {
var isAuthorFilter;
isAuthorFilter = $('.js-author-search');
- return _this.users(term, function(users) {
+ return _this.users(term, options, function(users) {
var anyUser, index, j, len, name, obj, showDivider;
if (term.length === 0) {
showDivider = 0;
@@ -185,11 +186,14 @@
$('.ajax-users-select').each((function(_this) {
return function(i, select) {
var firstUser, showAnyUser, showEmailUser, showNullUser;
- _this.projectId = $(select).data('project-id');
- _this.groupId = $(select).data('group-id');
- _this.showCurrentUser = $(select).data('current-user');
- _this.authorId = $(select).data('author-id');
- _this.skipUsers = $(select).data('skip-users');
+ var options = {};
+ options.skipLdap = $(select).hasClass('skip_ldap');
+ options.projectId = $(select).data('project-id');
+ options.groupId = $(select).data('group-id');
+ options.showCurrentUser = $(select).data('current-user');
+ options.pushCodeToProtectedBranches = $(select).data('push-code-to-protected-branches');
+ options.authorId = $(select).data('author-id');
+ options.skipUsers = $(select).data('skip-users');
showNullUser = $(select).data('null-user');
showAnyUser = $(select).data('any-user');
showEmailUser = $(select).data('email-user');
@@ -199,7 +203,7 @@
multiple: $(select).hasClass('multiselect'),
minimumInputLength: 0,
query: function(query) {
- return _this.users(query.term, function(users) {
+ return _this.users(query.term, options, function(users) {
var anyUser, data, emailUser, index, j, len, name, nullUser, obj, ref;
data = {
results: users
@@ -309,7 +313,7 @@
});
};
- UsersSelect.prototype.users = function(query, callback) {
+ UsersSelect.prototype.users = function(query, options, callback) {
var url;
url = this.buildUrl(this.usersPath);
return $.ajax({
@@ -318,11 +322,13 @@
search: query,
per_page: 20,
active: true,
- project_id: this.projectId,
- group_id: this.groupId,
- current_user: this.showCurrentUser,
- author_id: this.authorId,
- skip_users: this.skipUsers
+ project_id: options.projectId || null,
+ group_id: options.groupId || null,
+ skip_ldap: options.skipLdap || null,
+ current_user: options.showCurrentUser || null,
+ push_code_to_protected_branches: options.pushCodeToProtectedBranches || null,
+ author_id: options.authorId || null,
+ skip_users: options.skipUsers || null
},
dataType: "json"
}).done(function(users) {
diff --git a/app/assets/stylesheets/framework/dropdowns.scss b/app/assets/stylesheets/framework/dropdowns.scss
index c54eb0d6479..e8eafa15899 100644
--- a/app/assets/stylesheets/framework/dropdowns.scss
+++ b/app/assets/stylesheets/framework/dropdowns.scss
@@ -72,6 +72,14 @@
&.large {
width: 200px;
}
+
+ &.wide {
+ width: 100%;
+
+ + .dropdown-select {
+ width: 100%;
+ }
+ }
}
.dropdown-menu,
diff --git a/app/assets/stylesheets/framework/lists.scss b/app/assets/stylesheets/framework/lists.scss
index 2c40ec430ca..965fcc06518 100644
--- a/app/assets/stylesheets/framework/lists.scss
+++ b/app/assets/stylesheets/framework/lists.scss
@@ -114,6 +114,12 @@ ul.content-list {
font-size: $list-font-size;
color: $list-text-color;
+ &.no-description {
+ .title {
+ line-height: $list-text-height;
+ }
+ }
+
.title {
font-weight: 600;
}
@@ -134,12 +140,11 @@ ul.content-list {
}
.controls {
- padding-top: 1px;
float: right;
> .control-text {
margin-right: $gl-padding-top;
- line-height: 40px;
+ line-height: $list-text-height;
&:last-child {
margin-right: 0;
@@ -150,7 +155,7 @@ ul.content-list {
> .btn-group {
margin-right: $gl-padding-top;
display: inline-block;
- margin-top: 4px;
+ margin-top: 3px;
margin-bottom: 4px;
&:last-child {
diff --git a/app/assets/stylesheets/framework/panels.scss b/app/assets/stylesheets/framework/panels.scss
index 874416e1007..c6f30e144fd 100644
--- a/app/assets/stylesheets/framework/panels.scss
+++ b/app/assets/stylesheets/framework/panels.scss
@@ -23,4 +23,9 @@
margin-top: $gl-padding;
}
}
+
+ .panel-title {
+ font-size: inherit;
+ line-height: inherit;
+ }
}
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index 1882d4e888d..ca720022539 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -43,6 +43,7 @@ $gl-header-color: $gl-title-color;
$list-font-size: $gl-font-size;
$list-title-color: $gl-title-color;
$list-text-color: $gl-text-color;
+$list-text-height: 42px;
/*
* Markdown
diff --git a/app/assets/stylesheets/pages/groups.scss b/app/assets/stylesheets/pages/groups.scss
index 2a3acc3eb4c..b657ca47d38 100644
--- a/app/assets/stylesheets/pages/groups.scss
+++ b/app/assets/stylesheets/pages/groups.scss
@@ -23,15 +23,9 @@
}
.group-row {
- &.no-description {
- .group-name {
- line-height: 44px;
- }
- }
-
.stats {
float: right;
- line-height: 44px;
+ line-height: $list-text-height;
color: $gl-gray;
span {
diff --git a/app/assets/stylesheets/pages/labels.scss b/app/assets/stylesheets/pages/labels.scss
index 3b1e38fc07d..606459f82cd 100644
--- a/app/assets/stylesheets/pages/labels.scss
+++ b/app/assets/stylesheets/pages/labels.scss
@@ -182,6 +182,17 @@
.btn {
color: inherit;
}
+
+ a.btn {
+ padding: 0;
+
+ .has-tooltip {
+ top: 0;
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ line-height: 1.1;
+ }
+ }
}
.label-options-toggle {
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index 4409477916f..cf9aa02600d 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -512,18 +512,12 @@ pre.light-well {
.project-row {
border-color: $table-border-color;
- &.no-description {
- .project {
- line-height: 40px;
- }
- }
-
.project-full-name {
@include str-truncated;
}
.controls {
- line-height: 40px;
+ line-height: $list-text-height;
a:hover {
text-decoration: none;
@@ -662,13 +656,9 @@ pre.light-well {
}
.new_protected_branch {
- .dropdown {
- display: inline;
- margin-left: 15px;
- }
-
label {
- min-width: 120px;
+ margin-top: 6px;
+ font-weight: normal;
}
}
@@ -684,6 +674,21 @@ pre.light-well {
font-weight: 600;
}
}
+
+ .settings-message {
+ margin: 0;
+ border-radius: 0 0 1px 1px;
+ padding: 20px 0;
+ border: none;
+ }
+
+ .table-bordered {
+ border-radius: 1px;
+
+ th:not(:last-child), td:not(:last-child) {
+ border-right: solid 1px transparent;
+ }
+ }
}
.custom-notifications-form {
diff --git a/app/controllers/concerns/diff_for_path.rb b/app/controllers/concerns/diff_for_path.rb
index 026d8b2e1e0..aeec3009f15 100644
--- a/app/controllers/concerns/diff_for_path.rb
+++ b/app/controllers/concerns/diff_for_path.rb
@@ -1,8 +1,8 @@
module DiffForPath
extend ActiveSupport::Concern
- def render_diff_for_path(diffs, diff_refs, project)
- diff_file = safe_diff_files(diffs, diff_refs: diff_refs, repository: project.repository).find do |diff|
+ def render_diff_for_path(diffs)
+ diff_file = diffs.diff_files.find do |diff|
diff.old_path == params[:old_path] && diff.new_path == params[:new_path]
end
@@ -14,7 +14,7 @@ module DiffForPath
locals = {
diff_file: diff_file,
diff_commit: diff_commit,
- diff_refs: diff_refs,
+ diff_refs: diffs.diff_refs,
blob: blob,
project: project
}
diff --git a/app/controllers/import/gitlab_projects_controller.rb b/app/controllers/import/gitlab_projects_controller.rb
index 30df1fb2fec..3ec173abcdb 100644
--- a/app/controllers/import/gitlab_projects_controller.rb
+++ b/app/controllers/import/gitlab_projects_controller.rb
@@ -12,13 +12,14 @@ class Import::GitlabProjectsController < Import::BaseController
return redirect_back_or_default(options: { alert: "You need to upload a GitLab project export archive." })
end
- imported_file = project_params[:file].path + "-import"
+ import_upload_path = Gitlab::ImportExport.import_upload_path(filename: project_params[:file].original_filename)
- FileUtils.copy_entry(project_params[:file].path, imported_file)
+ FileUtils.mkdir_p(File.dirname(import_upload_path))
+ FileUtils.copy_entry(project_params[:file].path, import_upload_path)
@project = Gitlab::ImportExport::ProjectCreator.new(project_params[:namespace_id],
current_user,
- File.expand_path(imported_file),
+ import_upload_path,
project_params[:path]).execute
if @project.saved?
diff --git a/app/controllers/profiles/passwords_controller.rb b/app/controllers/profiles/passwords_controller.rb
index c780e0983f9..6217ec5ecef 100644
--- a/app/controllers/profiles/passwords_controller.rb
+++ b/app/controllers/profiles/passwords_controller.rb
@@ -50,6 +50,7 @@ class Profiles::PasswordsController < Profiles::ApplicationController
flash[:notice] = "Password was successfully updated. Please login with it"
redirect_to new_user_session_path
else
+ @user.reload
render 'edit'
end
end
diff --git a/app/controllers/projects/badges_controller.rb b/app/controllers/projects/badges_controller.rb
index a9f482c8787..d0f5071d2cc 100644
--- a/app/controllers/projects/badges_controller.rb
+++ b/app/controllers/projects/badges_controller.rb
@@ -8,8 +8,9 @@ class Projects::BadgesController < Projects::ApplicationController
respond_to do |format|
format.html { render_404 }
+
format.svg do
- send_data(badge.data, type: badge.type, disposition: 'inline')
+ render 'badge', locals: { badge: badge.template }
end
end
end
diff --git a/app/controllers/projects/blob_controller.rb b/app/controllers/projects/blob_controller.rb
index eda3727a28d..19d051720e9 100644
--- a/app/controllers/projects/blob_controller.rb
+++ b/app/controllers/projects/blob_controller.rb
@@ -76,6 +76,8 @@ class Projects::BlobController < Projects::ApplicationController
end
def diff
+ apply_diff_view_cookie!
+
@form = UnfoldForm.new(params)
@lines = Gitlab::Highlight.highlight_lines(repository, @ref, @path)
@lines = @lines[@form.since - 1..@form.to - 1]
diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb
index 7ae034f9398..fdfe7c65b7b 100644
--- a/app/controllers/projects/commit_controller.rb
+++ b/app/controllers/projects/commit_controller.rb
@@ -28,7 +28,7 @@ class Projects::CommitController < Projects::ApplicationController
end
def diff_for_path
- render_diff_for_path(@diffs, @commit.diff_refs, @project)
+ render_diff_for_path(@commit.diffs(diff_options))
end
def builds
diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb
index 8c004724f02..bee3d56076c 100644
--- a/app/controllers/projects/compare_controller.rb
+++ b/app/controllers/projects/compare_controller.rb
@@ -21,7 +21,7 @@ class Projects::CompareController < Projects::ApplicationController
def diff_for_path
return render_404 unless @compare
- render_diff_for_path(@diffs, @diff_refs, @project)
+ render_diff_for_path(@compare.diffs(diff_options))
end
def create
@@ -40,18 +40,12 @@ class Projects::CompareController < Projects::ApplicationController
@compare = CompareService.new.execute(@project, @head_ref, @project, @start_ref)
if @compare
- @commits = Commit.decorate(@compare.commits, @project)
-
- @start_commit = @project.commit(@start_ref)
- @commit = @project.commit(@head_ref)
- @base_commit = @project.merge_base_commit(@start_ref, @head_ref)
+ @commits = @compare.commits
+ @start_commit = @compare.start_commit
+ @commit = @compare.commit
+ @base_commit = @compare.base_commit
@diffs = @compare.diffs(diff_options)
- @diff_refs = Gitlab::Diff::DiffRefs.new(
- base_sha: @base_commit.try(:sha),
- start_sha: @start_commit.try(:sha),
- head_sha: @commit.try(:sha)
- )
@diff_notes_disabled = true
@grouped_diff_discussions = {}
diff --git a/app/controllers/projects/deploy_keys_controller.rb b/app/controllers/projects/deploy_keys_controller.rb
index 83d5ced9be8..529e0aa2d33 100644
--- a/app/controllers/projects/deploy_keys_controller.rb
+++ b/app/controllers/projects/deploy_keys_controller.rb
@@ -12,8 +12,7 @@ class Projects::DeployKeysController < Projects::ApplicationController
end
def new
- redirect_to namespace_project_deploy_keys_path(@project.namespace,
- @project)
+ redirect_to namespace_project_deploy_keys_path(@project.namespace, @project)
end
def create
@@ -21,19 +20,16 @@ class Projects::DeployKeysController < Projects::ApplicationController
set_index_vars
if @key.valid? && @project.deploy_keys << @key
- redirect_to namespace_project_deploy_keys_path(@project.namespace,
- @project)
+ redirect_to namespace_project_deploy_keys_path(@project.namespace, @project)
else
render "index"
end
end
def enable
- @key = accessible_keys.find(params[:id])
- @project.deploy_keys << @key
+ Projects::EnableDeployKeyService.new(@project, current_user, params).execute
- redirect_to namespace_project_deploy_keys_path(@project.namespace,
- @project)
+ redirect_to namespace_project_deploy_keys_path(@project.namespace, @project)
end
def disable
@@ -45,9 +41,9 @@ class Projects::DeployKeysController < Projects::ApplicationController
protected
def set_index_vars
- @enabled_keys ||= @project.deploy_keys
+ @enabled_keys ||= @project.deploy_keys
- @available_keys ||= accessible_keys - @enabled_keys
+ @available_keys ||= current_user.accessible_deploy_keys - @enabled_keys
@available_project_keys ||= current_user.project_deploy_keys - @enabled_keys
@available_public_keys ||= DeployKey.are_public - @enabled_keys
@@ -56,10 +52,6 @@ class Projects::DeployKeysController < Projects::ApplicationController
@available_public_keys -= @available_project_keys
end
- def accessible_keys
- @accessible_keys ||= current_user.accessible_deploy_keys
- end
-
def deploy_key_params
params.require(:deploy_key).permit(:key, :title)
end
diff --git a/app/controllers/projects/git_http_controller.rb b/app/controllers/projects/git_http_controller.rb
index 40a8b7940d9..e2f93e239bd 100644
--- a/app/controllers/projects/git_http_controller.rb
+++ b/app/controllers/projects/git_http_controller.rb
@@ -20,9 +20,9 @@ class Projects::GitHttpController < Projects::ApplicationController
elsif receive_pack? && receive_pack_allowed?
render_ok
elsif http_blocked?
- render_not_allowed
+ render_http_not_allowed
else
- render_not_found
+ render_denied
end
end
@@ -31,7 +31,7 @@ class Projects::GitHttpController < Projects::ApplicationController
if upload_pack? && upload_pack_allowed?
render_ok
else
- render_not_found
+ render_denied
end
end
@@ -40,7 +40,7 @@ class Projects::GitHttpController < Projects::ApplicationController
if receive_pack? && receive_pack_allowed?
render_ok
else
- render_not_found
+ render_denied
end
end
@@ -156,8 +156,17 @@ class Projects::GitHttpController < Projects::ApplicationController
render plain: 'Not Found', status: :not_found
end
- def render_not_allowed
- render plain: download_access.message, status: :forbidden
+ def render_http_not_allowed
+ render plain: access_check.message, status: :forbidden
+ end
+
+ def render_denied
+ if user && user.can?(:read_project, project)
+ render plain: 'Access denied', status: :forbidden
+ else
+ # Do not leak information about project existence
+ render_not_found
+ end
end
def ci?
@@ -168,22 +177,20 @@ class Projects::GitHttpController < Projects::ApplicationController
return false unless Gitlab.config.gitlab_shell.upload_pack
if user
- download_access.allowed?
+ access_check.allowed?
else
ci? || project.public?
end
end
def access
- return @access if defined?(@access)
-
- @access = Gitlab::GitAccess.new(user, project, 'http')
+ @access ||= Gitlab::GitAccess.new(user, project, 'http')
end
- def download_access
- return @download_access if defined?(@download_access)
-
- @download_access = access.check('git-upload-pack')
+ def access_check
+ # Use the magic string '_any' to indicate we do not know what the
+ # changes are. This is also what gitlab-shell does.
+ @access_check ||= access.check(git_command, '_any')
end
def http_blocked?
@@ -193,8 +200,6 @@ class Projects::GitHttpController < Projects::ApplicationController
def receive_pack_allowed?
return false unless Gitlab.config.gitlab_shell.receive_pack
- # Skip user authorization on upload request.
- # It will be done by the pre-receive hook in the repository.
- user.present?
+ access_check.allowed?
end
end
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 116e7904a4e..2cf6a2dd1b3 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -85,7 +85,11 @@ class Projects::MergeRequestsController < Projects::ApplicationController
respond_to do |format|
format.html { define_discussion_vars }
- format.json { render json: { html: view_to_html_string("projects/merge_requests/show/_diffs") } }
+ format.json do
+ @diffs = @merge_request.diffs(diff_options)
+
+ render json: { html: view_to_html_string("projects/merge_requests/show/_diffs") }
+ end
end
end
@@ -103,9 +107,8 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end
define_commit_vars
- diffs = @merge_request.diffs(diff_options)
- render_diff_for_path(diffs, @merge_request.diff_refs, @merge_request.project)
+ render_diff_for_path(@merge_request.diffs(diff_options))
end
def commits
@@ -153,7 +156,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
@commits = @merge_request.compare_commits.reverse
@commit = @merge_request.diff_head_commit
@base_commit = @merge_request.diff_base_commit
- @diffs = @merge_request.compare.diffs(diff_options) if @merge_request.compare
+ @diffs = @merge_request.diffs(diff_options) if @merge_request.compare
@diff_notes_disabled = true
@pipeline = @merge_request.pipeline
diff --git a/app/controllers/projects/pipelines_settings_controller.rb b/app/controllers/projects/pipelines_settings_controller.rb
index 85ba706e5cd..75dd3648e45 100644
--- a/app/controllers/projects/pipelines_settings_controller.rb
+++ b/app/controllers/projects/pipelines_settings_controller.rb
@@ -3,7 +3,7 @@ class Projects::PipelinesSettingsController < Projects::ApplicationController
def show
@ref = params[:ref] || @project.default_branch || 'master'
- @build_badge = Gitlab::Badge::Build.new(@project, @ref)
+ @build_badge = Gitlab::Badge::Build.new(@project, @ref).metadata
end
def update
diff --git a/app/controllers/projects_controller.rb b/app/controllers/projects_controller.rb
index a6e1aa5ccc1..207f9d6a77f 100644
--- a/app/controllers/projects_controller.rb
+++ b/app/controllers/projects_controller.rb
@@ -125,7 +125,7 @@ class ProjectsController < Projects::ApplicationController
def destroy
return access_denied! unless can?(current_user, :remove_project, @project)
- ::Projects::DestroyService.new(@project, current_user, {}).pending_delete!
+ ::Projects::DestroyService.new(@project, current_user, {}).async_execute
flash[:alert] = "Project '#{@project.name}' will be deleted."
redirect_to dashboard_projects_path
diff --git a/app/controllers/registrations_controller.rb b/app/controllers/registrations_controller.rb
index 75b78a49eab..3327f4f2b87 100644
--- a/app/controllers/registrations_controller.rb
+++ b/app/controllers/registrations_controller.rb
@@ -33,7 +33,7 @@ class RegistrationsController < Devise::RegistrationsController
protected
- def build_resource(hash=nil)
+ def build_resource(hash = nil)
super
end
diff --git a/app/controllers/sessions_controller.rb b/app/controllers/sessions_controller.rb
index 17aed816cbd..5d7ecfeacf4 100644
--- a/app/controllers/sessions_controller.rb
+++ b/app/controllers/sessions_controller.rb
@@ -101,7 +101,7 @@ class SessionsController < Devise::SessionsController
# Prevent alert from popping up on the first page shown after authentication.
flash[:alert] = nil
- redirect_to user_omniauth_authorize_path(provider.to_sym)
+ redirect_to omniauth_authorize_path(:user, provider)
end
def valid_otp_attempt?(user)
diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb
index 50de93d4bdf..c3613bc67dd 100644
--- a/app/helpers/application_helper.rb
+++ b/app/helpers/application_helper.rb
@@ -163,9 +163,13 @@ module ApplicationHelper
# `html_class` argument is provided.
#
# Returns an HTML-safe String
- def time_ago_with_tooltip(time, placement: 'top', html_class: 'time_ago', skip_js: false)
+ def time_ago_with_tooltip(time, placement: 'top', html_class: '', skip_js: false, short_format: false)
+ css_classes = short_format ? 'js-short-timeago' : 'js-timeago'
+ css_classes << " #{html_class}" unless html_class.blank?
+ css_classes << ' js-timeago-pending' unless skip_js
+
element = content_tag :time, time.to_s,
- class: "#{html_class} js-timeago #{"js-timeago-pending" unless skip_js}",
+ class: css_classes,
datetime: time.to_time.getutc.iso8601,
title: time.to_time.in_time_zone.to_s(:medium),
data: { toggle: 'tooltip', placement: placement, container: 'body' }
diff --git a/app/helpers/avatars_helper.rb b/app/helpers/avatars_helper.rb
index 6ff40c6b461..2160cf7a690 100644
--- a/app/helpers/avatars_helper.rb
+++ b/app/helpers/avatars_helper.rb
@@ -1,5 +1,4 @@
module AvatarsHelper
-
def author_avatar(commit_or_event, options = {})
user_avatar(options.merge({
user: commit_or_event.author,
@@ -26,5 +25,4 @@ module AvatarsHelper
mail_to(options[:user_email], avatar)
end
end
-
end
diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb
index f497626e21a..7a02d0b10d9 100644
--- a/app/helpers/commits_helper.rb
+++ b/app/helpers/commits_helper.rb
@@ -206,10 +206,10 @@ module CommitsHelper
end
end
- def view_file_btn(commit_sha, diff, project)
+ def view_file_btn(commit_sha, diff_new_path, project)
link_to(
namespace_project_blob_path(project.namespace, project,
- tree_join(commit_sha, diff.new_path)),
+ tree_join(commit_sha, diff_new_path)),
class: 'btn view-file js-view-file btn-file-option'
) do
raw('View file @') + content_tag(:span, commit_sha[0..6],
diff --git a/app/helpers/diff_helper.rb b/app/helpers/diff_helper.rb
index f35e2f6ddcd..f3c9ea074b4 100644
--- a/app/helpers/diff_helper.rb
+++ b/app/helpers/diff_helper.rb
@@ -13,12 +13,11 @@ module DiffHelper
end
def diff_view
- diff_views = %w(inline parallel)
-
- if diff_views.include?(cookies[:diff_view])
- cookies[:diff_view]
- else
- diff_views.first
+ @diff_view ||= begin
+ diff_views = %w(inline parallel)
+ diff_view = cookies[:diff_view]
+ diff_view = diff_views.first unless diff_views.include?(diff_view)
+ diff_view.to_sym
end
end
@@ -30,19 +29,26 @@ module DiffHelper
options[:paths] = params.values_at(:old_path, :new_path)
end
- Commit.max_diff_options.merge(options)
+ options
end
- def safe_diff_files(diffs, diff_refs: nil, repository: nil)
- diffs.decorate! { |diff| Gitlab::Diff::File.new(diff, diff_refs: diff_refs, repository: repository) }
- end
+ def diff_match_line(old_pos, new_pos, text: '', view: :inline, bottom: false)
+ content = content_tag :td, text, class: "line_content match #{view == :inline ? '' : view}"
+ cls = ['diff-line-num', 'unfold', 'js-unfold']
+ cls << 'js-unfold-bottom' if bottom
- def unfold_bottom_class(bottom)
- bottom ? 'js-unfold js-unfold-bottom' : ''
- end
+ html = ''
+ if old_pos
+ html << content_tag(:td, '...', class: cls + ['old_line'], data: { linenumber: old_pos })
+ html << content unless view == :inline
+ end
+
+ if new_pos
+ html << content_tag(:td, '...', class: cls + ['new_line'], data: { linenumber: new_pos })
+ html << content
+ end
- def unfold_class(unfold)
- unfold ? 'unfold js-unfold' : ''
+ html.html_safe
end
def diff_line_content(line, line_type = nil)
@@ -71,11 +77,11 @@ module DiffHelper
end
def inline_diff_btn
- diff_btn('Inline', 'inline', diff_view == 'inline')
+ diff_btn('Inline', 'inline', diff_view == :inline)
end
def parallel_diff_btn
- diff_btn('Side-by-side', 'parallel', diff_view == 'parallel')
+ diff_btn('Side-by-side', 'parallel', diff_view == :parallel)
end
def submodule_link(blob, ref, repository = @repository)
@@ -107,7 +113,8 @@ module DiffHelper
commit = commit_for_diff(diff_file)
{
blob_diff_path: namespace_project_blob_diff_path(project.namespace, project,
- tree_join(commit.id, diff_file.file_path))
+ tree_join(commit.id, diff_file.file_path)),
+ view: diff_view
}
end
diff --git a/app/helpers/explore_helper.rb b/app/helpers/explore_helper.rb
index 337b0aacbb5..2b1f3825adc 100644
--- a/app/helpers/explore_helper.rb
+++ b/app/helpers/explore_helper.rb
@@ -1,5 +1,5 @@
module ExploreHelper
- def filter_projects_path(options={})
+ def filter_projects_path(options = {})
exist_opts = {
sort: params[:sort],
scope: params[:scope],
diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb
index a2bba139c17..c0195713f4a 100644
--- a/app/helpers/search_helper.rb
+++ b/app/helpers/search_helper.rb
@@ -107,7 +107,7 @@ module SearchHelper
Sanitize.clean(str)
end
- def search_filter_path(options={})
+ def search_filter_path(options = {})
exist_opts = {
search: params[:search],
project_id: params[:project_id],
diff --git a/app/helpers/tree_helper.rb b/app/helpers/tree_helper.rb
index dbedf417fa5..4a76c679bad 100644
--- a/app/helpers/tree_helper.rb
+++ b/app/helpers/tree_helper.rb
@@ -4,23 +4,11 @@ module TreeHelper
#
# contents - A Grit::Tree object for the current tree
def render_tree(tree)
- # Render Folders before Files/Submodules
+ # Sort submodules and folders together by name ahead of files
folders, files, submodules = tree.trees, tree.blobs, tree.submodules
-
tree = ""
-
- # Render folders if we have any
- tree << render(partial: 'projects/tree/tree_item', collection: folders,
- locals: { type: 'folder' }) if folders.present?
-
- # Render files if we have any
- tree << render(partial: 'projects/tree/blob_item', collection: files,
- locals: { type: 'file' }) if files.present?
-
- # Render submodules if we have any
- tree << render(partial: 'projects/tree/submodule_item',
- collection: submodules) if submodules.present?
-
+ items = (folders + submodules).sort_by(&:name) + files
+ tree << render(partial: "projects/tree/tree_row", collection: items) if items.present?
tree.html_safe
end
diff --git a/app/models/ability.rb b/app/models/ability.rb
index d95a2507199..d9113ffd99a 100644
--- a/app/models/ability.rb
+++ b/app/models/ability.rb
@@ -6,6 +6,10 @@ class Ability
return [] unless user.is_a?(User)
return [] if user.blocked?
+ abilities_by_subject_class(user: user, subject: subject)
+ end
+
+ def abilities_by_subject_class(user:, subject:)
case subject
when CommitStatus then commit_status_abilities(user, subject)
when Project then project_abilities(user, subject)
diff --git a/app/models/commit.rb b/app/models/commit.rb
index c52b4a051c2..cc413448ce8 100644
--- a/app/models/commit.rb
+++ b/app/models/commit.rb
@@ -104,7 +104,7 @@ class Commit
end
def diff_line_count
- @diff_line_count ||= Commit::diff_line_count(self.diffs)
+ @diff_line_count ||= Commit::diff_line_count(raw_diffs)
@diff_line_count
end
@@ -317,6 +317,14 @@ class Commit
nil
end
+ def raw_diffs(*args)
+ raw.diffs(*args)
+ end
+
+ def diffs(diff_options = nil)
+ Gitlab::Diff::FileCollection::Commit.new(self, diff_options: diff_options)
+ end
+
private
def find_author_by_any_email
@@ -326,7 +334,7 @@ class Commit
def repo_changes
changes = { added: [], modified: [], removed: [] }
- diffs.each do |diff|
+ raw_diffs(deltas_only: true).each do |diff|
if diff.deleted_file
changes[:removed] << diff.old_path
elsif diff.renamed_file || diff.new_file
diff --git a/app/models/compare.rb b/app/models/compare.rb
new file mode 100644
index 00000000000..4856510f526
--- /dev/null
+++ b/app/models/compare.rb
@@ -0,0 +1,66 @@
+class Compare
+ delegate :same, :head, :base, to: :@compare
+
+ attr_reader :project
+
+ def self.decorate(compare, project)
+ if compare.is_a?(Compare)
+ compare
+ else
+ self.new(compare, project)
+ end
+ end
+
+ def initialize(compare, project)
+ @compare = compare
+ @project = project
+ end
+
+ def commits
+ @commits ||= Commit.decorate(@compare.commits, project)
+ end
+
+ def start_commit
+ return @start_commit if defined?(@start_commit)
+
+ commit = @compare.base
+ @start_commit = commit ? ::Commit.new(commit, project) : nil
+ end
+
+ def head_commit
+ return @head_commit if defined?(@head_commit)
+
+ commit = @compare.head
+ @head_commit = commit ? ::Commit.new(commit, project) : nil
+ end
+ alias_method :commit, :head_commit
+
+ def base_commit
+ return @base_commit if defined?(@base_commit)
+
+ @base_commit = if start_commit && head_commit
+ project.merge_base_commit(start_commit.id, head_commit.id)
+ else
+ nil
+ end
+ end
+
+ def raw_diffs(*args)
+ @compare.diffs(*args)
+ end
+
+ def diffs(diff_options = nil)
+ Gitlab::Diff::FileCollection::Compare.new(self,
+ project: project,
+ diff_options: diff_options,
+ diff_refs: diff_refs)
+ end
+
+ def diff_refs
+ Gitlab::Diff::DiffRefs.new(
+ base_sha: base_commit.try(:sha),
+ start_sha: start_commit.try(:sha),
+ head_sha: commit.try(:sha)
+ )
+ end
+end
diff --git a/app/models/concerns/faster_cache_keys.rb b/app/models/concerns/faster_cache_keys.rb
new file mode 100644
index 00000000000..5b14723fa2d
--- /dev/null
+++ b/app/models/concerns/faster_cache_keys.rb
@@ -0,0 +1,16 @@
+module FasterCacheKeys
+ # A faster version of Rails' "cache_key" method.
+ #
+ # Rails' default "cache_key" method uses all kind of complex logic to figure
+ # out the cache key. In many cases this complexity and overhead may not be
+ # needed.
+ #
+ # This method does not do any timestamp parsing as this process is quite
+ # expensive and not needed when generating cache keys. This method also relies
+ # on the table name instead of the cache namespace name as the latter uses
+ # complex logic to generate the exact same value (as when using the table
+ # name) in 99% of the cases.
+ def cache_key
+ "#{self.class.table_name}/#{id}-#{read_attribute_before_type_cast(:updated_at)}"
+ end
+end
diff --git a/app/models/issue.rb b/app/models/issue.rb
index 11f734cfc6d..d62ffb21467 100644
--- a/app/models/issue.rb
+++ b/app/models/issue.rb
@@ -7,6 +7,7 @@ class Issue < ActiveRecord::Base
include Sortable
include Taskable
include Spammable
+ include FasterCacheKeys
DueDateStruct = Struct.new(:title, :name).freeze
NoDueDate = DueDateStruct.new('No Due Date', '0').freeze
diff --git a/app/models/legacy_diff_note.rb b/app/models/legacy_diff_note.rb
index 865712268a0..6ed66001513 100644
--- a/app/models/legacy_diff_note.rb
+++ b/app/models/legacy_diff_note.rb
@@ -85,7 +85,7 @@ class LegacyDiffNote < Note
return nil unless noteable
return @diff if defined?(@diff)
- @diff = noteable.diffs(Commit.max_diff_options).find do |d|
+ @diff = noteable.raw_diffs(Commit.max_diff_options).find do |d|
d.new_path && Digest::SHA1.hexdigest(d.new_path) == diff_file_hash
end
end
@@ -116,7 +116,7 @@ class LegacyDiffNote < Note
# Find the diff on noteable that matches our own
def find_noteable_diff
- diffs = noteable.diffs(Commit.max_diff_options)
+ diffs = noteable.raw_diffs(Commit.max_diff_options)
diffs.find { |d| d.new_path == self.diff.new_path }
end
end
diff --git a/app/models/members/project_member.rb b/app/models/members/project_member.rb
index f39afc61ce9..f176feddbad 100644
--- a/app/models/members/project_member.rb
+++ b/app/models/members/project_member.rb
@@ -21,19 +21,19 @@ class ProjectMember < Member
# or symbol like :master representing role
#
# Ex.
- # add_users_into_projects(
+ # add_users_to_projects(
# project_ids,
# user_ids,
# ProjectMember::MASTER
# )
#
- # add_users_into_projects(
+ # add_users_to_projects(
# project_ids,
# user_ids,
# :master
# )
#
- def add_users_into_projects(project_ids, user_ids, access, current_user = nil)
+ def add_users_to_projects(project_ids, user_ids, access, current_user = nil)
access_level = if roles_hash.has_key?(access)
roles_hash[access]
elsif roles_hash.values.include?(access.to_i)
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index a99c4ba52a4..b1fb3ce5d69 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -164,8 +164,16 @@ class MergeRequest < ActiveRecord::Base
merge_request_diff ? merge_request_diff.first_commit : compare_commits.first
end
- def diffs(*args)
- merge_request_diff ? merge_request_diff.diffs(*args) : compare.diffs(*args)
+ def raw_diffs(*args)
+ merge_request_diff ? merge_request_diff.raw_diffs(*args) : compare.raw_diffs(*args)
+ end
+
+ def diffs(diff_options = nil)
+ if self.compare
+ self.compare.diffs(diff_options)
+ else
+ Gitlab::Diff::FileCollection::MergeRequest.new(self, diff_options: diff_options)
+ end
end
def diff_size
@@ -313,6 +321,8 @@ class MergeRequest < ActiveRecord::Base
merge_request_diff.reload_content
+ MergeRequests::MergeRequestDiffCacheService.new.execute(self)
+
new_diff_refs = self.diff_refs
update_diff_notes_positions(
diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb
index 119266f2d2c..32cc6a3bfea 100644
--- a/app/models/merge_request_diff.rb
+++ b/app/models/merge_request_diff.rb
@@ -33,12 +33,12 @@ class MergeRequestDiff < ActiveRecord::Base
end
def size
- real_size.presence || diffs.size
+ real_size.presence || raw_diffs.size
end
- def diffs(options={})
+ def raw_diffs(options = {})
if options[:ignore_whitespace_change]
- @diffs_no_whitespace ||= begin
+ @raw_diffs_no_whitespace ||= begin
compare = Gitlab::Git::Compare.new(
repository.raw_repository,
self.start_commit_sha || self.target_branch_sha,
@@ -47,8 +47,8 @@ class MergeRequestDiff < ActiveRecord::Base
compare.diffs(options)
end
else
- @diffs ||= {}
- @diffs[options] ||= load_diffs(st_diffs, options)
+ @raw_diffs ||= {}
+ @raw_diffs[options] ||= load_diffs(st_diffs, options)
end
end
diff --git a/app/models/note.rb b/app/models/note.rb
index b6b2ac6aa42..ddcd7f9d034 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -5,6 +5,7 @@ class Note < ActiveRecord::Base
include Mentionable
include Awardable
include Importable
+ include FasterCacheKeys
# Attribute containing rendered and redacted Markdown as generated by
# Banzai::ObjectRenderer.
diff --git a/app/models/project.rb b/app/models/project.rb
index 83b848ded8b..3b1a53edc75 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -379,9 +379,10 @@ class Project < ActiveRecord::Base
joins(join_body).reorder('join_note_counts.amount DESC')
end
- # Deletes gitlab project export files older than 24 hours
- def remove_gitlab_exports!
- Gitlab::Popen.popen(%W(find #{Gitlab::ImportExport.storage_path} -not -path #{Gitlab::ImportExport.storage_path} -mmin +1440 -delete))
+ def cached_count
+ Rails.cache.fetch('total_project_count', expires_in: 5.minutes) do
+ Project.count
+ end
end
end
@@ -870,10 +871,16 @@ class Project < ActiveRecord::Base
# Check if current branch name is marked as protected in the system
def protected_branch?(branch_name)
+ return true if empty_repo? && default_branch_protected?
+
@protected_branches ||= self.protected_branches.to_a
ProtectedBranch.matching(branch_name, protected_branches: @protected_branches).present?
end
+ def user_can_push_to_empty_repo?(user)
+ !default_branch_protected? || team.max_member_access(user.id) > Gitlab::Access::DEVELOPER
+ end
+
def forked?
!(forked_project_link.nil? || forked_project_link.forked_from_project.nil?)
end
@@ -1154,16 +1161,6 @@ class Project < ActiveRecord::Base
@wiki ||= ProjectWiki.new(self, self.owner)
end
- def schedule_delete!(user_id, params)
- # Queue this task for after the commit, so once we mark pending_delete it will run
- run_after_commit do
- job_id = ProjectDestroyWorker.perform_async(id, user_id, params)
- Rails.logger.info("User #{user_id} scheduled destruction of project #{path_with_namespace} with job ID #{job_id}")
- end
-
- update_attribute(:pending_delete, true)
- end
-
def running_or_pending_build_count(force: false)
Rails.cache.fetch(['projects', id, 'running_or_pending_build_count'], force: force) do
builds.running_or_pending.count(:all)
@@ -1265,6 +1262,11 @@ class Project < ActiveRecord::Base
private
+ def default_branch_protected?
+ current_application_settings.default_branch_protection == Gitlab::Access::PROTECTION_FULL ||
+ current_application_settings.default_branch_protection == Gitlab::Access::PROTECTION_DEV_CAN_MERGE
+ end
+
def authorized_for_user_by_group?(user, min_access_level)
member = user.group_members.find_by(source_id: group)
diff --git a/app/models/project_team.rb b/app/models/project_team.rb
index 19fd082534c..d0a714cd6fc 100644
--- a/app/models/project_team.rb
+++ b/app/models/project_team.rb
@@ -34,7 +34,7 @@ class ProjectTeam
end
def add_users(users, access, current_user = nil)
- ProjectMember.add_users_into_projects(
+ ProjectMember.add_users_to_projects(
[project.id],
users,
access,
diff --git a/app/models/repository.rb b/app/models/repository.rb
index bac37483c47..e56bac509a4 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -372,7 +372,7 @@ class Repository
# We don't want to flush the cache if the commit didn't actually make any
# changes to any of the possible avatar files.
if revision && commit = self.commit(revision)
- return unless commit.diffs.
+ return unless commit.raw_diffs(deltas_only: true).
any? { |diff| AVATAR_FILES.include?(diff.new_path) }
end
@@ -601,7 +601,7 @@ class Repository
commit(sha)
end
- def next_branch(name, opts={})
+ def next_branch(name, opts = {})
branch_ids = self.branch_names.map do |n|
next 1 if n == name
result = n.match(/\A#{name}-([0-9]+)\z/)
@@ -636,9 +636,7 @@ class Repository
def tags_sorted_by(value)
case value
when 'name'
- # Would be better to use `sort_by` but `version_sorter` only exposes
- # `sort` and `rsort`
- VersionSorter.rsort(tag_names).map { |tag_name| find_tag(tag_name) }
+ VersionSorter.rsort(tags) { |tag| tag.name }
when 'updated_desc'
tags_sorted_by_committed_date.reverse
when 'updated_asc'
diff --git a/app/services/compare_service.rb b/app/services/compare_service.rb
index 149822aa647..6d6075628af 100644
--- a/app/services/compare_service.rb
+++ b/app/services/compare_service.rb
@@ -20,10 +20,12 @@ class CompareService
)
end
- Gitlab::Git::Compare.new(
+ raw_compare = Gitlab::Git::Compare.new(
target_project.repository.raw_repository,
target_branch,
- source_sha,
+ source_sha
)
+
+ Compare.new(raw_compare, target_project)
end
end
diff --git a/app/services/delete_user_service.rb b/app/services/delete_user_service.rb
index ce79287e35a..2f237de813c 100644
--- a/app/services/delete_user_service.rb
+++ b/app/services/delete_user_service.rb
@@ -18,7 +18,7 @@ class DeleteUserService
user.personal_projects.each do |project|
# Skip repository removal because we remove directory with namespace
# that contain all this repositories
- ::Projects::DestroyService.new(project, current_user, skip_repo: true).pending_delete!
+ ::Projects::DestroyService.new(project, current_user, skip_repo: true).async_execute
end
user.destroy
diff --git a/app/services/destroy_group_service.rb b/app/services/destroy_group_service.rb
index 3c42ac61be4..a4ebccb5606 100644
--- a/app/services/destroy_group_service.rb
+++ b/app/services/destroy_group_service.rb
@@ -9,7 +9,7 @@ class DestroyGroupService
group.projects.each do |project|
# Skip repository removal because we remove directory with namespace
# that contain all this repositories
- ::Projects::DestroyService.new(project, current_user, skip_repo: true).pending_delete!
+ ::Projects::DestroyService.new(project, current_user, skip_repo: true).async_execute
end
group.destroy
diff --git a/app/services/import_export_clean_up_service.rb b/app/services/import_export_clean_up_service.rb
new file mode 100644
index 00000000000..6442406d77e
--- /dev/null
+++ b/app/services/import_export_clean_up_service.rb
@@ -0,0 +1,24 @@
+class ImportExportCleanUpService
+ LAST_MODIFIED_TIME_IN_MINUTES = 1440
+
+ attr_reader :mmin, :path
+
+ def initialize(mmin = LAST_MODIFIED_TIME_IN_MINUTES)
+ @mmin = mmin
+ @path = Gitlab::ImportExport.storage_path
+ end
+
+ def execute
+ Gitlab::Metrics.measure(:import_export_clean_up) do
+ return unless File.directory?(path)
+
+ clean_up_export_files
+ end
+ end
+
+ private
+
+ def clean_up_export_files
+ Gitlab::Popen.popen(%W(find #{path} -not -path #{path} -mmin +#{mmin} -delete))
+ end
+end
diff --git a/app/services/merge_requests/build_service.rb b/app/services/merge_requests/build_service.rb
index 7fe57747265..290742f1506 100644
--- a/app/services/merge_requests/build_service.rb
+++ b/app/services/merge_requests/build_service.rb
@@ -34,7 +34,7 @@ module MergeRequests
# At this point we decide if merge request can be created
# If we have at least one commit to merge -> creation allowed
if commits.present?
- merge_request.compare_commits = Commit.decorate(commits, merge_request.source_project)
+ merge_request.compare_commits = commits
merge_request.can_be_created = true
merge_request.compare = compare
else
diff --git a/app/services/merge_requests/merge_request_diff_cache_service.rb b/app/services/merge_requests/merge_request_diff_cache_service.rb
new file mode 100644
index 00000000000..2945a7fd4e4
--- /dev/null
+++ b/app/services/merge_requests/merge_request_diff_cache_service.rb
@@ -0,0 +1,8 @@
+module MergeRequests
+ class MergeRequestDiffCacheService
+ def execute(merge_request)
+ # Executing the iteration we cache all the highlighted diff information
+ merge_request.diffs.diff_files.to_a
+ end
+ end
+end
diff --git a/app/services/projects/destroy_service.rb b/app/services/projects/destroy_service.rb
index 882606e38d0..8a53f65aec1 100644
--- a/app/services/projects/destroy_service.rb
+++ b/app/services/projects/destroy_service.rb
@@ -6,8 +6,12 @@ module Projects
DELETED_FLAG = '+deleted'
- def pending_delete!
- project.schedule_delete!(current_user.id, params)
+ def async_execute
+ project.transaction do
+ project.update_attribute(:pending_delete, true)
+ job_id = ProjectDestroyWorker.perform_async(project.id, current_user.id, params)
+ Rails.logger.info("User #{current_user.id} scheduled destruction of project #{project.path_with_namespace} with job ID #{job_id}")
+ end
end
def execute
diff --git a/app/services/projects/enable_deploy_key_service.rb b/app/services/projects/enable_deploy_key_service.rb
new file mode 100644
index 00000000000..3cf4264ce9b
--- /dev/null
+++ b/app/services/projects/enable_deploy_key_service.rb
@@ -0,0 +1,17 @@
+module Projects
+ class EnableDeployKeyService < BaseService
+ def execute
+ key = accessible_keys.find_by(id: params[:key_id] || params[:id])
+ return unless key
+
+ project.deploy_keys << key
+ key
+ end
+
+ private
+
+ def accessible_keys
+ current_user.accessible_deploy_keys
+ end
+ end
+end
diff --git a/app/services/repository_archive_clean_up_service.rb b/app/services/repository_archive_clean_up_service.rb
index 0b56b09738d..aa84d36a206 100644
--- a/app/services/repository_archive_clean_up_service.rb
+++ b/app/services/repository_archive_clean_up_service.rb
@@ -1,6 +1,8 @@
class RepositoryArchiveCleanUpService
LAST_MODIFIED_TIME_IN_MINUTES = 120
+ attr_reader :mmin, :path
+
def initialize(mmin = LAST_MODIFIED_TIME_IN_MINUTES)
@mmin = mmin
@path = Gitlab.config.gitlab.repository_downloads_path
@@ -17,8 +19,6 @@ class RepositoryArchiveCleanUpService
private
- attr_reader :mmin, :path
-
def clean_up_old_archives
run(%W(find #{path} -not -path #{path} -type f \( -name \*.tar -o -name \*.bz2 -o -name \*.tar.gz -o -name \*.zip \) -maxdepth 2 -mmin +#{mmin} -delete))
end
diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml
index 23b52d08df7..c7fd344eea2 100644
--- a/app/views/admin/application_settings/_form.html.haml
+++ b/app/views/admin/application_settings/_form.html.haml
@@ -228,6 +228,9 @@
= f.label :max_artifacts_size, 'Maximum artifacts size (MB)', class: 'control-label col-sm-2'
.col-sm-10
= f.number_field :max_artifacts_size, class: 'form-control'
+ .help-block
+ Set the maximum file size each build's artifacts can have
+ = link_to "(?)", help_page_path("user/admin_area/settings/continuous_integration", anchor: "maximum-artifacts-size")
- if Gitlab.config.registry.enabled
%fieldset
@@ -363,7 +366,9 @@
.col-sm-10
= f.select :repository_storage, repository_storage_options_for_select, {}, class: 'form-control'
.help-block
- You can manage the repository storage paths in your gitlab.yml configuration file
+ Manage repository storage paths. Learn more in the
+ = succeed "." do
+ = link_to "repository storages documentation", help_page_path("administration/repository_storages")
%fieldset
%legend Repository Checks
@@ -385,4 +390,4 @@
.form-actions
- = f.submit 'Save', class: 'btn btn-save' \ No newline at end of file
+ = f.submit 'Save', class: 'btn btn-save'
diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml
index 452fc25ab07..e6687f43816 100644
--- a/app/views/admin/dashboard/index.html.haml
+++ b/app/views/admin/dashboard/index.html.haml
@@ -112,7 +112,7 @@
%h4 Projects
.data
= link_to admin_namespaces_projects_path do
- %h1= number_with_delimiter(Project.count)
+ %h1= number_with_delimiter(Project.cached_count)
%hr
= link_to('New Project', new_project_path, class: "btn btn-new")
.col-sm-4
diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml
index d37489bebea..76c9ed0ee8b 100644
--- a/app/views/admin/users/show.html.haml
+++ b/app/views/admin/users/show.html.haml
@@ -140,12 +140,10 @@
.panel-heading
This user is blocked
.panel-body
- %p Blocking user has the following effects:
+ %p A blocked user cannot:
%ul
- %li User will not be able to login
- %li User will not be able to access git repositories
- %li Personal projects will be left
- %li Owned groups will be left
+ %li Log in
+ %li Access Git repositories
%br
= link_to 'Unblock user', unblock_admin_user_path(@user), method: :put, class: "btn btn-info", data: { confirm: 'Are you sure?' }
- else
diff --git a/app/views/devise/sessions/_new_crowd.html.haml b/app/views/devise/sessions/_new_crowd.html.haml
index 8e81671b7e7..b7d3acac2b1 100644
--- a/app/views/devise/sessions/_new_crowd.html.haml
+++ b/app/views/devise/sessions/_new_crowd.html.haml
@@ -1,4 +1,4 @@
-= form_tag(user_omniauth_authorize_path("crowd"), id: 'new_crowd_user' ) do
+= form_tag(omniauth_authorize_path(:user, :crowd), id: 'new_crowd_user' ) do
= text_field_tag :username, nil, {class: "form-control top", placeholder: "Username", autofocus: "autofocus"}
= password_field_tag :password, nil, {class: "form-control bottom", placeholder: "Password"}
- if devise_mapping.rememberable?
diff --git a/app/views/devise/shared/_omniauth_box.html.haml b/app/views/devise/shared/_omniauth_box.html.haml
index de18bc2d844..2e7da2747d0 100644
--- a/app/views/devise/shared/_omniauth_box.html.haml
+++ b/app/views/devise/shared/_omniauth_box.html.haml
@@ -5,4 +5,4 @@
- providers.each do |provider|
%span.light
- has_icon = provider_has_icon?(provider)
- = link_to provider_image_tag(provider), user_omniauth_authorize_path(provider), method: :post, class: (has_icon ? 'oauth-image-link' : 'btn'), "data-no-turbolink" => "true"
+ = link_to provider_image_tag(provider), omniauth_authorize_path(:user, provider), method: :post, class: (has_icon ? 'oauth-image-link' : 'btn'), "data-no-turbolink" => "true"
diff --git a/app/views/import/github/status.html.haml b/app/views/import/github/status.html.haml
index deaaf9af875..54ff1d27c67 100644
--- a/app/views/import/github/status.html.haml
+++ b/app/views/import/github/status.html.haml
@@ -4,10 +4,6 @@
%i.fa.fa-github
Import projects from GitHub
-%p
- %i.fa.fa-warning
- To import GitHub pull requests, any pull request source branches that had been deleted are temporarily restored on GitHub. To prevent any connected CI services from being overloaded with dozens of irrelevant branches being created and deleted again, GitHub webhooks are temporarily disabled during the import process, but only if you have admin access to the GitHub repository.
-
%p.light
Select projects you want to import.
%hr
diff --git a/app/views/notify/new_issue_email.text.erb b/app/views/notify/new_issue_email.text.erb
index fc64c98038b..ca5c2f2688c 100644
--- a/app/views/notify/new_issue_email.text.erb
+++ b/app/views/notify/new_issue_email.text.erb
@@ -3,3 +3,5 @@ New Issue was created.
Issue <%= @issue.iid %>: <%= url_for(namespace_project_issue_url(@issue.project.namespace, @issue.project, @issue)) %>
Author: <%= @issue.author_name %>
Assignee: <%= @issue.assignee_name %>
+
+<%= @issue.description %>
diff --git a/app/views/notify/new_merge_request_email.text.erb b/app/views/notify/new_merge_request_email.text.erb
index d4aad8d1862..3c8f178ac77 100644
--- a/app/views/notify/new_merge_request_email.text.erb
+++ b/app/views/notify/new_merge_request_email.text.erb
@@ -6,3 +6,5 @@ New Merge Request <%= @merge_request.to_reference %>
Author: <%= @merge_request.author_name %>
Assignee: <%= @merge_request.assignee_name %>
+<%= @merge_request.description %>
+
diff --git a/app/views/profiles/accounts/show.html.haml b/app/views/profiles/accounts/show.html.haml
index 57d16d29158..c80f22457b4 100644
--- a/app/views/profiles/accounts/show.html.haml
+++ b/app/views/profiles/accounts/show.html.haml
@@ -70,7 +70,7 @@
= link_to unlink_profile_account_path(provider: provider), method: :delete, class: 'provider-btn' do
Disconnect
- else
- = link_to user_omniauth_authorize_path(provider), method: :post, class: 'provider-btn not-active', "data-no-turbolink" => "true" do
+ = link_to omniauth_authorize_path(:user, provider), method: :post, class: 'provider-btn not-active', "data-no-turbolink" => "true" do
Connect
%hr
- if current_user.can_change_username?
diff --git a/app/views/projects/badges/badge.svg.erb b/app/views/projects/badges/badge.svg.erb
new file mode 100644
index 00000000000..a5fef4fc56f
--- /dev/null
+++ b/app/views/projects/badges/badge.svg.erb
@@ -0,0 +1,36 @@
+<svg xmlns="http://www.w3.org/2000/svg" width="<%= badge.width %>" height="20">
+ <linearGradient id="b" x2="0" y2="100%">
+ <stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
+ <stop offset="1" stop-opacity=".1"/>
+ </linearGradient>
+
+ <mask id="a">
+ <rect width="<%= badge.width %>" height="20" rx="3" fill="#fff"/>
+ </mask>
+
+ <g mask="url(#a)">
+ <path fill="<%= badge.key_color %>"
+ d="M0 0 h<%= badge.key_width %> v20 H0 z"/>
+ <path fill="<%= badge.value_color %>"
+ d="M<%= badge.key_width %> 0 h<%= badge.value_width %> v20 H<%= badge.key_width %> z"/>
+ <path fill="url(#b)"
+ d="M0 0 h<%= badge.width %> v20 H0 z"/>
+ </g>
+
+ <g fill="#fff" text-anchor="middle">
+ <g font-family="DejaVu Sans,Verdana,Geneva,sans-serif" font-size="11">
+ <text x="<%= badge.key_text_anchor %>" y="15" fill="#010101" fill-opacity=".3">
+ <%= badge.key_text %>
+ </text>
+ <text x="<%= badge.key_text_anchor %>" y="14">
+ <%= badge.key_text %>
+ </text>
+ <text x="<%= badge.value_text_anchor %>" y="15" fill="#010101" fill-opacity=".3">
+ <%= badge.value_text %>
+ </text>
+ <text x="<%= badge.value_text_anchor %>" y="14">
+ <%= badge.value_text %>
+ </text>
+ </g>
+ </g>
+</svg>
diff --git a/app/views/projects/blob/diff.html.haml b/app/views/projects/blob/diff.html.haml
index 5926d181ba3..a79ae53c780 100644
--- a/app/views/projects/blob/diff.html.haml
+++ b/app/views/projects/blob/diff.html.haml
@@ -1,20 +1,30 @@
- if @lines.present?
+ - line_class = diff_view == :inline ? '' : diff_view
- if @form.unfold? && @form.since != 1 && !@form.bottom?
- %tr.line_holder
- = render "projects/diffs/match_line", { line: @match_line,
- line_old: @form.since, line_new: @form.since, bottom: false, new_file: false }
+ %tr.line_holder{ class: line_class }
+ = diff_match_line @form.since, @form.since, text: @match_line, view: diff_view
- @lines.each_with_index do |line, index|
- line_new = index + @form.since
- line_old = line_new - @form.offset
- %tr.line_holder{ id: line_old }
- %td.old_line.diff-line-num{ data: { linenumber: line_old } }
- = link_to raw(line_old), "##{line_old}"
- %td.new_line.diff-line-num{ data: { linenumber: line_old } }
- = link_to raw(line_new) , "##{line_old}"
- %td.line_content.noteable_line==#{' ' * @form.indent}#{line}
+ - line_content = capture do
+ %td.line_content.noteable_line{ class: line_class }==#{' ' * @form.indent}#{line}
+ %tr.line_holder{ id: line_old, class: line_class }
+ - case diff_view
+ - when :inline
+ %td.old_line.diff-line-num{ data: { linenumber: line_old } }
+ %a{href: "##{line_old}", data: { linenumber: line_old }}
+ %td.new_line.diff-line-num{ data: { linenumber: line_new } }
+ %a{href: "##{line_new}", data: { linenumber: line_new }}
+ = line_content
+ - when :parallel
+ %td.old_line.diff-line-num{data: { linenumber: line_old }}
+ = link_to raw(line_old), "##{line_old}"
+ = line_content
+ %td.new_line.diff-line-num{data: { linenumber: line_new }}
+ = link_to raw(line_new), "##{line_new}"
+ = line_content
- if @form.unfold? && @form.bottom? && @form.to < @blob.loc
- %tr.line_holder{ id: @form.to }
- = render "projects/diffs/match_line", { line: @match_line,
- line_old: @form.to, line_new: @form.to, bottom: true, new_file: false }
+ %tr.line_holder{ id: @form.to, class: line_class }
+ = diff_match_line @form.to, @form.to, text: @match_line, view: diff_view, bottom: true
diff --git a/app/views/projects/ci/pipelines/_pipeline.html.haml b/app/views/projects/ci/pipelines/_pipeline.html.haml
index 558c35553da..9a594877803 100644
--- a/app/views/projects/ci/pipelines/_pipeline.html.haml
+++ b/app/views/projects/ci/pipelines/_pipeline.html.haml
@@ -53,7 +53,7 @@
- if pipeline.finished_at
%p.finished-at
= icon("calendar")
- #{time_ago_with_tooltip(pipeline.finished_at)}
+ #{time_ago_with_tooltip(pipeline.finished_at, short_format: true, skip_js: true)}
%td.pipeline-actions
.controls.hidden-xs.pull-right
diff --git a/app/views/projects/commit/_ci_menu.html.haml b/app/views/projects/commit/_ci_menu.html.haml
index ea33aa472a6..935433306ea 100644
--- a/app/views/projects/commit/_ci_menu.html.haml
+++ b/app/views/projects/commit/_ci_menu.html.haml
@@ -2,7 +2,7 @@
= nav_link(path: 'commit#show') do
= link_to namespace_project_commit_path(@project.namespace, @project, @commit.id) do
Changes
- %span.badge= @diffs.count
+ %span.badge= @diffs.size
= nav_link(path: 'commit#builds') do
= link_to builds_namespace_project_commit_path(@project.namespace, @project, @commit.id) do
Builds
diff --git a/app/views/projects/commit/show.html.haml b/app/views/projects/commit/show.html.haml
index d0da2606587..ed44d86a687 100644
--- a/app/views/projects/commit/show.html.haml
+++ b/app/views/projects/commit/show.html.haml
@@ -7,7 +7,7 @@
= render "ci_menu"
- else
%div.block-connector
-= render "projects/diffs/diffs", diffs: @diffs, project: @project, diff_refs: @commit.diff_refs
+= render "projects/diffs/diffs", diffs: @diffs
= render "projects/notes/notes_with_form"
- if can_collaborate_with_project?
- %w(revert cherry-pick).each do |type|
diff --git a/app/views/projects/compare/show.html.haml b/app/views/projects/compare/show.html.haml
index 28a50e7031a..819e9bc15ae 100644
--- a/app/views/projects/compare/show.html.haml
+++ b/app/views/projects/compare/show.html.haml
@@ -8,7 +8,7 @@
- if @commits.present?
= render "projects/commits/commit_list"
- = render "projects/diffs/diffs", diffs: @diffs, project: @project, diff_refs: @diff_refs
+ = render "projects/diffs/diffs", diffs: @diffs
- else
.light-well
.center
diff --git a/app/views/projects/diffs/_content.html.haml b/app/views/projects/diffs/_content.html.haml
index a1b071f130c..d37961c4e40 100644
--- a/app/views/projects/diffs/_content.html.haml
+++ b/app/views/projects/diffs/_content.html.haml
@@ -13,7 +13,7 @@
.nothing-here-block.diff-collapsed{data: { diff_for_path: url } }
This diff is collapsed. Click to expand it.
- elsif diff_file.diff_lines.length > 0
- - if diff_view == 'parallel'
+ - if diff_view == :parallel
= render "projects/diffs/parallel_view", diff_file: diff_file, project: project, blob: blob
- else
= render "projects/diffs/text_file", diff_file: diff_file
diff --git a/app/views/projects/diffs/_diffs.html.haml b/app/views/projects/diffs/_diffs.html.haml
index 4bf3ccace20..62aff36aadd 100644
--- a/app/views/projects/diffs/_diffs.html.haml
+++ b/app/views/projects/diffs/_diffs.html.haml
@@ -1,20 +1,19 @@
- show_whitespace_toggle = local_assigns.fetch(:show_whitespace_toggle, true)
-- if diff_view == 'parallel'
+- diff_files = diffs.diff_files
+- if diff_view == :parallel
- fluid_layout true
-- diff_files = safe_diff_files(diffs, diff_refs: diff_refs, repository: project.repository)
-
.content-block.oneline-block.files-changed
.inline-parallel-buttons
- if !expand_all_diffs? && diff_files.any? { |diff_file| diff_file.collapsed? }
= link_to 'Expand all', url_for(params.merge(expand_all_diffs: 1, format: nil)), class: 'btn btn-default'
- if show_whitespace_toggle
- if current_controller?(:commit)
- = commit_diff_whitespace_link(@project, @commit, class: 'hidden-xs')
+ = commit_diff_whitespace_link(diffs.project, @commit, class: 'hidden-xs')
- elsif current_controller?(:merge_requests)
- = diff_merge_request_whitespace_link(@project, @merge_request, class: 'hidden-xs')
+ = diff_merge_request_whitespace_link(diffs.project, @merge_request, class: 'hidden-xs')
- elsif current_controller?(:compare)
- = diff_compare_whitespace_link(@project, params[:from], params[:to], class: 'hidden-xs')
+ = diff_compare_whitespace_link(diffs.project, params[:from], params[:to], class: 'hidden-xs')
.btn-group
= inline_diff_btn
= parallel_diff_btn
@@ -23,12 +22,12 @@
- if diff_files.overflow?
= render 'projects/diffs/warning', diff_files: diff_files
-.files{data: {can_create_note: (!@diff_notes_disabled && can?(current_user, :create_note, @project))}}
+.files{data: {can_create_note: (!@diff_notes_disabled && can?(current_user, :create_note, diffs.project))}}
- diff_files.each_with_index do |diff_file, index|
- diff_commit = commit_for_diff(diff_file)
- blob = diff_file.blob(diff_commit)
- next unless blob
- - blob.load_all_data!(project.repository) unless blob.only_display_raw?
+ - blob.load_all_data!(diffs.project.repository) unless blob.only_display_raw?
- = render 'projects/diffs/file', i: index, project: project,
- diff_file: diff_file, diff_commit: diff_commit, blob: blob, diff_refs: diff_refs
+ = render 'projects/diffs/file', index: index, project: diffs.project,
+ diff_file: diff_file, diff_commit: diff_commit, blob: blob
diff --git a/app/views/projects/diffs/_file.html.haml b/app/views/projects/diffs/_file.html.haml
index 1854c64cbd7..f0a86fd6d40 100644
--- a/app/views/projects/diffs/_file.html.haml
+++ b/app/views/projects/diffs/_file.html.haml
@@ -1,6 +1,6 @@
-.diff-file.file-holder{id: "diff-#{i}", data: diff_file_html_data(project, diff_file)}
+.diff-file.file-holder{id: "diff-#{index}", data: diff_file_html_data(project, diff_file)}
.file-title{id: "file-path-#{hexdigest(diff_file.file_path)}"}
- = render "projects/diffs/file_header", diff_file: diff_file, blob: blob, diff_commit: diff_commit, project: project, url: "#diff-#{i}"
+ = render "projects/diffs/file_header", diff_file: diff_file, blob: blob, diff_commit: diff_commit, project: project, url: "#diff-#{index}"
- unless diff_file.submodule?
.file-actions.hidden-xs
@@ -15,6 +15,6 @@
from_merge_request_id: @merge_request.id,
skip_visible_check: true)
- = view_file_btn(diff_commit.id, diff_file, project)
+ = view_file_btn(diff_commit.id, diff_file.new_path, project)
- = render 'projects/diffs/content', diff_file: diff_file, diff_commit: diff_commit, diff_refs: diff_refs, blob: blob, project: project
+ = render 'projects/diffs/content', diff_file: diff_file, diff_commit: diff_commit, blob: blob, project: project
diff --git a/app/views/projects/diffs/_line.html.haml b/app/views/projects/diffs/_line.html.haml
index 4d3af905b58..2d6a370b848 100644
--- a/app/views/projects/diffs/_line.html.haml
+++ b/app/views/projects/diffs/_line.html.haml
@@ -4,8 +4,7 @@
%tr.line_holder{ plain ? { class: type} : { class: type, id: line_code } }
- case type
- when 'match'
- = render "projects/diffs/match_line", { line: line.text,
- line_old: line.old_pos, line_new: line.new_pos, bottom: false, new_file: diff_file.new_file }
+ = diff_match_line line.old_pos, line.new_pos, text: line.text
- when 'nonewline'
%td.old_line.diff-line-num
%td.new_line.diff-line-num
diff --git a/app/views/projects/diffs/_match_line.html.haml b/app/views/projects/diffs/_match_line.html.haml
deleted file mode 100644
index d6dddd97879..00000000000
--- a/app/views/projects/diffs/_match_line.html.haml
+++ /dev/null
@@ -1,7 +0,0 @@
-%td.old_line.diff-line-num{data: {linenumber: line_old},
- class: [unfold_bottom_class(bottom), unfold_class(!new_file)]}
- \...
-%td.new_line.diff-line-num{data: {linenumber: line_new},
- class: [unfold_bottom_class(bottom), unfold_class(!new_file)]}
- \...
-%td.line_content.match= line
diff --git a/app/views/projects/diffs/_parallel_view.html.haml b/app/views/projects/diffs/_parallel_view.html.haml
index 7f30faa20d8..28aad3f4725 100644
--- a/app/views/projects/diffs/_parallel_view.html.haml
+++ b/app/views/projects/diffs/_parallel_view.html.haml
@@ -1,14 +1,15 @@
/ Side-by-side diff view
%div.text-file.diff-wrap-lines.code.file-content.js-syntax-highlight{ data: diff_view_data }
%table
+ - last_line = 0
- diff_file.parallel_diff_lines.each do |line|
- left = line[:left]
- right = line[:right]
+ - last_line = right.new_pos if right
%tr.line_holder.parallel
- if left
- if left.meta?
- %td.old_line.diff-line-num.empty-cell
- %td.line_content.parallel.match= left.text
+ = diff_match_line left.old_pos, nil, text: left.text, view: :parallel
- else
- left_line_code = diff_file.line_code(left)
- left_position = diff_file.position(left)
@@ -21,8 +22,7 @@
- if right
- if right.meta?
- %td.old_line.diff-line-num.empty-cell
- %td.line_content.parallel.match= left.text
+ = diff_match_line nil, right.new_pos, text: left.text, view: :parallel
- else
- right_line_code = diff_file.line_code(right)
- right_position = diff_file.position(right)
@@ -37,3 +37,5 @@
- discussion_left, discussion_right = parallel_diff_discussions(left, right, diff_file)
- if discussion_left || discussion_right
= render "discussions/parallel_diff_discussion", discussion_left: discussion_left, discussion_right: discussion_right
+ - if !diff_file.new_file && last_line > 0
+ = diff_match_line last_line, last_line, bottom: true, view: :parallel
diff --git a/app/views/projects/diffs/_text_file.html.haml b/app/views/projects/diffs/_text_file.html.haml
index 5970b9abf2b..ab5463ba89d 100644
--- a/app/views/projects/diffs/_text_file.html.haml
+++ b/app/views/projects/diffs/_text_file.html.haml
@@ -15,6 +15,5 @@
- if discussion
= render "discussions/diff_discussion", discussion: discussion
- - if last_line > 0
- = render "projects/diffs/match_line", { line: "",
- line_old: last_line, line_new: last_line, bottom: true, new_file: diff_file.new_file }
+ - if !diff_file.new_file && last_line > 0
+ = diff_match_line last_line, last_line, bottom: true
diff --git a/app/views/projects/merge_requests/_new_submit.html.haml b/app/views/projects/merge_requests/_new_submit.html.haml
index a5e67b95727..598bd743676 100644
--- a/app/views/projects/merge_requests/_new_submit.html.haml
+++ b/app/views/projects/merge_requests/_new_submit.html.haml
@@ -42,7 +42,7 @@
%h4 This comparison includes more than #{MergeRequestDiff::COMMITS_SAFE_SIZE} commits.
%p To preserve performance the line changes are not shown.
- else
- = render "projects/diffs/diffs", diffs: @diffs, project: @project, diff_refs: @merge_request.diff_refs, show_whitespace_toggle: false
+ = render "projects/diffs/diffs", diffs: @diffs, show_whitespace_toggle: false
- if @pipeline
#builds.builds.tab-pane
= render "projects/merge_requests/show/builds"
diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml
index 873ed9b59ee..269198adf91 100644
--- a/app/views/projects/merge_requests/_show.html.haml
+++ b/app/views/projects/merge_requests/_show.html.haml
@@ -2,7 +2,7 @@
- page_description @merge_request.description
- page_card_attributes @merge_request.card_attributes
-- if diff_view == 'parallel'
+- if diff_view == :parallel
- fluid_layout true
.merge-request{'data-url' => merge_request_path(@merge_request)}
diff --git a/app/views/projects/merge_requests/show/_diffs.html.haml b/app/views/projects/merge_requests/show/_diffs.html.haml
index 1b0bae86ad4..013b05628fa 100644
--- a/app/views/projects/merge_requests/show/_diffs.html.haml
+++ b/app/views/projects/merge_requests/show/_diffs.html.haml
@@ -1,6 +1,5 @@
- if @merge_request_diff.collected?
- = render "projects/diffs/diffs", diffs: @merge_request.diffs(diff_options),
- project: @merge_request.project, diff_refs: @merge_request.diff_refs
+ = render "projects/diffs/diffs", diffs: @diffs
- elsif @merge_request_diff.empty?
.nothing-here-block Nothing to merge from #{@merge_request.source_branch} into #{@merge_request.target_branch}
- else
diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml
index facdfcc9447..adcc984f506 100644
--- a/app/views/projects/new.html.haml
+++ b/app/views/projects/new.html.haml
@@ -46,28 +46,18 @@
%div
- if github_import_enabled?
= link_to new_import_github_path, class: 'btn import_github' do
- = icon 'github', text: 'GitHub'
+ = icon('github', text: 'GitHub')
%div
- if bitbucket_import_enabled?
- - if bitbucket_import_configured?
- = link_to status_import_bitbucket_path, class: 'btn import_bitbucket', "data-no-turbolink" => "true" do
- %i.fa.fa-bitbucket
- Bitbucket
- - else
- = link_to status_import_bitbucket_path, class: 'how_to_import_link btn import_bitbucket', "data-no-turbolink" => "true" do
- %i.fa.fa-bitbucket
- Bitbucket
+ = link_to status_import_bitbucket_path, class: "btn import_bitbucket #{'how_to_import_link' unless bitbucket_import_configured?}", "data-no-turbolink" => "true" do
+ = icon('bitbucket', text: 'Bitbucket')
+ - unless bitbucket_import_configured?
= render 'bitbucket_import_modal'
%div
- if gitlab_import_enabled?
- - if gitlab_import_configured?
- = link_to status_import_gitlab_path, class: 'btn import_gitlab' do
- %i.fa.fa-heart
- GitLab.com
- - else
- = link_to status_import_gitlab_path, class: 'how_to_import_link btn import_gitlab' do
- %i.fa.fa-heart
- GitLab.com
+ = link_to status_import_gitlab_path, class: "btn import_gitlab #{'how_to_import_link' unless bitbucket_import_configured?}" do
+ = icon('gitlab', text: 'GitLab.com')
+ - unless gitlab_import_configured?
= render 'gitlab_import_modal'
%div
- if gitorious_import_enabled?
@@ -77,23 +67,19 @@
%div
- if google_code_import_enabled?
= link_to new_import_google_code_path, class: 'btn import_google_code' do
- %i.fa.fa-google
- Google Code
+ = icon('google', text: 'Google Code')
%div
- if fogbugz_import_enabled?
= link_to new_import_fogbugz_path, class: 'btn import_fogbugz' do
- %i.fa.fa-bug
- Fogbugz
+ = icon('bug', text: 'Fogbugz')
%div
- if git_import_enabled?
= link_to "#", class: 'btn js-toggle-button import_git' do
- %i.fa.fa-git
- %span Repo by URL
+ = icon('git', text: 'Repo by URL')
%div{ class: 'import_gitlab_project' }
- if gitlab_project_import_enabled?
= link_to new_import_gitlab_project_path, class: 'btn btn_import_gitlab_project project-submit' do
- %i.fa.fa-gitlab
- %span GitLab export
+ = icon('gitlab', text: 'GitLab export')
.js-toggle-content.hide
= render "shared/import_form", f: f
@@ -159,4 +145,4 @@
$('.import_git').click(function( event ) {
$projectImportUrl = $('#project_import_url')
$projectImportUrl.attr('disabled', !$projectImportUrl.attr('disabled'))
- }); \ No newline at end of file
+ });
diff --git a/app/views/projects/protected_branches/_branches_list.html.haml b/app/views/projects/protected_branches/_branches_list.html.haml
index 0603a014008..04b19a8c5a7 100644
--- a/app/views/projects/protected_branches/_branches_list.html.haml
+++ b/app/views/projects/protected_branches/_branches_list.html.haml
@@ -1,26 +1,28 @@
-%h5.prepend-top-0
- Already Protected (#{@protected_branches.size})
-- if @protected_branches.empty?
- %p.settings-message.text-center
- No branches are protected, protect a branch with the form above.
-- else
- - can_admin_project = can?(current_user, :admin_project, @project)
+.panel.panel-default.protected-branches-list
+ - if @protected_branches.empty?
+ .panel-heading
+ %h3.panel-title
+ Protected branch (#{@protected_branches.size})
+ %p.settings-message.text-center
+ There are currently no protected branches, protect a branch with the form above.
+ - else
+ - can_admin_project = can?(current_user, :admin_project, @project)
- %table.table.protected-branches-list
- %colgroup
- %col{ width: "20%" }
- %col{ width: "30%" }
- %col{ width: "25%" }
- %col{ width: "25%" }
- %thead
- %tr
- %th Branch
- %th Last commit
- %th Allowed to merge
- %th Allowed to push
- - if can_admin_project
- %th
- %tbody
- = render partial: @protected_branches, locals: { can_admin_project: can_admin_project }
+ %table.table.table-bordered
+ %colgroup
+ %col{ width: "25%" }
+ %col{ width: "30%" }
+ %col{ width: "25%" }
+ %col{ width: "20%" }
+ %thead
+ %tr
+ %th Protected branch (#{@protected_branches.size})
+ %th Last commit
+ %th Allowed to merge
+ %th Allowed to push
+ - if can_admin_project
+ %th
+ %tbody
+ = render partial: @protected_branches, locals: { can_admin_project: can_admin_project }
- = paginate @protected_branches, theme: 'gitlab'
+ = paginate @protected_branches, theme: 'gitlab'
diff --git a/app/views/projects/protected_branches/_create_protected_branch.html.haml b/app/views/projects/protected_branches/_create_protected_branch.html.haml
new file mode 100644
index 00000000000..85d0c494ba8
--- /dev/null
+++ b/app/views/projects/protected_branches/_create_protected_branch.html.haml
@@ -0,0 +1,36 @@
+= form_for [@project.namespace.becomes(Namespace), @project, @protected_branch] do |f|
+ .panel.panel-default
+ .panel-heading
+ %h3.panel-title
+ Protect a branch
+ .panel-body
+ .form-horizontal
+ .form-group
+ = f.label :name, class: 'col-md-2 text-right' do
+ Branch:
+ .col-md-10
+ = render partial: "dropdown", locals: { f: f }
+ .help-block
+ = link_to 'Wildcards', help_page_path('user/project/protected_branches', anchor: 'wildcard-protected-branches')
+ such as
+ %code *-stable
+ or
+ %code production/*
+ are supported
+ .form-group
+ %label.col-md-2.text-right{ for: 'merge_access_level_attributes' }
+ Allowed to merge:
+ .col-md-10
+ = dropdown_tag('Select',
+ options: { toggle_class: 'js-allowed-to-merge wide',
+ data: { field_name: 'protected_branch[merge_access_level_attributes][access_level]', input_id: 'merge_access_level_attributes' }})
+ .form-group
+ %label.col-md-2.text-right{ for: 'push_access_level_attributes' }
+ Allowed to push:
+ .col-md-10
+ = dropdown_tag('Select',
+ options: { toggle_class: 'js-allowed-to-push wide',
+ data: { field_name: 'protected_branch[push_access_level_attributes][access_level]', input_id: 'push_access_level_attributes' }})
+
+ .panel-footer
+ = f.submit 'Protect', class: 'btn-create btn', disabled: true
diff --git a/app/views/projects/protected_branches/_dropdown.html.haml b/app/views/projects/protected_branches/_dropdown.html.haml
index b803d932e67..a9e27df5a87 100644
--- a/app/views/projects/protected_branches/_dropdown.html.haml
+++ b/app/views/projects/protected_branches/_dropdown.html.haml
@@ -1,17 +1,15 @@
= f.hidden_field(:name)
-= dropdown_tag("Protected Branch",
- options: { title: "Pick protected branch", toggle_class: 'js-protected-branch-select js-filter-submit',
+= dropdown_tag('Select branch or create wildcard',
+ options: { toggle_class: 'js-protected-branch-select js-filter-submit wide',
filter: true, dropdown_class: "dropdown-menu-selectable", placeholder: "Search protected branches",
footer_content: true,
data: { show_no: true, show_any: true, show_upcoming: true,
selected: params[:protected_branch_name],
project_id: @project.try(:id) } }) do
- %ul.dropdown-footer-list.hidden.protected-branch-select-footer-list
+ %ul.dropdown-footer-list
%li
= link_to '#', title: "New Protected Branch", class: "create-new-protected-branch" do
- Create new
-
-:javascript
- new ProtectedBranchSelect();
+ Create wildcard
+ %code
diff --git a/app/views/projects/protected_branches/_protected_branch.html.haml b/app/views/projects/protected_branches/_protected_branch.html.haml
index 498e412235e..e2e01ee78f8 100644
--- a/app/views/projects/protected_branches/_protected_branch.html.haml
+++ b/app/views/projects/protected_branches/_protected_branch.html.haml
@@ -1,5 +1,4 @@
-- url = namespace_project_protected_branch_path(@project.namespace, @project, protected_branch)
-%tr
+%tr.js-protected-branch-edit-form{ data: { url: namespace_project_protected_branch_path(@project.namespace, @project, protected_branch), branch_id: protected_branch.id } }
%td
= protected_branch.name
- if @project.root_ref?(protected_branch.name)
@@ -16,14 +15,14 @@
(branch was removed from repository)
%td
= hidden_field_tag "allowed_to_merge_#{protected_branch.id}", protected_branch.merge_access_level.access_level
- = dropdown_tag(protected_branch.merge_access_level.humanize,
- options: { title: "Allowed to merge", toggle_class: 'allowed-to-merge', dropdown_class: 'dropdown-menu-selectable merge',
- data: { field_name: "allowed_to_merge_#{protected_branch.id}", url: url, id: protected_branch.id, type: "merge_access_level" }})
+ = dropdown_tag( (protected_branch.merge_access_level.humanize || 'Select') ,
+ options: { toggle_class: 'js-allowed-to-merge', dropdown_class: 'dropdown-menu-selectable js-allowed-to-merge-container',
+ data: { field_name: "allowed_to_merge_#{protected_branch.id}" }})
%td
= hidden_field_tag "allowed_to_push_#{protected_branch.id}", protected_branch.push_access_level.access_level
- = dropdown_tag(protected_branch.push_access_level.humanize,
- options: { title: "Allowed to push", toggle_class: 'allowed-to-push', dropdown_class: 'dropdown-menu-selectable push',
- data: { field_name: "allowed_to_push_#{protected_branch.id}", url: url, id: protected_branch.id, type: "push_access_level" }})
+ = dropdown_tag( (protected_branch.push_access_level.humanize || 'Select') ,
+ options: { toggle_class: 'js-allowed-to-push', dropdown_class: 'dropdown-menu-selectable js-allowed-to-push-container',
+ data: { field_name: "allowed_to_push_#{protected_branch.id}" }})
- if can_admin_project
%td
- = link_to 'Unprotect', [@project.namespace.becomes(Namespace), @project, protected_branch], data: { confirm: 'Branch will be writable for developers. Are you sure?' }, method: :delete, class: "btn btn-warning btn-sm pull-right"
+ = link_to 'Unprotect', [@project.namespace.becomes(Namespace), @project, protected_branch], data: { confirm: 'Branch will be writable for developers. Are you sure?' }, method: :delete, class: 'btn btn-warning'
diff --git a/app/views/projects/protected_branches/index.html.haml b/app/views/projects/protected_branches/index.html.haml
index 4efe44c7233..49dcc9a6ba4 100644
--- a/app/views/projects/protected_branches/index.html.haml
+++ b/app/views/projects/protected_branches/index.html.haml
@@ -14,41 +14,7 @@
%li prevent <strong>anyone</strong> from deleting the branch
%p.append-bottom-0 Read more about #{link_to "protected branches", help_page_path("user/project/protected_branches"), class: "underlined-link"} and #{link_to "project permissions", help_page_path("user/permissions"), class: "underlined-link"}.
.col-lg-9
- %h5.prepend-top-0
- Protect a branch
- if can? current_user, :admin_project, @project
- = form_for [@project.namespace.becomes(Namespace), @project, @protected_branch] do |f|
- = form_errors(@protected_branch)
+ = render 'create_protected_branch'
- .form-group
- = f.label :name, "Branch", class: "label-light"
- = render partial: "dropdown", locals: { f: f }
- %p.help-block
- = link_to "Wildcards", help_page_path('user/project/protected_branches', anchor: "wildcard-protected-branches")
- such as
- %code *-stable
- or
- %code production/*
- are supported.
-
- .form-group
- = hidden_field_tag 'protected_branch[merge_access_level_attributes][access_level]'
- = label_tag "Allowed to merge: ", nil, class: "label-light append-bottom-0"
- = dropdown_tag("<Make a selection>",
- options: { title: "Allowed to merge", toggle_class: 'allowed-to-merge',
- dropdown_class: 'dropdown-menu-selectable',
- data: { field_name: "protected_branch[merge_access_level_attributes][access_level]" }})
-
- .form-group
- = hidden_field_tag 'protected_branch[push_access_level_attributes][access_level]'
- = label_tag "Allowed to push: ", nil, class: "label-light append-bottom-0"
- = dropdown_tag("<Make a selection>",
- options: { title: "Allowed to push", toggle_class: 'allowed-to-push',
- dropdown_class: 'dropdown-menu-selectable',
- data: { field_name: "protected_branch[push_access_level_attributes][access_level]" }})
-
-
- = f.submit "Protect", class: "btn-create btn protect-branch-btn", disabled: true
-
- %hr
= render "branches_list"
diff --git a/app/views/projects/tree/_tree_row.html.haml b/app/views/projects/tree/_tree_row.html.haml
new file mode 100644
index 00000000000..0a5c6f048f7
--- /dev/null
+++ b/app/views/projects/tree/_tree_row.html.haml
@@ -0,0 +1,6 @@
+- if tree_row.type == :tree
+ = render partial: 'projects/tree/tree_item', object: tree_row, as: 'tree_item', locals: { type: 'folder' }
+- elsif tree_row.type == :blob
+ = render partial: 'projects/tree/blob_item', object: tree_row, as: 'blob_item', locals: { type: 'file' }
+- elsif tree_row.type == :commit
+ = render partial: 'projects/tree/submodule_item', object: tree_row, as: 'submodule_item'
diff --git a/app/views/shared/_labels_row.html.haml b/app/views/shared/_labels_row.html.haml
index dce492352ac..e324d0e5203 100644
--- a/app/views/shared/_labels_row.html.haml
+++ b/app/views/shared/_labels_row.html.haml
@@ -1,9 +1,5 @@
- labels.each do |label|
%span.label-row.btn-group{ role: "group", aria: { label: label.name }, style: "color: #{text_color_for_bg(label.color)}" }
- = link_to label.name, label_filter_path(@project, label, type: controller.controller_name),
- class: "btn btn-transparent has-tooltip",
- style: "background-color: #{label.color};",
- title: escape_once(label.description),
- data: { container: "body" }
+ = link_to_label(label, css_class: 'btn btn-transparent')
%button.btn.btn-transparent.label-remove.js-label-filter-remove{ type: "button", style: "background-color: #{label.color};", data: { label: label.title } }
= icon("times")
diff --git a/app/views/shared/projects/_project.html.haml b/app/views/shared/projects/_project.html.haml
index b8b66d08db8..92803838d02 100644
--- a/app/views/shared/projects/_project.html.haml
+++ b/app/views/shared/projects/_project.html.haml
@@ -24,7 +24,7 @@
= icon('star')
= project.star_count
%span.visibility-icon.has-tooltip{data: { container: 'body', placement: 'left' }, title: visibility_icon_description(project)}
- = visibility_level_icon(project.visibility_level, fw: false)
+ = visibility_level_icon(project.visibility_level, fw: true)
.title
= link_to project_path(project), class: dom_class(project) do
diff --git a/app/views/shared/web_hooks/_form.html.haml b/app/views/shared/web_hooks/_form.html.haml
index 2585ed9360b..470dac6d75b 100644
--- a/app/views/shared/web_hooks/_form.html.haml
+++ b/app/views/shared/web_hooks/_form.html.haml
@@ -19,7 +19,7 @@
= f.label :token, "Secret Token", class: 'label-light'
= f.text_field :token, class: "form-control", placeholder: ''
%p.help-block
- Use this token to validate received payloads
+ Use this token to validate received payloads. It will be sent with the request in the X-Gitlab-Token HTTP header.
.form-group
= f.label :url, "Trigger", class: 'label-light'
%ul.list-unstyled
diff --git a/app/workers/emails_on_push_worker.rb b/app/workers/emails_on_push_worker.rb
index 0b6a01a3200..c6a5af2809a 100644
--- a/app/workers/emails_on_push_worker.rb
+++ b/app/workers/emails_on_push_worker.rb
@@ -33,25 +33,14 @@ class EmailsOnPushWorker
reverse_compare = false
if action == :push
- merge_base_sha = project.merge_base_commit(before_sha, after_sha).try(:sha)
- compare = Gitlab::Git::Compare.new(project.repository.raw_repository, before_sha, after_sha)
-
- diff_refs = Gitlab::Diff::DiffRefs.new(
- base_sha: merge_base_sha,
- start_sha: before_sha,
- head_sha: after_sha
- )
+ compare = CompareService.new.execute(project, before_sha, project, after_sha)
+ diff_refs = compare.diff_refs
return false if compare.same
if compare.commits.empty?
- compare = Gitlab::Git::Compare.new(project.repository.raw_repository, after_sha, before_sha)
-
- diff_refs = Gitlab::Diff::DiffRefs.new(
- base_sha: merge_base_sha,
- start_sha: after_sha,
- head_sha: before_sha
- )
+ compare = CompareService.new.execute(project, after_sha, project, before_sha)
+ diff_refs = compare.diff_refs
reverse_compare = true
diff --git a/app/workers/gitlab_remove_project_export_worker.rb b/app/workers/import_export_project_cleanup_worker.rb
index 1d91897d520..72e3a9ae734 100644
--- a/app/workers/gitlab_remove_project_export_worker.rb
+++ b/app/workers/import_export_project_cleanup_worker.rb
@@ -1,9 +1,9 @@
-class GitlabRemoveProjectExportWorker
+class ImportExportProjectCleanupWorker
include Sidekiq::Worker
sidekiq_options queue: :default
def perform
- Project.remove_gitlab_exports!
+ ImportExportCleanUpService.new.execute
end
end
diff --git a/app/workers/irker_worker.rb b/app/workers/irker_worker.rb
index 605ec4f04e5..19f38358eb5 100644
--- a/app/workers/irker_worker.rb
+++ b/app/workers/irker_worker.rb
@@ -141,8 +141,10 @@ class IrkerWorker
end
def files_count(commit)
- files = "#{commit.diffs.real_size} file"
- files += 's' if commit.diffs.count > 1
+ diffs = commit.raw_diffs(deltas_only: true)
+
+ files = "#{diffs.real_size} file"
+ files += 's' if diffs.size > 1
files
end
diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb
index 09035a7cf2d..a9a2b716005 100644
--- a/app/workers/post_receive.rb
+++ b/app/workers/post_receive.rb
@@ -10,6 +10,10 @@ class PostReceive
log("Check gitlab.yml config for correct repositories.storages values. No repository storage path matches \"#{repo_path}\"")
end
+ changes = Base64.decode64(changes) unless changes.include?(' ')
+ # Use Sidekiq.logger so arguments can be correlated with execution
+ # time and thread ID's.
+ Sidekiq.logger.info "changes: #{changes.inspect}" if ENV['SIDEKIQ_LOG_ARGUMENTS']
post_received = Gitlab::GitPostReceive.new(repo_path, identifier, changes)
if post_received.project.nil?
diff --git a/app/workers/project_destroy_worker.rb b/app/workers/project_destroy_worker.rb
index b51c6a266c9..3062301a9b1 100644
--- a/app/workers/project_destroy_worker.rb
+++ b/app/workers/project_destroy_worker.rb
@@ -12,6 +12,6 @@ class ProjectDestroyWorker
user = User.find(user_id)
- ::Projects::DestroyService.new(project, user, params).execute
+ ::Projects::DestroyService.new(project, user, params.symbolize_keys).execute
end
end