summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/assets/images/auth_buttons/azure_64.pngbin986 -> 695 bytes
-rw-r--r--app/assets/images/auth_buttons/bitbucket_64.pngbin2163 -> 2161 bytes
-rw-r--r--app/assets/images/auth_buttons/facebook_64.pngbin2970 -> 870 bytes
-rw-r--r--app/assets/images/auth_buttons/github_64.pngbin2625 -> 1151 bytes
-rw-r--r--app/assets/images/auth_buttons/gitlab_64.pngbin2849 -> 2070 bytes
-rw-r--r--app/assets/images/auth_buttons/google_64.pngbin5281 -> 4366 bytes
-rw-r--r--app/assets/images/auth_buttons/twitter_64.pngbin4835 -> 3110 bytes
-rw-r--r--app/assets/images/bg_fallback.pngbin167 -> 167 bytes
-rw-r--r--app/assets/images/dark-scheme-preview.pngbin3996 -> 3992 bytes
-rw-r--r--app/assets/images/emoji.pngbin263533 -> 263346 bytes
-rw-r--r--app/assets/images/emoji@2x.pngbin690504 -> 689076 bytes
-rw-r--r--app/assets/images/gitlab_logo.pngbin5189 -> 3616 bytes
-rw-r--r--app/assets/images/gitorious-logo-black.pngbin809 -> 631 bytes
-rw-r--r--app/assets/images/gitorious-logo-blue.pngbin495 -> 201 bytes
-rw-r--r--app/assets/images/icon-link.pngbin1128 -> 729 bytes
-rw-r--r--app/assets/images/images.pngbin5849 -> 5806 bytes
-rw-r--r--app/assets/images/monokai-scheme-preview.pngbin3711 -> 3708 bytes
-rw-r--r--app/assets/images/msapplication-tile.pngbin5798 -> 4328 bytes
-rw-r--r--app/assets/images/no_avatar.pngbin621 -> 621 bytes
-rw-r--r--app/assets/images/no_group_avatar.pngbin942 -> 939 bytes
-rw-r--r--app/assets/images/slider_handles.pngbin1377 -> 1341 bytes
-rw-r--r--app/assets/images/touch-icon-ipad-retina.pngbin8130 -> 5662 bytes
-rw-r--r--app/assets/images/touch-icon-ipad.pngbin3493 -> 2465 bytes
-rw-r--r--app/assets/images/touch-icon-iphone-retina.pngbin4997 -> 3460 bytes
-rw-r--r--app/assets/images/touch-icon-iphone.pngbin2766 -> 1949 bytes
-rw-r--r--app/assets/javascripts/application.js.coffee16
-rw-r--r--app/assets/javascripts/dispatcher.js.coffee2
-rw-r--r--app/assets/javascripts/flash.js.coffee12
-rw-r--r--app/assets/javascripts/gl_dropdown.js.coffee9
-rw-r--r--app/assets/javascripts/issuable.js.coffee3
-rw-r--r--app/assets/javascripts/lib/utils/text_utility.js.coffee45
-rw-r--r--app/assets/javascripts/search_autocomplete.js.coffee11
-rw-r--r--app/assets/javascripts/shortcuts.js.coffee6
-rw-r--r--app/assets/javascripts/tree.js.coffee12
-rw-r--r--app/assets/stylesheets/framework/blocks.scss2
-rw-r--r--app/assets/stylesheets/framework/flash.scss7
-rw-r--r--app/assets/stylesheets/framework/markdown_area.scss3
-rw-r--r--app/assets/stylesheets/framework/nav.scss5
-rw-r--r--app/assets/stylesheets/framework/sidebar.scss1
-rw-r--r--app/assets/stylesheets/framework/variables.scss2
-rw-r--r--app/assets/stylesheets/pages/commits.scss10
-rw-r--r--app/assets/stylesheets/pages/groups.scss6
-rw-r--r--app/assets/stylesheets/pages/merge_requests.scss9
-rw-r--r--app/assets/stylesheets/pages/notes.scss4
-rw-r--r--app/assets/stylesheets/pages/projects.scss73
-rw-r--r--app/assets/stylesheets/pages/tree.scss3
-rw-r--r--app/controllers/admin/application_settings_controller.rb1
-rw-r--r--app/controllers/admin/system_info_controller.rb59
-rw-r--r--app/controllers/ci/projects_controller.rb2
-rw-r--r--app/controllers/groups_controller.rb23
-rw-r--r--app/controllers/import/github_controller.rb25
-rw-r--r--app/controllers/notification_settings_controller.rb22
-rw-r--r--app/controllers/projects/merge_requests_controller.rb8
-rw-r--r--app/finders/pipelines_finder.rb4
-rw-r--r--app/helpers/application_settings_helper.rb8
-rw-r--r--app/helpers/blob_helper.rb8
-rw-r--r--app/helpers/dropdowns_helper.rb2
-rw-r--r--app/helpers/labels_helper.rb12
-rw-r--r--app/helpers/notes_helper.rb10
-rw-r--r--app/helpers/notifications_helper.rb2
-rw-r--r--app/helpers/page_layout_helper.rb2
-rw-r--r--app/helpers/projects_helper.rb8
-rw-r--r--app/models/application_setting.rb5
-rw-r--r--app/models/ci/build.rb2
-rw-r--r--app/models/ci/variable.rb1
-rw-r--r--app/models/event.rb2
-rw-r--r--app/models/member.rb1
-rw-r--r--app/models/merge_request.rb7
-rw-r--r--app/models/merge_request_diff.rb47
-rw-r--r--app/models/namespace.rb95
-rw-r--r--app/models/network/graph.rb4
-rw-r--r--app/models/project.rb22
-rw-r--r--app/models/project_import_data.rb1
-rw-r--r--app/models/project_services/bugzilla_service.rb25
-rw-r--r--app/models/project_services/custom_issue_tracker_service.rb3
-rw-r--r--app/models/project_services/hipchat_service.rb2
-rw-r--r--app/models/project_services/jira_service.rb2
-rw-r--r--app/models/project_team.rb14
-rw-r--r--app/models/project_wiki.rb4
-rw-r--r--app/models/repository.rb22
-rw-r--r--app/models/service.rb1
-rw-r--r--app/models/snippet.rb6
-rw-r--r--app/models/user.rb3
-rw-r--r--app/services/projects/destroy_service.rb6
-rw-r--r--app/services/projects/housekeeping_service.rb2
-rw-r--r--app/services/projects/import_service.rb2
-rw-r--r--app/services/projects/transfer_service.rb4
-rw-r--r--app/uploaders/lfs_object_uploader.rb2
-rw-r--r--app/views/admin/application_settings/_form.html.haml11
-rw-r--r--app/views/admin/background_jobs/_head.html.haml4
-rw-r--r--app/views/admin/background_jobs/show.html.haml2
-rw-r--r--app/views/admin/builds/index.html.haml2
-rw-r--r--app/views/admin/dashboard/index.html.haml2
-rw-r--r--app/views/admin/groups/index.html.haml5
-rw-r--r--app/views/admin/health_check/show.html.haml2
-rw-r--r--app/views/admin/logs/show.html.haml2
-rw-r--r--app/views/admin/projects/index.html.haml2
-rw-r--r--app/views/admin/runners/index.html.haml2
-rw-r--r--app/views/admin/system_info/show.html.haml25
-rw-r--r--app/views/admin/users/index.html.haml2
-rw-r--r--app/views/events/event/_push.html.haml25
-rw-r--r--app/views/groups/show.html.haml11
-rw-r--r--app/views/help/index.html.haml2
-rw-r--r--app/views/import/github/new.html.haml43
-rw-r--r--app/views/layouts/header/_default.html.haml2
-rw-r--r--app/views/layouts/nav/_admin.html.haml8
-rw-r--r--app/views/layouts/nav/_group.html.haml4
-rw-r--r--app/views/layouts/nav/_profile.html.haml4
-rw-r--r--app/views/layouts/nav/_project.html.haml4
-rw-r--r--app/views/projects/_github_import_modal.html.haml13
-rw-r--r--app/views/projects/_home_panel.html.haml2
-rw-r--r--app/views/projects/_last_push.html.haml2
-rw-r--r--app/views/projects/_md_preview.html.haml4
-rw-r--r--app/views/projects/blob/_text.html.haml2
-rw-r--r--app/views/projects/blob/show.html.haml17
-rw-r--r--app/views/projects/branches/index.html.haml4
-rw-r--r--app/views/projects/builds/index.html.haml2
-rw-r--r--app/views/projects/builds/show.html.haml2
-rw-r--r--app/views/projects/commits/_head.html.haml4
-rw-r--r--app/views/projects/commits/show.html.haml2
-rw-r--r--app/views/projects/compare/index.html.haml2
-rw-r--r--app/views/projects/compare/show.html.haml2
-rw-r--r--app/views/projects/environments/index.html.haml2
-rw-r--r--app/views/projects/environments/show.html.haml2
-rw-r--r--app/views/projects/graphs/ci.html.haml2
-rw-r--r--app/views/projects/graphs/commits.html.haml2
-rw-r--r--app/views/projects/graphs/languages.html.haml2
-rw-r--r--app/views/projects/graphs/show.html.haml2
-rw-r--r--app/views/projects/imports/new.html.haml2
-rw-r--r--app/views/projects/issues/index.html.haml2
-rw-r--r--app/views/projects/labels/index.html.haml2
-rw-r--r--app/views/projects/merge_requests/index.html.haml2
-rw-r--r--app/views/projects/milestones/index.html.haml2
-rw-r--r--app/views/projects/network/_head.html.haml2
-rw-r--r--app/views/projects/network/show.html.haml2
-rw-r--r--app/views/projects/new.html.haml201
-rw-r--r--app/views/projects/notes/_note.html.haml2
-rw-r--r--app/views/projects/pipelines/index.html.haml2
-rw-r--r--app/views/projects/show.html.haml2
-rw-r--r--app/views/projects/tags/index.html.haml4
-rw-r--r--app/views/projects/tree/show.html.haml2
-rw-r--r--app/views/projects/wikis/_new.html.haml2
-rw-r--r--app/views/projects/wikis/edit.html.haml2
-rw-r--r--app/views/projects/wikis/git_access.html.haml2
-rw-r--r--app/views/projects/wikis/history.html.haml2
-rw-r--r--app/views/projects/wikis/pages.html.haml2
-rw-r--r--app/views/projects/wikis/show.html.haml2
-rw-r--r--app/views/shared/_file_highlight.html.haml4
-rw-r--r--app/views/shared/_labels_row.html.haml2
-rw-r--r--app/views/users/calendar_activities.html.haml2
-rw-r--r--app/workers/post_receive.rb6
-rw-r--r--app/workers/repository_fork_worker.rb2
152 files changed, 816 insertions, 395 deletions
diff --git a/app/assets/images/auth_buttons/azure_64.png b/app/assets/images/auth_buttons/azure_64.png
index a82c751e001..85de7793440 100644
--- a/app/assets/images/auth_buttons/azure_64.png
+++ b/app/assets/images/auth_buttons/azure_64.png
Binary files differ
diff --git a/app/assets/images/auth_buttons/bitbucket_64.png b/app/assets/images/auth_buttons/bitbucket_64.png
index 4b90a57bc7d..b3d022a5a70 100644
--- a/app/assets/images/auth_buttons/bitbucket_64.png
+++ b/app/assets/images/auth_buttons/bitbucket_64.png
Binary files differ
diff --git a/app/assets/images/auth_buttons/facebook_64.png b/app/assets/images/auth_buttons/facebook_64.png
index 1f1a80d7368..71ffb1c6a1f 100644
--- a/app/assets/images/auth_buttons/facebook_64.png
+++ b/app/assets/images/auth_buttons/facebook_64.png
Binary files differ
diff --git a/app/assets/images/auth_buttons/github_64.png b/app/assets/images/auth_buttons/github_64.png
index 182a1a3f734..1fa19c55d2f 100644
--- a/app/assets/images/auth_buttons/github_64.png
+++ b/app/assets/images/auth_buttons/github_64.png
Binary files differ
diff --git a/app/assets/images/auth_buttons/gitlab_64.png b/app/assets/images/auth_buttons/gitlab_64.png
index 99a40583b3a..f675678dc9d 100644
--- a/app/assets/images/auth_buttons/gitlab_64.png
+++ b/app/assets/images/auth_buttons/gitlab_64.png
Binary files differ
diff --git a/app/assets/images/auth_buttons/google_64.png b/app/assets/images/auth_buttons/google_64.png
index fb64f8bee68..720824230a5 100644
--- a/app/assets/images/auth_buttons/google_64.png
+++ b/app/assets/images/auth_buttons/google_64.png
Binary files differ
diff --git a/app/assets/images/auth_buttons/twitter_64.png b/app/assets/images/auth_buttons/twitter_64.png
index e3bd9169a34..a4f14de57ae 100644
--- a/app/assets/images/auth_buttons/twitter_64.png
+++ b/app/assets/images/auth_buttons/twitter_64.png
Binary files differ
diff --git a/app/assets/images/bg_fallback.png b/app/assets/images/bg_fallback.png
index e5fe659ba63..5c55bc79dec 100644
--- a/app/assets/images/bg_fallback.png
+++ b/app/assets/images/bg_fallback.png
Binary files differ
diff --git a/app/assets/images/dark-scheme-preview.png b/app/assets/images/dark-scheme-preview.png
index 2ef58e52549..8855babf147 100644
--- a/app/assets/images/dark-scheme-preview.png
+++ b/app/assets/images/dark-scheme-preview.png
Binary files differ
diff --git a/app/assets/images/emoji.png b/app/assets/images/emoji.png
index 1e7cf79ea45..99093d4725a 100644
--- a/app/assets/images/emoji.png
+++ b/app/assets/images/emoji.png
Binary files differ
diff --git a/app/assets/images/emoji@2x.png b/app/assets/images/emoji@2x.png
index 74d67f7520d..48989942a9f 100644
--- a/app/assets/images/emoji@2x.png
+++ b/app/assets/images/emoji@2x.png
Binary files differ
diff --git a/app/assets/images/gitlab_logo.png b/app/assets/images/gitlab_logo.png
index 0c157546b9c..ca30b459019 100644
--- a/app/assets/images/gitlab_logo.png
+++ b/app/assets/images/gitlab_logo.png
Binary files differ
diff --git a/app/assets/images/gitorious-logo-black.png b/app/assets/images/gitorious-logo-black.png
index 78f17a9af79..4a55fdc225a 100644
--- a/app/assets/images/gitorious-logo-black.png
+++ b/app/assets/images/gitorious-logo-black.png
Binary files differ
diff --git a/app/assets/images/gitorious-logo-blue.png b/app/assets/images/gitorious-logo-blue.png
index 4962cffba31..5eaa327d3df 100644
--- a/app/assets/images/gitorious-logo-blue.png
+++ b/app/assets/images/gitorious-logo-blue.png
Binary files differ
diff --git a/app/assets/images/icon-link.png b/app/assets/images/icon-link.png
index 7d89da97e11..5b55e12571c 100644
--- a/app/assets/images/icon-link.png
+++ b/app/assets/images/icon-link.png
Binary files differ
diff --git a/app/assets/images/images.png b/app/assets/images/images.png
index ad146246caf..bd60de994c4 100644
--- a/app/assets/images/images.png
+++ b/app/assets/images/images.png
Binary files differ
diff --git a/app/assets/images/monokai-scheme-preview.png b/app/assets/images/monokai-scheme-preview.png
index fbb339c6a91..d9c7d2d8041 100644
--- a/app/assets/images/monokai-scheme-preview.png
+++ b/app/assets/images/monokai-scheme-preview.png
Binary files differ
diff --git a/app/assets/images/msapplication-tile.png b/app/assets/images/msapplication-tile.png
index 58bbf2b20cb..1e0e2ed73ce 100644
--- a/app/assets/images/msapplication-tile.png
+++ b/app/assets/images/msapplication-tile.png
Binary files differ
diff --git a/app/assets/images/no_avatar.png b/app/assets/images/no_avatar.png
index 8287acbce13..5383d687b53 100644
--- a/app/assets/images/no_avatar.png
+++ b/app/assets/images/no_avatar.png
Binary files differ
diff --git a/app/assets/images/no_group_avatar.png b/app/assets/images/no_group_avatar.png
index bfb31bb2184..71612d55286 100644
--- a/app/assets/images/no_group_avatar.png
+++ b/app/assets/images/no_group_avatar.png
Binary files differ
diff --git a/app/assets/images/slider_handles.png b/app/assets/images/slider_handles.png
index 884378ec96a..52ad11ab7a1 100644
--- a/app/assets/images/slider_handles.png
+++ b/app/assets/images/slider_handles.png
Binary files differ
diff --git a/app/assets/images/touch-icon-ipad-retina.png b/app/assets/images/touch-icon-ipad-retina.png
index feb32b48ec9..516dc2f4710 100644
--- a/app/assets/images/touch-icon-ipad-retina.png
+++ b/app/assets/images/touch-icon-ipad-retina.png
Binary files differ
diff --git a/app/assets/images/touch-icon-ipad.png b/app/assets/images/touch-icon-ipad.png
index a6ddc543509..b2093d015b8 100644
--- a/app/assets/images/touch-icon-ipad.png
+++ b/app/assets/images/touch-icon-ipad.png
Binary files differ
diff --git a/app/assets/images/touch-icon-iphone-retina.png b/app/assets/images/touch-icon-iphone-retina.png
index 8bf7ccb7534..438654e0d20 100644
--- a/app/assets/images/touch-icon-iphone-retina.png
+++ b/app/assets/images/touch-icon-iphone-retina.png
Binary files differ
diff --git a/app/assets/images/touch-icon-iphone.png b/app/assets/images/touch-icon-iphone.png
index 87da550f8be..e5f87fbbcf6 100644
--- a/app/assets/images/touch-icon-iphone.png
+++ b/app/assets/images/touch-icon-iphone.png
Binary files differ
diff --git a/app/assets/javascripts/application.js.coffee b/app/assets/javascripts/application.js.coffee
index 5c5a4ca7670..20fe5a5cc27 100644
--- a/app/assets/javascripts/application.js.coffee
+++ b/app/assets/javascripts/application.js.coffee
@@ -185,6 +185,15 @@ $ ->
else
buttons.enable()
+ $(document).ajaxError (e, xhrObj, xhrSetting, xhrErrorText) ->
+
+ if xhrObj.status is 401
+ new Flash 'You need to be logged in.', 'alert'
+
+ else if xhrObj.status in [ 404, 500 ]
+ new Flash 'Something went wrong on our end.', 'alert'
+
+
# Show/Hide the profile menu when hovering the account box
$('.account-box').hover -> $(@).toggleClass('hover')
@@ -199,7 +208,6 @@ $ ->
$('.header-content .header-logo').toggle()
$('.header-content .navbar-collapse').toggle()
$('.navbar-toggle').toggleClass('active')
- $('.navbar-toggle i').toggleClass("fa-angle-right fa-angle-left")
# Show/hide comments on diff
$body.on "click", ".js-toggle-diff-comments", (e) ->
@@ -261,8 +269,8 @@ $ ->
new Aside()
# Sidenav pinning
- if $window.width() < 1440 and $.cookie('pin_nav') is 'true'
- $.cookie('pin_nav', 'false', { path: '/' })
+ if $window.width() < 1024 and $.cookie('pin_nav') is 'true'
+ $.cookie('pin_nav', 'false', { path: '/', expires: 365 * 10 })
$('.page-with-sidebar')
.toggleClass('page-sidebar-collapsed page-sidebar-expanded')
.removeClass('page-sidebar-pinned')
@@ -293,7 +301,7 @@ $ ->
.toggleClass('header-collapsed header-expanded')
# Save settings
- $.cookie 'pin_nav', doPinNav, { path: '/' }
+ $.cookie 'pin_nav', doPinNav, { path: '/', expires: 365 * 10 }
if $.cookie('pin_nav') is 'true' or doPinNav
tooltipText = 'Unpin navigation'
diff --git a/app/assets/javascripts/dispatcher.js.coffee b/app/assets/javascripts/dispatcher.js.coffee
index 7fbff9214cf..9493a575801 100644
--- a/app/assets/javascripts/dispatcher.js.coffee
+++ b/app/assets/javascripts/dispatcher.js.coffee
@@ -84,6 +84,8 @@ class Dispatcher
new Activities()
when 'groups:show'
shortcut_handler = new ShortcutsNavigation()
+ new NotificationsForm()
+ new NotificationsDropdown()
when 'groups:group_members:index'
new GroupMembers()
new UsersSelect()
diff --git a/app/assets/javascripts/flash.js.coffee b/app/assets/javascripts/flash.js.coffee
index 4f73d215b85..b76d214790a 100644
--- a/app/assets/javascripts/flash.js.coffee
+++ b/app/assets/javascripts/flash.js.coffee
@@ -4,11 +4,19 @@ class @Flash
@flash.html("")
innerDiv = $('<div/>',
- class: "flash-#{type}",
- text: message
+ class: "flash-#{type}"
)
innerDiv.appendTo(".flash-container")
+ textDiv = $("<div/>",
+ class: "flash-text",
+ text: message
+ )
+ textDiv.appendTo(innerDiv)
+
+ if @flash.parent().hasClass('content-wrapper')
+ textDiv.addClass('container-fluid container-limited')
+
@flash.click -> $(@).fadeOut()
@flash.show()
diff --git a/app/assets/javascripts/gl_dropdown.js.coffee b/app/assets/javascripts/gl_dropdown.js.coffee
index 703128fecb3..ed9dfcc917e 100644
--- a/app/assets/javascripts/gl_dropdown.js.coffee
+++ b/app/assets/javascripts/gl_dropdown.js.coffee
@@ -186,6 +186,8 @@ class GitLabDropdown
@fullData = data
@parseData @fullData
+
+ @filter.input.trigger('keyup') if @options.filterable and @filter and @filter.input
}
# Init filterable
@@ -218,6 +220,13 @@ class GitLabDropdown
@dropdown.on 'keyup', (e) =>
if e.which is 27 # Escape key
$('.dropdown-menu-close', @dropdown).trigger 'click'
+ @dropdown.on 'blur', 'a', (e) =>
+ if e.relatedTarget?
+ $relatedTarget = $(e.relatedTarget)
+ $dropdownMenu = $relatedTarget.closest('.dropdown-menu')
+
+ if $dropdownMenu.length is 0
+ @dropdown.removeClass('open')
if @dropdown.find(".dropdown-toggle-page").length
@dropdown.find(".dropdown-toggle-page, .dropdown-menu-back").on "click", (e) =>
diff --git a/app/assets/javascripts/issuable.js.coffee b/app/assets/javascripts/issuable.js.coffee
index 6a108c033ea..0527c66461c 100644
--- a/app/assets/javascripts/issuable.js.coffee
+++ b/app/assets/javascripts/issuable.js.coffee
@@ -59,13 +59,12 @@ issuable_created = false
filterResults: (form) =>
formData = form.serialize()
- $('.issues-holder, .merge-requests-holder').css('opacity', '0.5')
formAction = form.attr('action')
issuesUrl = formAction
issuesUrl += ("#{if formAction.indexOf('?') < 0 then '?' else '&'}")
issuesUrl += formData
- Turbolinks.visit(issuesUrl);
+ Turbolinks.visit(issuesUrl)
initChecks: ->
@issuableBulkActions = $('.bulk-update').data('bulkActions')
diff --git a/app/assets/javascripts/lib/utils/text_utility.js.coffee b/app/assets/javascripts/lib/utils/text_utility.js.coffee
index bb2772dfed2..7bcb876d056 100644
--- a/app/assets/javascripts/lib/utils/text_utility.js.coffee
+++ b/app/assets/javascripts/lib/utils/text_utility.js.coffee
@@ -10,17 +10,41 @@
gl.text.selectedText = (text, textarea) ->
text.substring(textarea.selectionStart, textarea.selectionEnd)
- gl.text.insertText = (textArea, text, tag, selected, wrap) ->
+ gl.text.lineBefore = (text, textarea) ->
+ split = text.substring(0, textarea.selectionStart).trim().split('\n')
+ split[split.length - 1]
+
+ gl.text.lineAfter = (text, textarea) ->
+ text.substring(textarea.selectionEnd).trim().split('\n')[0]
+
+ gl.text.blockTagText = (text, textArea, blockTag, selected) ->
+ lineBefore = @lineBefore(text, textArea)
+ lineAfter = @lineAfter(text, textArea)
+
+ if lineBefore is blockTag and lineAfter is blockTag
+ # To remove the block tag we have to select the line before & after
+ if blockTag?
+ textArea.selectionStart = textArea.selectionStart - (blockTag.length + 1)
+ textArea.selectionEnd = textArea.selectionEnd + (blockTag.length + 1)
+
+ selected
+ else
+ "#{blockTag}\n#{selected}\n#{blockTag}"
+
+ gl.text.insertText = (textArea, text, tag, blockTag, selected, wrap) ->
selectedSplit = selected.split('\n')
startChar = if not wrap and textArea.selectionStart > 0 then '\n' else ''
- if selectedSplit.length > 1 and not wrap
- insertText = selectedSplit.map((val) ->
- if val.indexOf(tag) is 0
- "#{val.replace(tag, '')}"
- else
- "#{tag}#{val}"
- ).join('\n')
+ if selectedSplit.length > 1 and (not wrap or blockTag?)
+ if blockTag?
+ insertText = @blockTagText(text, textArea, blockTag, selected)
+ else
+ insertText = selectedSplit.map((val) ->
+ if val.indexOf(tag) is 0
+ "#{val.replace(tag, '')}"
+ else
+ "#{tag}#{val}"
+ ).join('\n')
else
insertText = "#{startChar}#{tag}#{selected}#{if wrap then tag else ' '}"
@@ -51,7 +75,7 @@
textArea.setSelectionRange pos, pos
- gl.text.updateText = (textArea, tag, wrap) ->
+ gl.text.updateText = (textArea, tag, blockTag, wrap) ->
$textArea = $(textArea)
oldVal = $textArea.val()
textArea = $textArea.get(0)
@@ -59,7 +83,7 @@
selected = @selectedText(text, textArea)
$textArea.focus()
- @insertText(textArea, text, tag, selected, wrap)
+ @insertText(textArea, text, tag, blockTag, selected, wrap)
gl.text.init = (form) ->
self = @
@@ -70,6 +94,7 @@
self.updateText(
$this.closest('.md-area').find('textarea'),
$this.data('md-tag'),
+ $this.data('md-block'),
not $this.data('md-prepend')
)
diff --git a/app/assets/javascripts/search_autocomplete.js.coffee b/app/assets/javascripts/search_autocomplete.js.coffee
index 421328554b8..72b1d3dfb1e 100644
--- a/app/assets/javascripts/search_autocomplete.js.coffee
+++ b/app/assets/javascripts/search_autocomplete.js.coffee
@@ -171,22 +171,15 @@ class @SearchAutocomplete
}
bindEvents: ->
- $(document).on 'click', @onDocumentClick
@searchInput.on 'keydown', @onSearchInputKeyDown
@searchInput.on 'keyup', @onSearchInputKeyUp
@searchInput.on 'click', @onSearchInputClick
@searchInput.on 'focus', @onSearchInputFocus
+ @searchInput.on 'blur', @onSearchInputBlur
@clearInput.on 'click', @onClearInputClick
@locationBadgeEl.on 'click', =>
@searchInput.focus()
- onDocumentClick: (e) =>
- # If clicking outside the search box
- # And search input is not focused
- # And we are not clicking inside a suggestion
- if not $.contains(@dropdown[0], e.target) and @isFocused and not $(e.target).closest('.search-form').length
- @onSearchInputBlur()
-
enableAutocomplete: ->
# No need to enable anything if user is not logged in
return if !gon.current_user_id
@@ -287,8 +280,6 @@ class @SearchAutocomplete
value: @originalState._location
)
- @dropdown.removeClass 'open'
-
badgePresent: ->
@locationBadgeEl.length
diff --git a/app/assets/javascripts/shortcuts.js.coffee b/app/assets/javascripts/shortcuts.js.coffee
index c03877e9b06..3319a67a79d 100644
--- a/app/assets/javascripts/shortcuts.js.coffee
+++ b/app/assets/javascripts/shortcuts.js.coffee
@@ -9,12 +9,12 @@ class @Shortcuts
onToggleHelp: (e) =>
e.preventDefault()
- @toggleHelp(@enabledHelp)
+ Shortcuts.toggleHelp(@enabledHelp)
- toggleMarkdownPreview: (e) =>
+ toggleMarkdownPreview: (e) ->
$(document).triggerHandler('markdown-preview:toggle', [e])
- toggleHelp: (location) ->
+ @toggleHelp: (location) ->
$modal = $('#modal-shortcuts')
if $modal.length
diff --git a/app/assets/javascripts/tree.js.coffee b/app/assets/javascripts/tree.js.coffee
index de8eebcd0b2..83de584f2d9 100644
--- a/app/assets/javascripts/tree.js.coffee
+++ b/app/assets/javascripts/tree.js.coffee
@@ -5,9 +5,15 @@ class @TreeView
# Code browser tree slider
# Make the entire tree-item row clickable, but not if clicking another link (like a commit message)
$(".tree-content-holder .tree-item").on 'click', (e) ->
- if (e.target.nodeName != "A")
- path = $('.tree-item-file-name a', this).attr('href')
- Turbolinks.visit(path)
+ $clickedEl = $(e.target)
+ path = $('.tree-item-file-name a', this).attr('href')
+
+ if not $clickedEl.is('a') and not $clickedEl.is('.str-truncated')
+ if e.metaKey or e.which is 2
+ e.preventDefault()
+ window.open path, '_blank'
+ else
+ Turbolinks.visit path
# Show the "Loading commit data" for only the first element
$('span.log_loading:first').removeClass('hide')
diff --git a/app/assets/stylesheets/framework/blocks.scss b/app/assets/stylesheets/framework/blocks.scss
index 38023818709..41e77a4ac68 100644
--- a/app/assets/stylesheets/framework/blocks.scss
+++ b/app/assets/stylesheets/framework/blocks.scss
@@ -137,7 +137,7 @@
margin: 0;
font-size: 24px;
font-weight: normal;
- margin-bottom: 5px;
+ margin-bottom: 10px;
color: #4c4e54;
font-size: 23px;
line-height: 1.1;
diff --git a/app/assets/stylesheets/framework/flash.scss b/app/assets/stylesheets/framework/flash.scss
index 1bfd0213995..a951a2b97fe 100644
--- a/app/assets/stylesheets/framework/flash.scss
+++ b/app/assets/stylesheets/framework/flash.scss
@@ -16,4 +16,11 @@
@extend .alert-danger;
margin: 0;
}
+
+ .flash-notice, .flash-alert {
+ .container-fluid.flash-text {
+ background: transparent;
+ }
+ }
}
+
diff --git a/app/assets/stylesheets/framework/markdown_area.scss b/app/assets/stylesheets/framework/markdown_area.scss
index fd8eaa8a691..5d3273ea64d 100644
--- a/app/assets/stylesheets/framework/markdown_area.scss
+++ b/app/assets/stylesheets/framework/markdown_area.scss
@@ -125,7 +125,8 @@
border: 0;
outline: 0;
- &:hover {
+ &:hover,
+ &:focus {
color: $gl-link-color;
}
}
diff --git a/app/assets/stylesheets/framework/nav.scss b/app/assets/stylesheets/framework/nav.scss
index 6211bc04597..6e5f216c894 100644
--- a/app/assets/stylesheets/framework/nav.scss
+++ b/app/assets/stylesheets/framework/nav.scss
@@ -21,9 +21,8 @@
.fa {
position: relative;
- top: 3px;
- font-size: 13px;
- color: $btn-placeholder-gray;
+ top: 5px;
+ font-size: 18px;
}
}
diff --git a/app/assets/stylesheets/framework/sidebar.scss b/app/assets/stylesheets/framework/sidebar.scss
index 98f917ce69b..e8d6a7f2775 100644
--- a/app/assets/stylesheets/framework/sidebar.scss
+++ b/app/assets/stylesheets/framework/sidebar.scss
@@ -1,5 +1,6 @@
.page-with-sidebar {
padding-top: $header-height;
+ padding-bottom: 25px;
transition: padding $sidebar-transition-duration;
.sidebar-wrapper {
diff --git a/app/assets/stylesheets/framework/variables.scss b/app/assets/stylesheets/framework/variables.scss
index c37574ca7a1..211a9af2348 100644
--- a/app/assets/stylesheets/framework/variables.scss
+++ b/app/assets/stylesheets/framework/variables.scss
@@ -7,7 +7,7 @@ $gutter_collapsed_width: 62px;
$gutter_width: 290px;
$gutter_inner_width: 258px;
$sidebar-transition-duration: .15s;
-$sidebar-breakpoint: 1440px;
+$sidebar-breakpoint: 1024px;
/*
* UI elements
diff --git a/app/assets/stylesheets/pages/commits.scss b/app/assets/stylesheets/pages/commits.scss
index de534d28421..85bbf70e188 100644
--- a/app/assets/stylesheets/pages/commits.scss
+++ b/app/assets/stylesheets/pages/commits.scss
@@ -83,11 +83,7 @@
position: relative;
@media (min-width: $screen-sm-min) {
- padding-left: 20px;
-
- .commit-info-block {
- padding-left: 44px;
- }
+ padding-left: 46px;
}
&:not(:last-child) {
@@ -102,9 +98,7 @@
.avatar {
- position: absolute;
- top: 10px;
- left: 16px;
+ margin-left: -46px;
}
.item-title {
diff --git a/app/assets/stylesheets/pages/groups.scss b/app/assets/stylesheets/pages/groups.scss
index ac7721cbe15..101faf59174 100644
--- a/app/assets/stylesheets/pages/groups.scss
+++ b/app/assets/stylesheets/pages/groups.scss
@@ -48,11 +48,7 @@
.access-request-button {
@include btn-gray;
- position: absolute;
- right: 16px;
- bottom: 32px;
- padding: 3px 10px;
+ margin-right: 10px;
text-transform: none;
- background-color: $background-color;
}
}
diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss
index aca82f7f7bf..124f4afaa0d 100644
--- a/app/assets/stylesheets/pages/merge_requests.scss
+++ b/app/assets/stylesheets/pages/merge_requests.scss
@@ -264,8 +264,15 @@
margin-bottom: 4px;
}
+ .item-title {
+ @media (min-width: $screen-sm-min) {
+ width: 49%;
+ }
+ }
+
.avatar {
- margin-left: 0;
+ left: 0;
+ top: 2px;
}
.commit-row-info {
diff --git a/app/assets/stylesheets/pages/notes.scss b/app/assets/stylesheets/pages/notes.scss
index ee7c98f805b..ac8c02b59dc 100644
--- a/app/assets/stylesheets/pages/notes.scss
+++ b/app/assets/stylesheets/pages/notes.scss
@@ -41,6 +41,10 @@ ul.notes {
.timeline-icon {
.avatar {
visibility: hidden;
+
+ .discussion-body & {
+ visibility: visible;
+ }
}
}
}
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index d3e59d7fdb9..89ce1b2df20 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -13,10 +13,53 @@
.new_project,
.edit-project {
- fieldset.features {
- .control-label {
+ fieldset {
+ &.features .control-label {
font-weight: normal;
}
+ .form-group {
+ margin-bottom: 5px;
+ }
+ &> .form-group {
+ padding-left: 0;
+ }
+ }
+ .help-block {
+ margin-bottom: 10px;
+ }
+ .project-path {
+ padding-right: 0;
+ .form-control {
+ border-radius: $border-radius-base;
+ }
+ }
+ .input-group > div {
+ &:last-child {
+ padding-right: 0;
+ }
+ }
+ @media (max-width: $screen-xs-max) {
+ .input-group > div {
+ margin-bottom: 14px;
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+ fieldset > .form-group:first-child {
+ padding-right: 0;
+ }
+ }
+
+ .input-group-addon {
+ &.static-namespace {
+ height: 35px;
+ border-radius: 3px;
+ border: 1px solid #e5e5e5;
+ }
+ &+ .select2 a {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+ }
}
}
@@ -365,10 +408,28 @@ a.deploy-project-label {
}
}
-.project-import .btn {
- float: left;
- margin-bottom: 10px;
- margin-right: 10px;
+.project-import {
+ .form-group {
+ margin-bottom: 0;
+ }
+ .import-buttons {
+ padding-left: 0;
+ display: -webkit-flex;
+ display: flex;
+ -webkit-flex-wrap: wrap;
+ flex-wrap: wrap;
+ .btn {
+ margin-right: 10px;
+ padding: 8px 12px;
+ }
+ &> div {
+ margin-bottom: 14px;
+ padding-left: 0;
+ &:last-child {
+ margin-bottom: 0;
+ }
+ }
+ }
}
.project-stats {
diff --git a/app/assets/stylesheets/pages/tree.scss b/app/assets/stylesheets/pages/tree.scss
index 99c9e81ddb9..5b61270daa8 100644
--- a/app/assets/stylesheets/pages/tree.scss
+++ b/app/assets/stylesheets/pages/tree.scss
@@ -101,7 +101,8 @@
margin: 0;
.commit {
- padding: 0 0 0 55px;
+ padding-top: 0;
+ padding-bottom: 0;
.commit-row-title {
.commit-row-message {
diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb
index f4eda864aac..5f65dd3aff0 100644
--- a/app/controllers/admin/application_settings_controller.rb
+++ b/app/controllers/admin/application_settings_controller.rb
@@ -109,6 +109,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController
:metrics_packet_size,
:send_user_confirmation_email,
:container_registry_token_expire_delay,
+ :repository_storage,
restricted_visibility_levels: [],
import_sources: [],
disabled_oauth_sign_in_sources: []
diff --git a/app/controllers/admin/system_info_controller.rb b/app/controllers/admin/system_info_controller.rb
new file mode 100644
index 00000000000..e4c73008826
--- /dev/null
+++ b/app/controllers/admin/system_info_controller.rb
@@ -0,0 +1,59 @@
+class Admin::SystemInfoController < Admin::ApplicationController
+ EXCLUDED_MOUNT_OPTIONS = [
+ 'nobrowse',
+ 'read-only',
+ 'ro'
+ ]
+
+ EXCLUDED_MOUNT_TYPES = [
+ 'autofs',
+ 'binfmt_misc',
+ 'cgroup',
+ 'debugfs',
+ 'devfs',
+ 'devpts',
+ 'devtmpfs',
+ 'efivarfs',
+ 'fuse.gvfsd-fuse',
+ 'fuseblk',
+ 'fusectl',
+ 'hugetlbfs',
+ 'mqueue',
+ 'proc',
+ 'pstore',
+ 'securityfs',
+ 'sysfs',
+ 'tmpfs',
+ 'tracefs',
+ 'vfat'
+ ]
+
+ def show
+ system_info = Vmstat.snapshot
+ mounts = Sys::Filesystem.mounts
+
+ @disks = []
+ mounts.each do |mount|
+ mount_options = mount.options.split(',')
+
+ next if (EXCLUDED_MOUNT_OPTIONS & mount_options).any?
+ next if (EXCLUDED_MOUNT_TYPES & [mount.mount_type]).any?
+
+ begin
+ disk = Sys::Filesystem.stat(mount.mount_point)
+ @disks.push({
+ bytes_total: disk.bytes_total,
+ bytes_used: disk.bytes_used,
+ disk_name: mount.name,
+ mount_path: disk.path
+ })
+ rescue Sys::Filesystem::Error
+ end
+ end
+
+ @cpus = system_info.cpus.length
+
+ @mem_used = system_info.memory.active_bytes
+ @mem_total = system_info.memory.total_bytes
+ end
+end
diff --git a/app/controllers/ci/projects_controller.rb b/app/controllers/ci/projects_controller.rb
index 8bf71a1adbb..aa894fde36b 100644
--- a/app/controllers/ci/projects_controller.rb
+++ b/app/controllers/ci/projects_controller.rb
@@ -25,7 +25,7 @@ module Ci
return render_404 unless @project
image = Ci::ImageForBuildService.new.execute(@project, params)
- send_file image.path, filename: image.name, disposition: 'inline', type:"image/svg+xml"
+ send_file image.path, filename: image.name, disposition: 'inline', type: "image/svg+xml"
end
protected
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index ee4fcc4e360..a04bf7df722 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -37,15 +37,12 @@ class GroupsController < Groups::ApplicationController
end
def show
- @last_push = current_user.recent_push if current_user
-
- @projects = @projects.includes(:namespace)
- @projects = @projects.sorted_by_activity
- @projects = filter_projects(@projects)
- @projects = @projects.sort(@sort = params[:sort])
- @projects = @projects.page(params[:page]) if params[:filter_projects].blank?
+ if current_user
+ @last_push = current_user.recent_push
+ @notification_setting = current_user.notification_settings_for(group)
+ end
- @shared_projects = GroupProjectsFinder.new(group, only_shared: true).execute(current_user)
+ setup_projects
respond_to do |format|
format.html
@@ -97,6 +94,16 @@ class GroupsController < Groups::ApplicationController
protected
+ def setup_projects
+ @projects = @projects.includes(:namespace)
+ @projects = @projects.sorted_by_activity
+ @projects = filter_projects(@projects)
+ @projects = @projects.sort(@sort = params[:sort])
+ @projects = @projects.page(params[:page]) if params[:filter_projects].blank?
+
+ @shared_projects = GroupProjectsFinder.new(group, only_shared: true).execute(current_user)
+ end
+
def authorize_create_group!
unless can?(current_user, :create_group, nil)
return render_404
diff --git a/app/controllers/import/github_controller.rb b/app/controllers/import/github_controller.rb
index 67bf4190e7e..9c1b0eb20f4 100644
--- a/app/controllers/import/github_controller.rb
+++ b/app/controllers/import/github_controller.rb
@@ -1,14 +1,29 @@
class Import::GithubController < Import::BaseController
before_action :verify_github_import_enabled
- before_action :github_auth, except: :callback
+ before_action :github_auth, only: [:status, :jobs, :create]
rescue_from Octokit::Unauthorized, with: :github_unauthorized
+ helper_method :logged_in_with_github?
+
+ def new
+ if logged_in_with_github?
+ go_to_github_for_permissions
+ elsif session[:github_access_token]
+ redirect_to status_import_github_url
+ end
+ end
+
def callback
session[:github_access_token] = client.get_token(params[:code])
redirect_to status_import_github_url
end
+ def personal_access_token
+ session[:github_access_token] = params[:personal_access_token]
+ redirect_to status_import_github_url
+ end
+
def status
@repos = client.repos
@already_added_projects = current_user.created_projects.where(import_type: "github")
@@ -57,10 +72,14 @@ class Import::GithubController < Import::BaseController
end
def github_unauthorized
- go_to_github_for_permissions
+ session[:github_access_token] = nil
+ redirect_to new_import_github_url,
+ alert: 'Access denied to your GitHub account.'
end
- private
+ def logged_in_with_github?
+ current_user.identities.exists?(provider: 'github')
+ end
def access_params
{ github_access_token: session[:github_access_token] }
diff --git a/app/controllers/notification_settings_controller.rb b/app/controllers/notification_settings_controller.rb
index eddd03cc229..8ec4bb1233f 100644
--- a/app/controllers/notification_settings_controller.rb
+++ b/app/controllers/notification_settings_controller.rb
@@ -2,11 +2,9 @@ class NotificationSettingsController < ApplicationController
before_action :authenticate_user!
def create
- project = Project.find(params[:project][:id])
+ return render_404 unless can_read?(resource)
- return render_404 unless can?(current_user, :read_project, project)
-
- @notification_setting = current_user.notification_settings_for(project)
+ @notification_setting = current_user.notification_settings_for(resource)
@saved = @notification_setting.update_attributes(notification_setting_params)
render_response
@@ -21,6 +19,22 @@ class NotificationSettingsController < ApplicationController
private
+ def resource
+ @resource ||=
+ if params[:project_id].present?
+ Project.find(params[:project_id])
+ elsif params[:namespace_id].present?
+ Group.find(params[:namespace_id])
+ end
+ end
+
+ def can_read?(resource)
+ ability_name = resource.class.name.downcase
+ ability_name = "read_#{ability_name}".to_sym
+
+ can?(current_user, ability_name, resource)
+ end
+
def render_response
render json: {
html: view_to_html_string("shared/notifications/_button", notification_setting: @notification_setting),
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index 39c8ba40ca2..dd86b940a08 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -59,7 +59,13 @@ class Projects::MergeRequestsController < Projects::ApplicationController
respond_to do |format|
format.html
format.json { render json: @merge_request }
- format.patch { render text: @merge_request.to_patch }
+ format.patch do
+ headers.store(*Gitlab::Workhorse.send_git_patch(@project.repository,
+ @merge_request.diff_base_commit.id,
+ @merge_request.last_commit.id))
+ headers['Content-Disposition'] = 'inline'
+ head :ok
+ end
format.diff do
return render_404 unless @merge_request.diff_refs
diff --git a/app/finders/pipelines_finder.rb b/app/finders/pipelines_finder.rb
index c19a795d467..641fbf838f1 100644
--- a/app/finders/pipelines_finder.rb
+++ b/app/finders/pipelines_finder.rb
@@ -29,10 +29,10 @@ class PipelinesFinder
end
def branches
- project.repository.branches.map(&:name)
+ project.repository.branch_names
end
def tags
- project.repository.tags.map(&:name)
+ project.repository.tag_names
end
end
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb
index 55313fd8357..6e580c62ccd 100644
--- a/app/helpers/application_settings_helper.rb
+++ b/app/helpers/application_settings_helper.rb
@@ -78,4 +78,12 @@ module ApplicationSettingsHelper
end
end
end
+
+ def repository_storage_options_for_select
+ options = Gitlab.config.repositories.storages.map do |name, path|
+ ["#{name} - #{path}", name]
+ end
+
+ options_for_select(options, @application_setting.repository_storage)
+ end
end
diff --git a/app/helpers/blob_helper.rb b/app/helpers/blob_helper.rb
index 4b4bc3d4276..428a42266d0 100644
--- a/app/helpers/blob_helper.rb
+++ b/app/helpers/blob_helper.rb
@@ -1,10 +1,10 @@
module BlobHelper
- def highlighter(blob_name, blob_content, nowrap: false)
- Gitlab::Highlight.new(blob_name, blob_content, nowrap: nowrap)
+ def highlighter(blob_name, blob_content, repository: nil, nowrap: false)
+ Gitlab::Highlight.new(blob_name, blob_content, nowrap: nowrap, repository: repository)
end
- def highlight(blob_name, blob_content, nowrap: false, plain: false)
- Gitlab::Highlight.highlight(blob_name, blob_content, nowrap: nowrap, plain: plain)
+ def highlight(blob_name, blob_content, repository: nil, nowrap: false, plain: false)
+ Gitlab::Highlight.highlight(blob_name, blob_content, nowrap: nowrap, plain: plain, repository: repository)
end
def no_highlight_files
diff --git a/app/helpers/dropdowns_helper.rb b/app/helpers/dropdowns_helper.rb
index 6b617e1730a..7c140538012 100644
--- a/app/helpers/dropdowns_helper.rb
+++ b/app/helpers/dropdowns_helper.rb
@@ -69,7 +69,7 @@ module DropdownsHelper
def dropdown_filter(placeholder, search_id: nil)
content_tag :div, class: "dropdown-input" do
- filter_output = search_field_tag search_id, nil, class: "dropdown-input-field", placeholder: placeholder
+ filter_output = search_field_tag search_id, nil, class: "dropdown-input-field", placeholder: placeholder, autocomplete: 'off'
filter_output << icon('search', class: "dropdown-input-search")
filter_output << icon('times', class: "dropdown-input-clear js-dropdown-input-clear", role: "button")
diff --git a/app/helpers/labels_helper.rb b/app/helpers/labels_helper.rb
index 5074e645769..5e9f5837101 100644
--- a/app/helpers/labels_helper.rb
+++ b/app/helpers/labels_helper.rb
@@ -34,10 +34,7 @@ module LabelsHelper
# Returns a String
def link_to_label(label, project: nil, type: :issue, tooltip: true, css_class: nil, &block)
project ||= @project || label.project
- link = send("namespace_project_#{type.to_s.pluralize}_path",
- project.namespace,
- project,
- label_name: [label.name])
+ link = label_filter_path(project, label, type: type)
if block_given?
link_to link, class: css_class, &block
@@ -46,6 +43,13 @@ module LabelsHelper
end
end
+ def label_filter_path(project, label, type: issue)
+ send("namespace_project_#{type.to_s.pluralize}_path",
+ project.namespace,
+ project,
+ label_name: [label.name])
+ end
+
def project_label_names
@project.labels.pluck(:title)
end
diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb
index b401c8385be..e85ba76887d 100644
--- a/app/helpers/notes_helper.rb
+++ b/app/helpers/notes_helper.rb
@@ -69,4 +69,14 @@ module NotesHelper
button_tag 'Reply...', class: 'btn btn-text-field js-discussion-reply-button',
data: data, title: 'Add a reply'
end
+
+ def note_max_access_for_user(note)
+ @max_access_by_user_id ||= Hash.new do |hash, key|
+ project = key[:project]
+ hash[key] = project.team.human_max_access(key[:user_id])
+ end
+
+ full_key = { project: note.project, user_id: note.author_id }
+ @max_access_by_user_id[full_key]
+ end
end
diff --git a/app/helpers/notifications_helper.rb b/app/helpers/notifications_helper.rb
index 77783cd7640..7e8369d0a05 100644
--- a/app/helpers/notifications_helper.rb
+++ b/app/helpers/notifications_helper.rb
@@ -72,6 +72,6 @@ module NotificationsHelper
# Create hidden field to send notification setting source to controller
def hidden_setting_source_input(notification_setting)
return unless notification_setting.source_type
- hidden_field_tag "#{notification_setting.source_type.downcase}[id]", notification_setting.source_id
+ hidden_field_tag "#{notification_setting.source_type.downcase}_id", notification_setting.source_id
end
end
diff --git a/app/helpers/page_layout_helper.rb b/app/helpers/page_layout_helper.rb
index e4e8b934bc8..22387d66451 100644
--- a/app/helpers/page_layout_helper.rb
+++ b/app/helpers/page_layout_helper.rb
@@ -52,7 +52,7 @@ module PageLayoutHelper
raise ArgumentError, 'cannot provide more than two attributes' if map.length > 2
@page_card_attributes ||= {}
- @page_card_attributes = map.reject { |_,v| v.blank? } if map.present?
+ @page_card_attributes = map.reject { |_, v| v.blank? } if map.present?
@page_card_attributes
end
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index d91e3332e48..f312a7ccca3 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -15,7 +15,7 @@ module ProjectsHelper
def link_to_member_avatar(author, opts = {})
default_opts = { avatar: true, name: true, size: 16, author_class: 'author', title: ":name" }
opts = default_opts.merge(opts)
- image_tag(avatar_icon(author, opts[:size]), width: opts[:size], class: "avatar avatar-inline #{"s#{opts[:size]}" if opts[:size]}", alt:'') if opts[:avatar]
+ image_tag(avatar_icon(author, opts[:size]), width: opts[:size], class: "avatar avatar-inline #{"s#{opts[:size]}" if opts[:size]}", alt: '') if opts[:avatar]
end
def link_to_member(project, author, opts = {}, &block)
@@ -27,7 +27,7 @@ module ProjectsHelper
author_html = ""
# Build avatar image tag
- author_html << image_tag(avatar_icon(author, opts[:size]), width: opts[:size], class: "avatar avatar-inline #{"s#{opts[:size]}" if opts[:size]}", alt:'') if opts[:avatar]
+ author_html << image_tag(avatar_icon(author, opts[:size]), width: opts[:size], class: "avatar avatar-inline #{"s#{opts[:size]}" if opts[:size]}", alt: '') if opts[:avatar]
# Build name span tag
if opts[:by_username]
@@ -327,9 +327,9 @@ module ProjectsHelper
end
end
- def sanitize_repo_path(message)
+ def sanitize_repo_path(project, message)
return '' unless message.present?
- message.strip.gsub(Gitlab.config.gitlab_shell.repos_path.chomp('/'), "[REPOS PATH]")
+ message.strip.gsub(project.repository_storage_path.chomp('/'), "[REPOS PATH]")
end
end
diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb
index d914b0b26eb..5fa6eacd234 100644
--- a/app/models/application_setting.rb
+++ b/app/models/application_setting.rb
@@ -55,6 +55,10 @@ class ApplicationSetting < ActiveRecord::Base
presence: true,
numericality: { only_integer: true, greater_than: 0 }
+ validates :repository_storage,
+ presence: true,
+ inclusion: { in: ->(_object) { Gitlab.config.repositories.storages.keys } }
+
validates_each :restricted_visibility_levels do |record, attr, value|
unless value.nil?
value.each do |level|
@@ -134,6 +138,7 @@ class ApplicationSetting < ActiveRecord::Base
disabled_oauth_sign_in_sources: [],
send_user_confirmation_email: false,
container_registry_token_expire_delay: 5,
+ repository_storage: 'default',
)
end
diff --git a/app/models/ci/build.rb b/app/models/ci/build.rb
index 2b0bec33131..c11f8e6884d 100644
--- a/app/models/ci/build.rb
+++ b/app/models/ci/build.rb
@@ -90,7 +90,7 @@ module Ci
end
def retryable?
- project.builds_enabled? && commands.present?
+ project.builds_enabled? && commands.present? && complete?
end
def retried?
diff --git a/app/models/ci/variable.rb b/app/models/ci/variable.rb
index f8d5d4486fd..c9c47ec7419 100644
--- a/app/models/ci/variable.rb
+++ b/app/models/ci/variable.rb
@@ -13,6 +13,7 @@ module Ci
attr_encrypted :value,
mode: :per_attribute_iv_and_salt,
+ insecure_mode: true,
key: Gitlab::Application.secrets.db_key_base,
algorithm: 'aes-256-cbc'
end
diff --git a/app/models/event.rb b/app/models/event.rb
index 716039fb54b..d7d23c7ae6d 100644
--- a/app/models/event.rb
+++ b/app/models/event.rb
@@ -315,7 +315,7 @@ class Event < ActiveRecord::Base
def body?
if push?
- push_with_commits?
+ push_with_commits? || rm_ref?
elsif note?
true
else
diff --git a/app/models/member.rb b/app/models/member.rb
index c74a16367db..57161397e2b 100644
--- a/app/models/member.rb
+++ b/app/models/member.rb
@@ -32,6 +32,7 @@ class Member < ActiveRecord::Base
scope :request, -> { where.not(requested_at: nil) }
scope :non_request, -> { where(requested_at: nil) }
scope :non_pending, -> { non_request.non_invite }
+ scope :has_access, -> { where('access_level > 0') }
scope :guests, -> { where(access_level: GUEST) }
scope :reporters, -> { where(access_level: REPORTER) }
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index f5c5b7c1306..53d9aa588af 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -319,13 +319,6 @@ class MergeRequest < ActiveRecord::Base
)
end
- # Returns the commit as a series of email patches.
- #
- # see "git format-patch"
- def to_patch
- target_project.repository.format_patch(diff_base_commit.sha, source_sha)
- end
-
def hook_attrs
attrs = {
source: source_project.try(:hook_attrs),
diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb
index aca377cc600..86331a33c05 100644
--- a/app/models/merge_request_diff.rb
+++ b/app/models/merge_request_diff.rb
@@ -108,44 +108,46 @@ class MergeRequestDiff < ActiveRecord::Base
# Reload all commits related to current merge request from repo
# and save it as array of hashes in st_commits db field
def reload_commits
+ new_attributes = {}
+
commit_objects = unmerged_commits
if commit_objects.present?
- self.st_commits = dump_commits(commit_objects)
+ new_attributes[:st_commits] = dump_commits(commit_objects)
end
- save
+ update_columns_serialized(new_attributes)
end
# Reload diffs between branches related to current merge request from repo
# and save it as array of hashes in st_diffs db field
def reload_diffs
+ new_attributes = {}
new_diffs = []
if commits.size.zero?
- self.state = :empty
+ new_attributes[:state] = :empty
else
diff_collection = unmerged_diffs
if diff_collection.overflow?
# Set our state to 'overflow' to make the #empty? and #collected?
# methods (generated by StateMachine) return false.
- self.state = :overflow
+ new_attributes[:state] = :overflow
end
- self.real_size = diff_collection.real_size
+ new_attributes[:real_size] = diff_collection.real_size
if diff_collection.any?
new_diffs = dump_diffs(diff_collection)
- self.state = :collected
+ new_attributes[:state] = :collected
end
end
- self.st_diffs = new_diffs
-
- self.base_commit_sha = self.repository.merge_base(self.head, self.base)
+ new_attributes[:st_diffs] = new_diffs
+ new_attributes[:base_commit_sha] = self.repository.merge_base(self.head, self.base)
- self.save
+ update_columns_serialized(new_attributes)
end
# Collect array of Git::Diff objects
@@ -190,4 +192,29 @@ class MergeRequestDiff < ActiveRecord::Base
)
end
end
+
+ private
+
+ #
+ # #save or #update_attributes providing changes on serialized attributes do a lot of
+ # serialization and deserialization calls resulting in bad performance.
+ # Using #update_columns solves the problem with just one YAML.dump per serialized attribute that we provide.
+ # As a tradeoff we need to reload the current instance to properly manage time objects on those serialized
+ # attributes. So to keep the same behaviour as the attribute assignment we reload the instance.
+ # The difference is in the usage of
+ # #write_attribute= (#update_attributes) and #raw_write_attribute= (#update_columns)
+ #
+ # Ex:
+ #
+ # new_attributes[:st_commits].first.slice(:committed_date)
+ # => {:committed_date=>2014-02-27 11:01:38 +0200}
+ # YAML.load(YAML.dump(new_attributes[:st_commits].first.slice(:committed_date)))
+ # => {:committed_date=>2014-02-27 10:01:38 +0100}
+ #
+ def update_columns_serialized(new_attributes)
+ return unless new_attributes.any?
+
+ update_columns(new_attributes.merge(updated_at: current_time_from_proper_timezone))
+ reload
+ end
end
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index da19462f265..8b52cc824cd 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -21,8 +21,10 @@ class Namespace < ActiveRecord::Base
delegate :name, to: :owner, allow_nil: true, prefix: true
- after_create :ensure_dir_exist
after_update :move_dir, if: :path_changed?
+
+ # Save the storage paths before the projects are destroyed to use them on after destroy
+ before_destroy(prepend: true) { @old_repository_storage_paths = repository_storage_paths }
after_destroy :rm_dir
scope :root, -> { where('type IS NULL') }
@@ -87,51 +89,35 @@ class Namespace < ActiveRecord::Base
owner_name
end
- def ensure_dir_exist
- gitlab_shell.add_namespace(path)
- end
-
- def rm_dir
- # Move namespace directory into trash.
- # We will remove it later async
- new_path = "#{path}+#{id}+deleted"
-
- if gitlab_shell.mv_namespace(path, new_path)
- message = "Namespace directory \"#{path}\" moved to \"#{new_path}\""
- Gitlab::AppLogger.info message
-
- # Remove namespace directroy async with delay so
- # GitLab has time to remove all projects first
- GitlabShellWorker.perform_in(5.minutes, :rm_namespace, new_path)
- end
- end
-
def move_dir
- # Ensure old directory exists before moving it
- gitlab_shell.add_namespace(path_was)
-
if any_project_has_container_registry_tags?
raise Exception.new('Namespace cannot be moved, because at least one project has tags in container registry')
end
- if gitlab_shell.mv_namespace(path_was, path)
- Gitlab::UploadsTransfer.new.rename_namespace(path_was, path)
-
- # If repositories moved successfully we need to
- # send update instructions to users.
- # However we cannot allow rollback since we moved namespace dir
- # So we basically we mute exceptions in next actions
- begin
- send_update_instructions
- rescue
- # Returning false does not rollback after_* transaction but gives
- # us information about failing some of tasks
- false
+ # Move the namespace directory in all storages paths used by member projects
+ repository_storage_paths.each do |repository_storage_path|
+ # Ensure old directory exists before moving it
+ gitlab_shell.add_namespace(repository_storage_path, path_was)
+
+ unless gitlab_shell.mv_namespace(repository_storage_path, path_was, path)
+ # if we cannot move namespace directory we should rollback
+ # db changes in order to prevent out of sync between db and fs
+ raise Exception.new('namespace directory cannot be moved')
end
- else
- # if we cannot move namespace directory we should rollback
- # db changes in order to prevent out of sync between db and fs
- raise Exception.new('namespace directory cannot be moved')
+ end
+
+ Gitlab::UploadsTransfer.new.rename_namespace(path_was, path)
+
+ # If repositories moved successfully we need to
+ # send update instructions to users.
+ # However we cannot allow rollback since we moved namespace dir
+ # So we basically we mute exceptions in next actions
+ begin
+ send_update_instructions
+ rescue
+ # Returning false does not rollback after_* transaction but gives
+ # us information about failing some of tasks
+ false
end
end
@@ -152,4 +138,33 @@ class Namespace < ActiveRecord::Base
def find_fork_of(project)
projects.joins(:forked_project_link).find_by('forked_project_links.forked_from_project_id = ?', project.id)
end
+
+ private
+
+ def repository_storage_paths
+ # We need to get the storage paths for all the projects, even the ones that are
+ # pending delete. Unscoping also get rids of the default order, which causes
+ # problems with SELECT DISTINCT.
+ Project.unscoped do
+ projects.select('distinct(repository_storage)').to_a.map(&:repository_storage_path)
+ end
+ end
+
+ def rm_dir
+ # Remove the namespace directory in all storages paths used by member projects
+ @old_repository_storage_paths.each do |repository_storage_path|
+ # Move namespace directory into trash.
+ # We will remove it later async
+ new_path = "#{path}+#{id}+deleted"
+
+ if gitlab_shell.mv_namespace(repository_storage_path, path, new_path)
+ message = "Namespace directory \"#{path}\" moved to \"#{new_path}\""
+ Gitlab::AppLogger.info message
+
+ # Remove namespace directroy async with delay so
+ # GitLab has time to remove all projects first
+ GitlabShellWorker.perform_in(5.minutes, :rm_namespace, repository_storage_path, new_path)
+ end
+ end
+ end
end
diff --git a/app/models/network/graph.rb b/app/models/network/graph.rb
index a2aee2f925b..345041a6ad1 100644
--- a/app/models/network/graph.rb
+++ b/app/models/network/graph.rb
@@ -54,7 +54,7 @@ module Network
@map = {}
@reserved = {}
- @commits.each_with_index do |c,i|
+ @commits.each_with_index do |c, i|
c.time = i
days[i] = c.committed_date
@map[c.id] = c
@@ -116,7 +116,7 @@ module Network
end
def commits_sort_by_ref
- @commits.sort do |a,b|
+ @commits.sort do |a, b|
if include_ref?(a)
-1
elsif include_ref?(b)
diff --git a/app/models/project.rb b/app/models/project.rb
index 96837364423..6a950ee830d 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -24,8 +24,12 @@ class Project < ActiveRecord::Base
default_value_for :wiki_enabled, gitlab_config_features.wiki
default_value_for :snippets_enabled, gitlab_config_features.snippets
default_value_for :container_registry_enabled, gitlab_config_features.container_registry
+ default_value_for(:repository_storage) { current_application_settings.repository_storage }
default_value_for(:shared_runners_enabled) { current_application_settings.shared_runners_enabled }
+ after_create :ensure_dir_exist
+ after_save :ensure_dir_exist, if: :namespace_id_changed?
+
# set last_activity_at to the same as created_at
after_create :set_last_activity_at
def set_last_activity_at
@@ -81,6 +85,7 @@ class Project < ActiveRecord::Base
has_one :jira_service, dependent: :destroy
has_one :redmine_service, dependent: :destroy
has_one :custom_issue_tracker_service, dependent: :destroy
+ has_one :bugzilla_service, dependent: :destroy
has_one :gitlab_issue_tracker_service, dependent: :destroy, inverse_of: :project
has_one :external_wiki_service, dependent: :destroy
@@ -164,6 +169,9 @@ class Project < ActiveRecord::Base
validate :visibility_level_allowed_by_group
validate :visibility_level_allowed_as_fork
validate :check_wiki_path_conflict
+ validates :repository_storage,
+ presence: true,
+ inclusion: { in: ->(_object) { Gitlab.config.repositories.storages.keys } }
add_authentication_token_field :runners_token
before_save :ensure_runners_token
@@ -375,6 +383,10 @@ class Project < ActiveRecord::Base
end
end
+ def repository_storage_path
+ Gitlab.config.repositories.storages[repository_storage]
+ end
+
def team
@team ||= ProjectTeam.new(self)
end
@@ -841,12 +853,12 @@ class Project < ActiveRecord::Base
raise Exception.new('Project cannot be renamed, because tags are present in its container registry')
end
- if gitlab_shell.mv_repository(old_path_with_namespace, new_path_with_namespace)
+ if gitlab_shell.mv_repository(repository_storage_path, old_path_with_namespace, new_path_with_namespace)
# If repository moved successfully we need to send update instructions to users.
# However we cannot allow rollback since we moved repository
# So we basically we mute exceptions in next actions
begin
- gitlab_shell.mv_repository("#{old_path_with_namespace}.wiki", "#{new_path_with_namespace}.wiki")
+ gitlab_shell.mv_repository(repository_storage_path, "#{old_path_with_namespace}.wiki", "#{new_path_with_namespace}.wiki")
send_move_instructions(old_path_with_namespace)
reset_events_cache
@@ -987,7 +999,7 @@ class Project < ActiveRecord::Base
def create_repository
# Forked import is handled asynchronously
unless forked?
- if gitlab_shell.add_repository(path_with_namespace)
+ if gitlab_shell.add_repository(repository_storage_path, path_with_namespace)
repository.after_create
true
else
@@ -1139,4 +1151,8 @@ class Project < ActiveRecord::Base
_, status = Gitlab::Popen.popen(%W(find #{export_path} -not -path #{export_path} -delete))
status.zero?
end
+
+ def ensure_dir_exist
+ gitlab_shell.add_namespace(repository_storage_path, namespace.path)
+ end
end
diff --git a/app/models/project_import_data.rb b/app/models/project_import_data.rb
index ca8a9b4217b..331123a5a5b 100644
--- a/app/models/project_import_data.rb
+++ b/app/models/project_import_data.rb
@@ -7,6 +7,7 @@ class ProjectImportData < ActiveRecord::Base
marshal: true,
encode: true,
mode: :per_attribute_iv_and_salt,
+ insecure_mode: true,
algorithm: 'aes-256-cbc'
serialize :data, JSON
diff --git a/app/models/project_services/bugzilla_service.rb b/app/models/project_services/bugzilla_service.rb
new file mode 100644
index 00000000000..260f6030957
--- /dev/null
+++ b/app/models/project_services/bugzilla_service.rb
@@ -0,0 +1,25 @@
+class BugzillaService < IssueTrackerService
+
+ prop_accessor :title, :description, :project_url, :issues_url, :new_issue_url
+
+ def title
+ if self.properties && self.properties['title'].present?
+ self.properties['title']
+ else
+ 'Bugzilla'
+ end
+ end
+
+ def description
+ if self.properties && self.properties['description'].present?
+ self.properties['description']
+ else
+ 'Bugzilla issue tracker'
+ end
+ end
+
+ def to_param
+ 'bugzilla'
+ end
+
+end
diff --git a/app/models/project_services/custom_issue_tracker_service.rb b/app/models/project_services/custom_issue_tracker_service.rb
index 6b2b1daa724..8f2db46a7ba 100644
--- a/app/models/project_services/custom_issue_tracker_service.rb
+++ b/app/models/project_services/custom_issue_tracker_service.rb
@@ -32,7 +32,4 @@ class CustomIssueTrackerService < IssueTrackerService
]
end
- def initialize_properties
- self.properties = {} if properties.nil?
- end
end
diff --git a/app/models/project_services/hipchat_service.rb b/app/models/project_services/hipchat_service.rb
index 0ff4f4c8dd2..23e5b16221b 100644
--- a/app/models/project_services/hipchat_service.rb
+++ b/app/models/project_services/hipchat_service.rb
@@ -106,7 +106,7 @@ class HipchatService < Service
else
message << "pushed to #{ref_type} <a href=\""\
"#{project.web_url}/commits/#{CGI.escape(ref)}\">#{ref}</a> "
- message << "of <a href=\"#{project.web_url}\">#{project.name_with_namespace.gsub!(/\s/,'')}</a> "
+ message << "of <a href=\"#{project.web_url}\">#{project.name_with_namespace.gsub!(/\s/, '')}</a> "
message << "(<a href=\"#{project.web_url}/compare/#{before}...#{after}\">Compare changes</a>)"
push[:commits].take(MAX_COMMITS).each do |commit|
diff --git a/app/models/project_services/jira_service.rb b/app/models/project_services/jira_service.rb
index beda89d3963..8b3296c712f 100644
--- a/app/models/project_services/jira_service.rb
+++ b/app/models/project_services/jira_service.rb
@@ -124,7 +124,7 @@ class JiraService < IssueTrackerService
def build_api_url_from_project_url
server = URI(project_url)
- default_ports = [["http",80],["https",443]].include?([server.scheme,server.port])
+ default_ports = [["http", 80], ["https", 443]].include?([server.scheme, server.port])
server_url = "#{server.scheme}://#{server.host}"
server_url.concat(":#{server.port}") unless default_ports
"#{server_url}/rest/api/#{DEFAULT_API_VERSION}"
diff --git a/app/models/project_team.rb b/app/models/project_team.rb
index 73e736820af..0865b979ce0 100644
--- a/app/models/project_team.rb
+++ b/app/models/project_team.rb
@@ -137,20 +137,10 @@ class ProjectTeam
def max_member_access(user_id)
access = []
- project.members.non_request.each do |member|
- if member.user_id == user_id
- access << member.access_field if member.access_field
- break
- end
- end
+ access += project.members.non_request.where(user_id: user_id).has_access.pluck(:access_level)
if group
- group.members.non_request.each do |member|
- if member.user_id == user_id
- access << member.access_field if member.access_field
- break
- end
- end
+ access += group.members.non_request.where(user_id: user_id).has_access.pluck(:access_level)
end
if project.invited_groups.any? && project.allowed_to_share_with_group?
diff --git a/app/models/project_wiki.rb b/app/models/project_wiki.rb
index 25d82929c0b..a255710f577 100644
--- a/app/models/project_wiki.rb
+++ b/app/models/project_wiki.rb
@@ -159,7 +159,7 @@ class ProjectWiki
private
def init_repo(path_with_namespace)
- gitlab_shell.add_repository(path_with_namespace)
+ gitlab_shell.add_repository(project.repository_storage_path, path_with_namespace)
end
def commit_details(action, message = nil, title = nil)
@@ -173,7 +173,7 @@ class ProjectWiki
end
def path_to_repo
- @path_to_repo ||= File.join(Gitlab.config.gitlab_shell.repos_path, "#{path_with_namespace}.git")
+ @path_to_repo ||= File.join(project.repository_storage_path, "#{path_with_namespace}.git")
end
def update_project_activity
diff --git a/app/models/repository.rb b/app/models/repository.rb
index acc720ccfa3..eb232ea681b 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -39,7 +39,7 @@ class Repository
# Return absolute path to repository
def path_to_repo
@path_to_repo ||= File.expand_path(
- File.join(Gitlab.config.gitlab_shell.repos_path, path_with_namespace + ".git")
+ File.join(@project.repository_storage_path, path_with_namespace + ".git")
)
end
@@ -246,24 +246,26 @@ class Repository
end
end
+ # Keys for data that can be affected for any commit push.
def cache_keys
- %i(size branch_names tag_names branch_count tag_count commit_count
+ %i(size commit_count
readme version contribution_guide changelog
license_blob license_key gitignore)
end
+ # Keys for data on branch/tag operations.
+ def cache_keys_for_branches_and_tags
+ %i(branch_names tag_names branch_count tag_count)
+ end
+
def build_cache
- cache_keys.each do |key|
+ (cache_keys + cache_keys_for_branches_and_tags).each do |key|
unless cache.exist?(key)
send(key)
end
end
end
- def expire_gitignore
- cache.expire(:gitignore)
- end
-
def expire_tags_cache
cache.expire(:tag_names)
@tags = nil
@@ -286,8 +288,6 @@ class Repository
# This ensures this particular cache is flushed after the first commit to a
# new repository.
expire_emptiness_caches if empty?
- expire_branch_count_cache
- expire_tag_count_cache
end
def expire_branch_cache(branch_name = nil)
@@ -978,6 +978,10 @@ class Repository
raw_repository.ls_files(actual_ref)
end
+ def gitattribute(path, name)
+ raw_repository.attributes(path)[name]
+ end
+
def copy_gitattributes(ref)
actual_ref = ref || root_ref
begin
diff --git a/app/models/service.rb b/app/models/service.rb
index 40d39933ad8..d7a32c28267 100644
--- a/app/models/service.rb
+++ b/app/models/service.rb
@@ -170,6 +170,7 @@ class Service < ActiveRecord::Base
bamboo
buildkite
builds_email
+ bugzilla
campfire
custom_issue_tracker
drone_ci
diff --git a/app/models/snippet.rb b/app/models/snippet.rb
index 51f6ae7b25c..5ec933601ac 100644
--- a/app/models/snippet.rb
+++ b/app/models/snippet.rb
@@ -20,6 +20,7 @@ class Snippet < ActiveRecord::Base
length: { within: 0..255 },
format: { with: Gitlab::Regex.file_name_regex,
message: Gitlab::Regex.file_name_regex_message }
+
validates :content, presence: true
validates :visibility_level, inclusion: { in: Gitlab::VisibilityLevel.values }
@@ -81,6 +82,11 @@ class Snippet < ActiveRecord::Base
0
end
+ # alias for compatibility with blobs and highlighting
+ def path
+ file_name
+ end
+
def name
file_name
end
diff --git a/app/models/user.rb b/app/models/user.rb
index 599b2fb1191..eac716b120b 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -25,6 +25,7 @@ class User < ActiveRecord::Base
attr_encrypted :otp_secret,
key: Gitlab::Application.config.secret_key_base,
mode: :per_attribute_iv_and_salt,
+ insecure_mode: true,
algorithm: 'aes-256-cbc'
devise :two_factor_authenticatable,
@@ -763,7 +764,7 @@ class User < ActiveRecord::Base
unless email_domains.blank?
match_found = email_domains.any? do |domain|
- escaped = Regexp.escape(domain).gsub('\*','.*?')
+ escaped = Regexp.escape(domain).gsub('\*', '.*?')
regexp = Regexp.new "^#{escaped}$", Regexp::IGNORECASE
email_domain = Mail::Address.new(self.email).domain
email_domain =~ regexp
diff --git a/app/services/projects/destroy_service.rb b/app/services/projects/destroy_service.rb
index f09072975c3..882606e38d0 100644
--- a/app/services/projects/destroy_service.rb
+++ b/app/services/projects/destroy_service.rb
@@ -51,13 +51,13 @@ module Projects
return true if params[:skip_repo] == true
# There is a possibility project does not have repository or wiki
- return true unless gitlab_shell.exists?(path + '.git')
+ return true unless gitlab_shell.exists?(project.repository_storage_path, path + '.git')
new_path = removal_path(path)
- if gitlab_shell.mv_repository(path, new_path)
+ if gitlab_shell.mv_repository(project.repository_storage_path, path, new_path)
log_info("Repository \"#{path}\" moved to \"#{new_path}\"")
- GitlabShellWorker.perform_in(5.minutes, :remove_repository, new_path)
+ GitlabShellWorker.perform_in(5.minutes, :remove_repository, project.repository_storage_path, new_path)
else
false
end
diff --git a/app/services/projects/housekeeping_service.rb b/app/services/projects/housekeeping_service.rb
index 43db29315a1..a47df22f1ba 100644
--- a/app/services/projects/housekeeping_service.rb
+++ b/app/services/projects/housekeeping_service.rb
@@ -24,7 +24,7 @@ module Projects
def execute
raise LeaseTaken unless try_obtain_lease
- GitlabShellOneShotWorker.perform_async(:gc, @project.path_with_namespace)
+ GitlabShellOneShotWorker.perform_async(:gc, @project.repository_storage_path, @project.path_with_namespace)
ensure
Gitlab::Metrics.measure(:reset_pushes_since_gc) do
@project.update_column(:pushes_since_gc, 0)
diff --git a/app/services/projects/import_service.rb b/app/services/projects/import_service.rb
index 9159ec08959..163ebf26c84 100644
--- a/app/services/projects/import_service.rb
+++ b/app/services/projects/import_service.rb
@@ -42,7 +42,7 @@ module Projects
def import_repository
begin
- gitlab_shell.import_repository(project.path_with_namespace, project.import_url)
+ gitlab_shell.import_repository(project.repository_storage_path, project.path_with_namespace, project.import_url)
rescue Gitlab::Shell::Error => e
raise Error, "Error importing repository #{project.import_url} into #{project.path_with_namespace} - #{e.message}"
end
diff --git a/app/services/projects/transfer_service.rb b/app/services/projects/transfer_service.rb
index 03b57dea51e..bc7f8bf433b 100644
--- a/app/services/projects/transfer_service.rb
+++ b/app/services/projects/transfer_service.rb
@@ -50,12 +50,12 @@ module Projects
project.send_move_instructions(old_path)
# Move main repository
- unless gitlab_shell.mv_repository(old_path, new_path)
+ unless gitlab_shell.mv_repository(project.repository_storage_path, old_path, new_path)
raise TransferError.new('Cannot move project')
end
# Move wiki repo also if present
- gitlab_shell.mv_repository("#{old_path}.wiki", "#{new_path}.wiki")
+ gitlab_shell.mv_repository(project.repository_storage_path, "#{old_path}.wiki", "#{new_path}.wiki")
# clear project cached events
project.reset_events_cache
diff --git a/app/uploaders/lfs_object_uploader.rb b/app/uploaders/lfs_object_uploader.rb
index 28085b31083..046a1d641a9 100644
--- a/app/uploaders/lfs_object_uploader.rb
+++ b/app/uploaders/lfs_object_uploader.rb
@@ -4,7 +4,7 @@ class LfsObjectUploader < CarrierWave::Uploader::Base
storage :file
def store_dir
- "#{Gitlab.config.lfs.storage_path}/#{model.oid[0,2]}/#{model.oid[2,2]}"
+ "#{Gitlab.config.lfs.storage_path}/#{model.oid[0, 2]}/#{model.oid[2, 2]}"
end
def cache_dir
diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml
index c883e8f97da..c1f70bc1866 100644
--- a/app/views/admin/application_settings/_form.html.haml
+++ b/app/views/admin/application_settings/_form.html.haml
@@ -15,7 +15,7 @@
= f.label :default_snippet_visibility, class: 'control-label col-sm-2'
.col-sm-10
= render('shared/visibility_radios', model_method: :default_snippet_visibility, form: f, selected_level: @application_setting.default_snippet_visibility, form_model: ProjectSnippet.new)
- .form-group.group-visibility-level-holder
+ .form-group.project-visibility-level-holder
= f.label :default_group_visibility, class: 'control-label col-sm-2'
.col-sm-10
= render('shared/visibility_radios', model_method: :default_group_visibility, form: f, selected_level: @application_setting.default_group_visibility, form_model: Group.new)
@@ -311,6 +311,15 @@
= f.text_field :sentry_dsn, class: 'form-control'
%fieldset
+ %legend Repository Storage
+ .form-group
+ = f.label :repository_storage, 'Storage path for new projects', class: 'control-label col-sm-2'
+ .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
+
+ %fieldset
%legend Repository Checks
.form-group
.col-sm-offset-2.col-sm-10
diff --git a/app/views/admin/background_jobs/_head.html.haml b/app/views/admin/background_jobs/_head.html.haml
index d78682532ed..9d722bd7382 100644
--- a/app/views/admin/background_jobs/_head.html.haml
+++ b/app/views/admin/background_jobs/_head.html.haml
@@ -1,5 +1,9 @@
.nav-links.sub-nav
%ul{ class: (container_class) }
+ = nav_link(controller: :system_info) do
+ = link_to admin_system_info_path, title: 'System Info' do
+ %span
+ System Info
= nav_link(controller: :background_jobs) do
= link_to admin_background_jobs_path, title: 'Background Jobs' do
%span
diff --git a/app/views/admin/background_jobs/show.html.haml b/app/views/admin/background_jobs/show.html.haml
index 654d261aa99..4f680b507c4 100644
--- a/app/views/admin/background_jobs/show.html.haml
+++ b/app/views/admin/background_jobs/show.html.haml
@@ -2,7 +2,7 @@
- page_title "Background Jobs"
= render 'admin/background_jobs/head'
-%div{ class: (container_class) }
+%div{ class: container_class }
%h3.page-title Background Jobs
%p.light GitLab uses #{link_to "sidekiq", "http://sidekiq.org/"} library for async job processing
diff --git a/app/views/admin/builds/index.html.haml b/app/views/admin/builds/index.html.haml
index efd5b12cfeb..1e60205f91a 100644
--- a/app/views/admin/builds/index.html.haml
+++ b/app/views/admin/builds/index.html.haml
@@ -1,7 +1,7 @@
- @no_container = true
= render "admin/dashboard/head"
-%div{ class: (container_class) }
+%div{ class: container_class }
.top-area
%ul.nav-links
diff --git a/app/views/admin/dashboard/index.html.haml b/app/views/admin/dashboard/index.html.haml
index 4682016a886..a2ac407c159 100644
--- a/app/views/admin/dashboard/index.html.haml
+++ b/app/views/admin/dashboard/index.html.haml
@@ -1,7 +1,7 @@
- @no_container = true
= render "admin/dashboard/head"
-%div{ class: (container_class) }
+%div{ class: container_class }
.admin-dashboard.prepend-top-default
.row
.col-md-4
diff --git a/app/views/admin/groups/index.html.haml b/app/views/admin/groups/index.html.haml
index 4f1996ef7ab..94aa5f5a942 100644
--- a/app/views/admin/groups/index.html.haml
+++ b/app/views/admin/groups/index.html.haml
@@ -2,7 +2,7 @@
- page_title "Groups"
= render "admin/dashboard/head"
-%div{ class: (container_class) }
+%div{ class: container_class }
%h3.page-title
Groups (#{number_with_delimiter(@groups.total_count)})
@@ -39,7 +39,6 @@
= link_to 'New Group', new_admin_group_path, class: "btn btn-new"
%ul.content-list
- - @groups.each do |group|
- = render 'group', group: group
+ = render @groups
= paginate @groups, theme: "gitlab"
diff --git a/app/views/admin/health_check/show.html.haml b/app/views/admin/health_check/show.html.haml
index 7b8407f9152..e79303240f0 100644
--- a/app/views/admin/health_check/show.html.haml
+++ b/app/views/admin/health_check/show.html.haml
@@ -2,7 +2,7 @@
- page_title "Health Check"
= render 'admin/background_jobs/head'
-%div{ class: (container_class) }
+%div{ class: container_class }
%h3.page-title
Health Check
.bs-callout.clearfix
diff --git a/app/views/admin/logs/show.html.haml b/app/views/admin/logs/show.html.haml
index 5ddc3b9ea85..676812121d7 100644
--- a/app/views/admin/logs/show.html.haml
+++ b/app/views/admin/logs/show.html.haml
@@ -5,7 +5,7 @@
Gitlab::RepositoryCheckLogger]
= render 'admin/background_jobs/head'
-%div{ class: (container_class) }
+%div{ class: container_class }
%ul.nav-links.log-tabs
- loggers.each do |klass|
%li{ class: (klass == Gitlab::GitLogger ? 'active' : '') }
diff --git a/app/views/admin/projects/index.html.haml b/app/views/admin/projects/index.html.haml
index 4822cb693c2..7d2eb423223 100644
--- a/app/views/admin/projects/index.html.haml
+++ b/app/views/admin/projects/index.html.haml
@@ -3,7 +3,7 @@
= render 'shared/show_aside'
= render "admin/dashboard/head"
-%div{ class: (container_class) }
+%div{ class: container_class }
.row.prepend-top-default
%aside.col-md-3
.panel.admin-filter
diff --git a/app/views/admin/runners/index.html.haml b/app/views/admin/runners/index.html.haml
index b5c6b5effe3..a53876d6757 100644
--- a/app/views/admin/runners/index.html.haml
+++ b/app/views/admin/runners/index.html.haml
@@ -1,7 +1,7 @@
- @no_container = true
= render "admin/dashboard/head"
-%div{ class: (container_class) }
+%div{ class: container_class }
%p.prepend-top-default
%span
diff --git a/app/views/admin/system_info/show.html.haml b/app/views/admin/system_info/show.html.haml
new file mode 100644
index 00000000000..6956e5ab795
--- /dev/null
+++ b/app/views/admin/system_info/show.html.haml
@@ -0,0 +1,25 @@
+- @no_container = true
+- page_title "System Info"
+= render 'admin/background_jobs/head'
+
+%div{ class: container_class }
+ .prepend-top-default
+ .row
+ .col-sm-4
+ .light-well
+ %h4 CPU
+ .data
+ %h1= "#{@cpus} cores"
+ .col-sm-4
+ .light-well
+ %h4 Memory
+ .data
+ %h1= "#{number_to_human_size(@mem_used)} / #{number_to_human_size(@mem_total)}"
+ .col-sm-4
+ .light-well
+ %h4 Disks
+ .data
+ - @disks.each do |disk|
+ %h1= "#{number_to_human_size(disk[:bytes_used])} / #{number_to_human_size(disk[:bytes_total])}"
+ %p= "#{disk[:disk_name]}"
+ %p= "#{disk[:mount_path]}"
diff --git a/app/views/admin/users/index.html.haml b/app/views/admin/users/index.html.haml
index d0a696da64b..21bb99a792c 100644
--- a/app/views/admin/users/index.html.haml
+++ b/app/views/admin/users/index.html.haml
@@ -3,7 +3,7 @@
= render 'shared/show_aside'
= render "admin/dashboard/head"
-%div{ class: (container_class) }
+%div{ class: container_class }
.admin-filter
%ul.nav-links
%li{class: "#{'active' unless params[:filter]}"}
diff --git a/app/views/events/event/_push.html.haml b/app/views/events/event/_push.html.haml
index dc4ff17e31a..ea54ef226ec 100644
--- a/app/views/events/event/_push.html.haml
+++ b/app/views/events/event/_push.html.haml
@@ -1,3 +1,5 @@
+- project = event.project
+
.event-title
%span.author_name= link_to_author event
%span.event_label.pushed #{event.action_name} #{event.ref_type}
@@ -5,19 +7,18 @@
%strong= event.ref_name
- else
%strong
- = link_to event.ref_name, namespace_project_commits_path(event.project.namespace, event.project, event.ref_name), title: h(event.target_title)
+ = link_to event.ref_name, namespace_project_commits_path(project.namespace, project, event.ref_name), title: h(event.target_title)
at
- = link_to_project event.project
+ = link_to_project project
- if event.push_with_commits?
- - project = event.project
.event-body
%ul.well-list.event_commits
- few_commits = event.commits[0...2]
- few_commits.each do |commit|
= render "events/commit", commit: commit, project: project, event: event
- - create_mr = event.new_ref? && create_mr_button?(event.project.default_branch, event.ref_name, event.project)
+ - create_mr = event.new_ref? && create_mr_button?(project.default_branch, event.ref_name, project)
- if event.commits_count > 1
%li.commits-stat
- if event.commits_count > 2
@@ -27,18 +28,26 @@
- from = event.commit_from
- from_label = truncate_sha(from)
- else
- - from = event.project.default_branch
+ - from = project.default_branch
- from_label = from
- = link_to namespace_project_compare_path(event.project.namespace, event.project, from: from, to: event.commit_to) do
+ = link_to namespace_project_compare_path(project.namespace, project, from: from, to: event.commit_to) do
Compare #{from_label}...#{truncate_sha(event.commit_to)}
- if create_mr
%span{"data-user-is" => event.author_id, "data-display" => "inline"}
or
- = link_to create_mr_path(event.project.default_branch, event.ref_name, event.project) do
+ = link_to create_mr_path(project.default_branch, event.ref_name, project) do
create a merge request
- elsif create_mr
%li.commits-stat{"data-user-is" => event.author_id}
- = link_to create_mr_path(event.project.default_branch, event.ref_name, event.project) do
+ = link_to create_mr_path(project.default_branch, event.ref_name, project) do
Create Merge Request
+- elsif event.rm_ref?
+ - repository = project.repository
+ - last_commit = repository.commit(event.commit_from)
+ - if last_commit
+ .event-body
+ %ul.well-list.event_commits
+ = render "events/commit", commit: last_commit, project: project, event: event
+
diff --git a/app/views/groups/show.html.haml b/app/views/groups/show.html.haml
index aecefbc6e8f..69f634e75b9 100644
--- a/app/views/groups/show.html.haml
+++ b/app/views/groups/show.html.haml
@@ -5,7 +5,7 @@
= auto_discovery_link_tag(:atom, group_url(@group, format: :atom, private_token: current_user.private_token), title: "#{@group.name} activity")
.cover-block.groups-cover-block
- %div{ class: (container_class) }
+ %div{ class: container_class }
= link_to group_icon(@group), target: '_blank' do
= image_tag group_icon(@group), class: "avatar group-avatar s70"
.group-info
@@ -15,12 +15,17 @@
%span.visibility-icon.has-tooltip{ data: { container: 'body' }, title: visibility_icon_description(@group) }
= visibility_level_icon(@group.visibility_level, fw: false)
+ %span.hidden-xs
+ = render 'shared/notifications/button', notification_setting: @notification_setting
+
+ - if current_user
+ .pull-right
+ = render 'shared/members/access_request_buttons', source: @group
+
- if @group.description.present?
.cover-desc.description
= markdown(@group.description, pipeline: :description)
- - if current_user
- = render 'shared/members/access_request_buttons', source: @group
%div{ class: container_class }
.top-area
diff --git a/app/views/help/index.html.haml b/app/views/help/index.html.haml
index 57bc91ea5a9..57601ae9be0 100644
--- a/app/views/help/index.html.haml
+++ b/app/views/help/index.html.haml
@@ -36,6 +36,6 @@
%ul.well-list
%li= link_to 'See our website for getting help', promo_url + '/getting-help/'
%li= link_to 'Use the search bar on the top of this page', '#', onclick: 'Shortcuts.focusSearch(event)'
- %li= link_to 'Use shortcuts', '#', onclick: 'Shortcuts.showHelp(event)'
+ %li= link_to 'Use shortcuts', '#', onclick: 'Shortcuts.toggleHelp()'
%li= link_to 'Get a support subscription', 'https://about.gitlab.com/pricing/'
%li= link_to 'Compare GitLab editions', 'https://about.gitlab.com/features/#compare'
diff --git a/app/views/import/github/new.html.haml b/app/views/import/github/new.html.haml
new file mode 100644
index 00000000000..435ed7bd4cb
--- /dev/null
+++ b/app/views/import/github/new.html.haml
@@ -0,0 +1,43 @@
+- page_title "GitHub Import"
+- header_title "Projects", root_path
+
+%h3.page-title
+ = icon 'github', text: 'Import Projects from GitHub'
+
+- if github_import_configured?
+ %p
+ To import a GitHub project, you first need to authorize GitLab to access
+ the list of your GitHub repositories:
+
+ = link_to 'List Your GitHub Repositories', status_import_github_path, class: 'btn btn-success'
+
+ %hr
+
+%p
+ - if github_import_configured?
+ Alternatively,
+ - else
+ To import a GitHub project,
+ you can use a
+ = succeed '.' do
+ = link_to 'Personal Access Token', 'https://github.com/settings/tokens'
+ When you create your Personal Access Token,
+ you will need to select the <code>repo</code> scope, so we can display a
+ list of your public and private repositories which are available for import.
+
+= form_tag personal_access_token_import_github_path, method: :post, class: 'form-inline' do
+ .form-group
+ = text_field_tag :personal_access_token, '', class: 'form-control', placeholder: "Personal Access Token", size: 40
+ = submit_tag 'List Your GitHub Repositories', class: 'btn btn-success'
+
+- unless github_import_configured?
+ %hr
+ %p
+ Note:
+ - if current_user.admin?
+ As an administrator you may like to configure
+ - else
+ Consider asking your GitLab administrator to configure
+ = link_to 'GitHub integration', help_page_path("integration", "github")
+ which will allow login via GitHub and allow importing projects without
+ generating a Personal Access Token.
diff --git a/app/views/layouts/header/_default.html.haml b/app/views/layouts/header/_default.html.haml
index 40a2c81eebd..1a39572ac3c 100644
--- a/app/views/layouts/header/_default.html.haml
+++ b/app/views/layouts/header/_default.html.haml
@@ -6,7 +6,7 @@
= icon('bars')
%button.navbar-toggle{type: 'button'}
%span.sr-only Toggle navigation
- = icon('angle-left')
+ = icon('ellipsis-v')
.navbar-collapse.collapse
%ul.nav.navbar-nav
diff --git a/app/views/layouts/nav/_admin.html.haml b/app/views/layouts/nav/_admin.html.haml
index 0f264cd2e06..5ee8772882e 100644
--- a/app/views/layouts/nav/_admin.html.haml
+++ b/app/views/layouts/nav/_admin.html.haml
@@ -1,16 +1,16 @@
.scrolling-tabs-container{ class: nav_control_class }
= render 'layouts/nav/admin_settings'
.fade-left
- = icon('arrow-left')
+ = icon('angle-left')
.fade-right
- = icon('arrow-right')
+ = icon('angle-right')
%ul.nav-links.scrolling-tabs
= nav_link(controller: %w(dashboard admin projects users groups builds runners), html_options: {class: 'home'}) do
= link_to admin_root_path, title: 'Overview', class: 'shortcuts-tree' do
%span
Overview
- = nav_link(controller: %w(background_jobs logs health_check)) do
- = link_to admin_background_jobs_path, title: 'Monitoring' do
+ = nav_link(controller: %w(system_info background_jobs logs health_check)) do
+ = link_to admin_system_info_path, title: 'Monitoring' do
%span
Monitoring
= nav_link(controller: :broadcast_messages) do
diff --git a/app/views/layouts/nav/_group.html.haml b/app/views/layouts/nav/_group.html.haml
index 5d657a9ac84..d7d36c84b6c 100644
--- a/app/views/layouts/nav/_group.html.haml
+++ b/app/views/layouts/nav/_group.html.haml
@@ -1,9 +1,9 @@
.scrolling-tabs-container{ class: nav_control_class }
= render 'layouts/nav/group_settings'
.fade-left
- = icon('arrow-left')
+ = icon('angle-left')
.fade-right
- = icon('arrow-right')
+ = icon('angle-right')
%ul.nav-links.scrolling-tabs
= nav_link(path: 'groups#show', html_options: {class: 'home'}) do
= link_to group_path(@group), title: 'Home' do
diff --git a/app/views/layouts/nav/_profile.html.haml b/app/views/layouts/nav/_profile.html.haml
index f37f9b0f5a3..96fe62c39c3 100644
--- a/app/views/layouts/nav/_profile.html.haml
+++ b/app/views/layouts/nav/_profile.html.haml
@@ -1,8 +1,8 @@
.scrolling-tabs-container
.fade-left
- = icon('arrow-left')
+ = icon('angle-left')
.fade-right
- = icon('arrow-right')
+ = icon('angle-right')
%ul.nav-links.scrolling-tabs
= nav_link(path: 'profiles#show', html_options: {class: 'home'}) do
= link_to profile_path, title: 'Profile Settings' do
diff --git a/app/views/layouts/nav/_project.html.haml b/app/views/layouts/nav/_project.html.haml
index a4bb56aa56f..dcef427cda3 100644
--- a/app/views/layouts/nav/_project.html.haml
+++ b/app/views/layouts/nav/_project.html.haml
@@ -26,9 +26,9 @@
.scrolling-tabs-container{ class: nav_control_class }
.fade-left
- = icon('arrow-left')
+ = icon('angle-left')
.fade-right
- = icon('arrow-right')
+ = icon('angle-right')
%ul.nav-links.scrolling-tabs
= nav_link(path: 'projects#show', html_options: {class: 'home'}) do
= link_to project_path(@project), title: 'Project', class: 'shortcuts-project' do
diff --git a/app/views/projects/_github_import_modal.html.haml b/app/views/projects/_github_import_modal.html.haml
deleted file mode 100644
index 46ad1559356..00000000000
--- a/app/views/projects/_github_import_modal.html.haml
+++ /dev/null
@@ -1,13 +0,0 @@
-%div#github_import_modal.modal
- .modal-dialog
- .modal-content
- .modal-header
- %a.close{href: "#", "data-dismiss" => "modal"} ×
- %h3 Import projects from GitHub
- .modal-body
- To enable importing projects from GitHub,
- - if current_user.admin?
- as administrator you need to configure
- - else
- ask your Gitlab administrator to configure
- == #{link_to 'OAuth integration', help_page_path("integration", "github")}.
diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml
index 86ea08dd229..8ce23379fb4 100644
--- a/app/views/projects/_home_panel.html.haml
+++ b/app/views/projects/_home_panel.html.haml
@@ -1,6 +1,6 @@
- empty_repo = @project.empty_repo?
.project-home-panel.cover-block.clearfix{:class => ("empty-project" if empty_repo)}
- %div{ class: (container_class) }
+ %div{ class: container_class }
.row
.project-image-container
= project_icon(@project, alt: '', class: 'project-avatar avatar s70')
diff --git a/app/views/projects/_last_push.html.haml b/app/views/projects/_last_push.html.haml
index e0ca2a3109c..434d8644b83 100644
--- a/app/views/projects/_last_push.html.haml
+++ b/app/views/projects/_last_push.html.haml
@@ -1,7 +1,7 @@
- if event = last_push_event
- if show_last_push_widget?(event)
.row-content-block.top-block.clear-block.hidden-xs
- %div{ class: (container_class) }
+ %div{ class: container_class }
.event-last-push
.event-last-push-text
%span You pushed to
diff --git a/app/views/projects/_md_preview.html.haml b/app/views/projects/_md_preview.html.haml
index ca6714ef42b..58d961d93ca 100644
--- a/app/views/projects/_md_preview.html.haml
+++ b/app/views/projects/_md_preview.html.haml
@@ -12,13 +12,13 @@
%li.confidential-issue-warning
= icon('warning')
%span This is a confidential issue. Your comment will not be visible to the public.
-
+
%li.pull-right
.toolbar-group
= markdown_toolbar_button({icon: "bold fw", data: { "md-tag" => "**" }, title: "Add bold text" })
= markdown_toolbar_button({icon: "italic fw", data: { "md-tag" => "*" }, title: "Add italic text" })
= markdown_toolbar_button({icon: "quote-right fw", data: { "md-tag" => "> ", "md-prepend" => true }, title: "Insert a quote" })
- = markdown_toolbar_button({icon: "code fw", data: { "md-tag" => "`" }, title: "Insert code" })
+ = markdown_toolbar_button({icon: "code fw", data: { "md-tag" => "`", "md-block" => "```" }, title: "Insert code" })
= markdown_toolbar_button({icon: "list-ul fw", data: { "md-tag" => "* ", "md-prepend" => true }, title: "Add a bullet list" })
= markdown_toolbar_button({icon: "list-ol fw", data: { "md-tag" => "1. ", "md-prepend" => true }, title: "Add a numbered list" })
= markdown_toolbar_button({icon: "check-square-o fw", data: { "md-tag" => "* [ ] ", "md-prepend" => true }, title: "Add a task list" })
diff --git a/app/views/projects/blob/_text.html.haml b/app/views/projects/blob/_text.html.haml
index b1769759dce..58524418a67 100644
--- a/app/views/projects/blob/_text.html.haml
+++ b/app/views/projects/blob/_text.html.haml
@@ -16,4 +16,4 @@
.file-content.code
.nothing-here-block Empty file
- else
- = render 'shared/file_highlight', blob: blob
+ = render 'shared/file_highlight', blob: blob, repository: @repository
diff --git a/app/views/projects/blob/show.html.haml b/app/views/projects/blob/show.html.haml
index ed670dae88d..0ab78a39cf9 100644
--- a/app/views/projects/blob/show.html.haml
+++ b/app/views/projects/blob/show.html.haml
@@ -1,12 +1,15 @@
+- @no_container = true
- page_title @blob.path, @ref
+= render "projects/commits/head"
-= render 'projects/last_push'
+%div{ class: container_class }
+ = render 'projects/last_push'
-%div#tree-holder.tree-holder
- = render 'blob', blob: @blob
+ %div#tree-holder.tree-holder
+ = render 'blob', blob: @blob
-- if can_edit_blob?(@blob)
- = render 'projects/blob/remove'
+ - if can_edit_blob?(@blob)
+ = render 'projects/blob/remove'
- - title = "Replace #{@blob.name}"
- = render 'projects/blob/upload', title: title, placeholder: title, button_title: 'Replace file', form_path: namespace_project_update_blob_path(@project.namespace, @project, @id), method: :put
+ - title = "Replace #{@blob.name}"
+ = render 'projects/blob/upload', title: title, placeholder: title, button_title: 'Replace file', form_path: namespace_project_update_blob_path(@project.namespace, @project, @id), method: :put
diff --git a/app/views/projects/branches/index.html.haml b/app/views/projects/branches/index.html.haml
index e0367c40272..77b405f1f39 100644
--- a/app/views/projects/branches/index.html.haml
+++ b/app/views/projects/branches/index.html.haml
@@ -2,7 +2,7 @@
- page_title "Branches"
= render "projects/commits/head"
-%div{ class: (container_class) }
+%div{ class: container_class }
.top-area
.nav-text
Protected branches can be managed in project settings
@@ -27,7 +27,7 @@
= sort_title_recently_updated
= link_to namespace_project_branches_path(sort: 'last_updated') do
= sort_title_oldest_updated
- - unless @branches.empty?
+ - if @branches.any?
%ul.content-list.all-branches
- @branches.each do |branch|
= render "projects/branches/branch", branch: branch
diff --git a/app/views/projects/builds/index.html.haml b/app/views/projects/builds/index.html.haml
index 181547316aa..a131289ee97 100644
--- a/app/views/projects/builds/index.html.haml
+++ b/app/views/projects/builds/index.html.haml
@@ -2,7 +2,7 @@
- page_title "Builds"
= render "projects/pipelines/head"
-%div{ class: (container_class) }
+%div{ class: container_class }
.top-area
%ul.nav-links
%li{class: ('active' if @scope.nil?)}
diff --git a/app/views/projects/builds/show.html.haml b/app/views/projects/builds/show.html.haml
index 4e2702c2e44..d1c468c4692 100644
--- a/app/views/projects/builds/show.html.haml
+++ b/app/views/projects/builds/show.html.haml
@@ -67,4 +67,4 @@
= render "sidebar"
:javascript
- new CiBuild("#{namespace_project_build_url(@project.namespace, @project, @build)}", "#{@build.status}", "#{trace_with_state[:state]}")
+ new CiBuild("#{namespace_project_build_url(@project.namespace, @project, @build, :json)}", "#{@build.status}", "#{trace_with_state[:state]}")
diff --git a/app/views/projects/commits/_head.html.haml b/app/views/projects/commits/_head.html.haml
index b11b6c24ccd..61152649907 100644
--- a/app/views/projects/commits/_head.html.haml
+++ b/app/views/projects/commits/_head.html.haml
@@ -1,8 +1,8 @@
.scrolling-tabs-container.sub-nav-scroll
.fade-left
- = icon('arrow-left')
+ = icon('angle-left')
.fade-right
- = icon('arrow-right')
+ = icon('angle-right')
.nav-links.sub-nav.scrolling-tabs
%ul{ class: (container_class) }
= nav_link(controller: %w(tree blob blame edit_tree new_tree find_file)) do
diff --git a/app/views/projects/commits/show.html.haml b/app/views/projects/commits/show.html.haml
index 51ca4eb903e..9a44ba94970 100644
--- a/app/views/projects/commits/show.html.haml
+++ b/app/views/projects/commits/show.html.haml
@@ -7,7 +7,7 @@
= render "head"
-%div{ class: (container_class) }
+%div{ class: container_class }
.row-content-block.second-block.content-component-block
.tree-ref-holder
= render 'shared/ref_switcher', destination: 'commits'
diff --git a/app/views/projects/compare/index.html.haml b/app/views/projects/compare/index.html.haml
index b22285c11e0..e9ff8e90dd5 100644
--- a/app/views/projects/compare/index.html.haml
+++ b/app/views/projects/compare/index.html.haml
@@ -2,7 +2,7 @@
- page_title "Compare"
= render "projects/commits/head"
-%div{ class: (container_class) }
+%div{ class: container_class }
.sub-header-block
Compare branches, tags or commit ranges.
%br
diff --git a/app/views/projects/compare/show.html.haml b/app/views/projects/compare/show.html.haml
index f4ec7b767f6..28a50e7031a 100644
--- a/app/views/projects/compare/show.html.haml
+++ b/app/views/projects/compare/show.html.haml
@@ -2,7 +2,7 @@
- page_title "#{params[:from]}...#{params[:to]}"
= render "projects/commits/head"
-%div{ class: (container_class) }
+%div{ class: container_class }
.sub-header-block.no-bottom-space
= render "form"
diff --git a/app/views/projects/environments/index.html.haml b/app/views/projects/environments/index.html.haml
index a03f117291f..5242021243e 100644
--- a/app/views/projects/environments/index.html.haml
+++ b/app/views/projects/environments/index.html.haml
@@ -2,7 +2,7 @@
- page_title "Environments"
= render "projects/pipelines/head"
-%div{ class: (container_class) }
+%div{ class: container_class }
- if can?(current_user, :create_environment, @project) && !@environments.blank?
.top-area
.nav-controls
diff --git a/app/views/projects/environments/show.html.haml b/app/views/projects/environments/show.html.haml
index 4c15e2759d6..53c62ef234d 100644
--- a/app/views/projects/environments/show.html.haml
+++ b/app/views/projects/environments/show.html.haml
@@ -2,7 +2,7 @@
- page_title "Environments"
= render "projects/pipelines/head"
-%div{ class: (container_class) }
+%div{ class: container_class }
.top-area
.col-md-9
%h3.page-title= @environment.name.titleize
diff --git a/app/views/projects/graphs/ci.html.haml b/app/views/projects/graphs/ci.html.haml
index e695d3ae369..6be4273b6ab 100644
--- a/app/views/projects/graphs/ci.html.haml
+++ b/app/views/projects/graphs/ci.html.haml
@@ -2,7 +2,7 @@
- page_title "Continuous Integration", "Graphs"
= render 'head'
-%div{ class: (container_class) }
+%div{ class: container_class }
.sub-header-block
.oneline
A collection of graphs for Continuous Integration
diff --git a/app/views/projects/graphs/commits.html.haml b/app/views/projects/graphs/commits.html.haml
index 0daffe68f6f..65db8af494d 100644
--- a/app/views/projects/graphs/commits.html.haml
+++ b/app/views/projects/graphs/commits.html.haml
@@ -2,7 +2,7 @@
- page_title "Commits", "Graphs"
= render 'head'
-%div{ class: (container_class) }
+%div{ class: container_class }
.sub-header-block
.tree-ref-holder
= render 'shared/ref_switcher', destination: 'graphs_commits'
diff --git a/app/views/projects/graphs/languages.html.haml b/app/views/projects/graphs/languages.html.haml
index 6d97f552a8e..fcfcae0be20 100644
--- a/app/views/projects/graphs/languages.html.haml
+++ b/app/views/projects/graphs/languages.html.haml
@@ -2,7 +2,7 @@
- page_title "Languages", "Graphs"
= render 'head'
-%div{ class: (container_class) }
+%div{ class: container_class }
.sub-header-block
.oneline
Programming languages used in this repository
diff --git a/app/views/projects/graphs/show.html.haml b/app/views/projects/graphs/show.html.haml
index 9f7e2a361ff..a985b442b2d 100644
--- a/app/views/projects/graphs/show.html.haml
+++ b/app/views/projects/graphs/show.html.haml
@@ -2,7 +2,7 @@
- page_title "Contributors", "Graphs"
= render 'head'
-%div{ class: (container_class) }
+%div{ class: container_class }
.sub-header-block
.tree-ref-holder
= render 'shared/ref_switcher', destination: 'graphs'
diff --git a/app/views/projects/imports/new.html.haml b/app/views/projects/imports/new.html.haml
index a8a8caf7280..2cd8d03e30e 100644
--- a/app/views/projects/imports/new.html.haml
+++ b/app/views/projects/imports/new.html.haml
@@ -10,7 +10,7 @@
.panel-body
%pre
:preserve
- #{sanitize_repo_path(@project.import_error)}
+ #{sanitize_repo_path(@project, @project.import_error)}
= form_for @project, url: namespace_project_import_path(@project.namespace, @project), method: :post, html: { class: 'form-horizontal' } do |f|
= render "shared/import_form", f: f
diff --git a/app/views/projects/issues/index.html.haml b/app/views/projects/issues/index.html.haml
index cd876b5ea62..7ce4c1e5555 100644
--- a/app/views/projects/issues/index.html.haml
+++ b/app/views/projects/issues/index.html.haml
@@ -6,7 +6,7 @@
- if current_user
= auto_discovery_link_tag(:atom, namespace_project_issues_url(@project.namespace, @project, :atom, private_token: current_user.private_token), title: "#{@project.name} issues")
-%div{ class: (container_class) }
+%div{ class: container_class }
.top-area
= render 'shared/issuable/nav', type: :issues
.nav-controls
diff --git a/app/views/projects/labels/index.html.haml b/app/views/projects/labels/index.html.haml
index aa4d69550ec..db66a0edbd8 100644
--- a/app/views/projects/labels/index.html.haml
+++ b/app/views/projects/labels/index.html.haml
@@ -3,7 +3,7 @@
- hide_class = ''
= render "projects/issues/head"
-%div{ class: (container_class) }
+%div{ class: container_class }
.top-area.adjust
.nav-text
Labels can be applied to issues and merge requests. Star a label to make it a priority label. Order the prioritized labels to change their relative priority, by dragging.
diff --git a/app/views/projects/merge_requests/index.html.haml b/app/views/projects/merge_requests/index.html.haml
index 9f948d41dda..ace275c689b 100644
--- a/app/views/projects/merge_requests/index.html.haml
+++ b/app/views/projects/merge_requests/index.html.haml
@@ -3,7 +3,7 @@
= render "projects/issues/head"
= render 'projects/last_push'
-%div{ class: (container_class) }
+%div{ class: container_class }
.top-area
= render 'shared/issuable/nav', type: :merge_requests
.nav-controls
diff --git a/app/views/projects/milestones/index.html.haml b/app/views/projects/milestones/index.html.haml
index b0e0bdfff5a..ad2bfbec915 100644
--- a/app/views/projects/milestones/index.html.haml
+++ b/app/views/projects/milestones/index.html.haml
@@ -2,7 +2,7 @@
- page_title "Milestones"
= render "projects/issues/head"
-%div{ class: (container_class) }
+%div{ class: container_class }
.top-area
= render 'shared/milestones_filter'
diff --git a/app/views/projects/network/_head.html.haml b/app/views/projects/network/_head.html.haml
index 86295a3d011..8f6805268d5 100644
--- a/app/views/projects/network/_head.html.haml
+++ b/app/views/projects/network/_head.html.haml
@@ -1,6 +1,6 @@
- @no_container = true
-%div{ class: (container_class) }
+%div{ class: container_class }
.row-content-block.second-block.content-component-block
.tree-ref-holder
= render partial: 'shared/ref_switcher', locals: {destination: 'graph'}
diff --git a/app/views/projects/network/show.html.haml b/app/views/projects/network/show.html.haml
index 3ca30b4ba6b..091af4df4a1 100644
--- a/app/views/projects/network/show.html.haml
+++ b/app/views/projects/network/show.html.haml
@@ -4,7 +4,7 @@
= page_specific_javascript_tag('network/application.js')
= render "projects/commits/head"
= render "head"
-%div{ class: (container_class) }
+%div{ class: container_class }
.project-network
.controls
= form_tag namespace_project_network_path(@project.namespace, @project, @id), method: :get, class: 'form-inline network-form' do |f|
diff --git a/app/views/projects/new.html.haml b/app/views/projects/new.html.haml
index 3c1c6060504..05f33b78a47 100644
--- a/app/views/projects/new.html.haml
+++ b/app/views/projects/new.html.haml
@@ -1,110 +1,115 @@
- page_title 'New Project'
- header_title "Projects", dashboard_projects_path
-%h3.page-title
- New Project
-%hr
-
.project-edit-container
.project-edit-errors
= render 'projects/errors'
- .project-edit-content
-
- = form_for @project, html: { class: 'new_project form-horizontal js-requires-input' } do |f|
- .form-group
- = f.label :path, class: 'control-label' do
- Project owner
- .col-sm-10
- = f.select :namespace_id, namespaces_options(:current_user), {}, {class: 'select2 js-select-namespace', tabindex: 1}
-
- - if current_user.can_create_group?
- .help-block
- Want to house several dependent projects under the same namespace?
- = link_to "Create a group", new_group_path
-
- .form-group
- = f.label :path, class: 'control-label' do
- Project name
- .col-sm-10
- = f.text_field :path, placeholder: "my-awesome-project", class: "form-control", tabindex: 2, autofocus: true, required: true
-
- - if import_sources_enabled?
- .project-import.js-toggle-container
- .form-group
- %label.control-label Import project from
- .col-sm-10
- - if github_import_enabled?
- - if github_import_configured?
- = link_to status_import_github_path, class: 'btn import_github' do
- %i.fa.fa-github
- GitHub
- - else
- = link_to '#', class: 'how_to_import_link btn import_github' do
- %i.fa.fa-github
- GitHub
- = render 'github_import_modal'
+ .row.prepend-top-default
+ .col-lg-3.profile-settings-sidebar
+ %h4.prepend-top-0
+ New project
+ %p
+ Create or Import your project from popular Git services
+ .col-lg-9
+ = form_for @project, html: { class: 'new_project' } do |f|
+ %fieldset.append-bottom-0
+ .form-group.col-xs-12.col-sm-6
+ = f.label :namespace_id, class: 'label-light' do
+ %span
+ Project path
+ .form-group
+ .input-group
+ - if current_user.can_select_namespace?
+ .input-group-addon
+ = root_url
+ = f.select :namespace_id, namespaces_options(params[:namespace_id] || :current_user, display_path: true), {}, {class: 'select2 js-select-namespace', tabindex: 1}
- - 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
- = render 'bitbucket_import_modal'
-
- - 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
- = render 'gitlab_import_modal'
-
- - if gitorious_import_enabled?
- = link_to new_import_gitorious_path, class: 'btn import_gitorious' do
- %i.icon-gitorious.icon-gitorious-small
- Gitorious.org
-
- - if google_code_import_enabled?
- = link_to new_import_google_code_path, class: 'btn import_google_code' do
- %i.fa.fa-google
- Google Code
-
- - if fogbugz_import_enabled?
- = link_to new_import_fogbugz_path, class: 'btn import_fogbugz' do
- %i.fa.fa-bug
- Fogbugz
-
- - if git_import_enabled?
- = link_to "#", class: 'btn js-toggle-button import_git' do
- %i.fa.fa-git
- %span Repo by URL
-
- - if gitlab_project_import_enabled?
- = link_to new_import_gitlab_project_path, class: 'btn import_gitlab_project project-submit' do
- %i.fa.fa-gitlab
- %span GitLab export
-
- .js-toggle-content.hide
- = render "shared/import_form", f: f
-
- .prepend-botton-10
-
- .form-group
- = f.label :description, class: 'control-label' do
- Description
- %span.light (optional)
- .col-sm-10
- = f.text_area :description, class: "form-control", rows: 3, maxlength: 250, tabindex: 3
- = render 'shared/visibility_level', f: f, visibility_level: default_project_visibility, can_change_visibility_level: true, form_model: @project
+ .input-group-addon.static-namespace
+ #{root_url}#{current_user.username}/
+ .form-group.col-xs-12.col-sm-6.project-path
+ = f.label :namespace_id, class: 'label-light' do
+ %span
+ Project name
+ = f.text_field :path, placeholder: "my-awesome-project", class: "form-control", tabindex: 2, autofocus: true, required: true
+ - if current_user.can_create_group?
+ .help-block
+ Want to house several dependent projects under the same namespace?
+ = link_to "Create a group", new_group_path
+
+ - if import_sources_enabled?
+ .project-import.js-toggle-container
+ .form-group.clearfix
+ = f.label :visibility_level, class: 'label-light' do
+ Import project from
+ .col-sm-12.import-buttons
+ %div
+ - if github_import_enabled?
+ = link_to new_import_github_path, class: 'btn import_github' do
+ = 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
+ = 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
+ = render 'gitlab_import_modal'
+ %div
+ - if gitorious_import_enabled?
+ = link_to new_import_gitorious_path, class: 'btn import_gitorious' do
+ %i.icon-gitorious.icon-gitorious-small
+ Gitorious.org
+ %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
+ %div
+ - if fogbugz_import_enabled?
+ = link_to new_import_fogbugz_path, class: 'btn import_fogbugz' do
+ %i.fa.fa-bug
+ Fogbugz
+ %div
+ - if git_import_enabled?
+ = link_to "#", class: 'btn js-toggle-button import_git' do
+ %i.fa.fa-git
+ %span Repo by URL
+ %div
+ - if gitlab_project_import_enabled?
+ = link_to new_import_gitlab_project_path, class: 'btn import_gitlab_project project-submit' do
+ %i.fa.fa-gitlab
+ %span GitLab export
+
+ .js-toggle-content.hide
+ = render "shared/import_form", f: f
+
+ .form-group
+ = f.label :description, class: 'label-light' do
+ Project description
+ %span.light (optional)
+ = f.text_area :description, placeholder: 'Description format', class: "form-control", rows: 3, maxlength: 250
+
+ .form-group.project-visibility-level-holder
+ = f.label :visibility_level, class: 'label-light' do
+ Visibility Level
+ = link_to "(?)", help_page_path("public_access", "public_access")
+ = render('shared/visibility_radios', model_method: :visibility_level, form: f, selected_level: @project.visibility_level, form_model: @project)
- .form-actions
= f.submit 'Create project', class: "btn btn-create project-submit", tabindex: 4
= link_to 'Cancel', dashboard_projects_path, class: 'btn btn-cancel'
diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml
index a5e163b91e9..af0046886fb 100644
--- a/app/views/projects/notes/_note.html.haml
+++ b/app/views/projects/notes/_note.html.haml
@@ -17,7 +17,7 @@
%a{ href: "##{dom_id(note)}" }
= time_ago_with_tooltip(note.created_at, placement: 'bottom', html_class: 'note-created-ago')
.note-actions
- - access = note.project.team.human_max_access(note.author.id)
+ - access = note_max_access_for_user(note)
- if access and not note.system
%span.note-role.hidden-xs= access
- if current_user and not note.system
diff --git a/app/views/projects/pipelines/index.html.haml b/app/views/projects/pipelines/index.html.haml
index b70693eeb62..28b475d5c2f 100644
--- a/app/views/projects/pipelines/index.html.haml
+++ b/app/views/projects/pipelines/index.html.haml
@@ -2,7 +2,7 @@
- page_title "Pipelines"
= render "projects/pipelines/head"
-%div{ class: (container_class) }
+%div{ class: container_class }
.top-area
%ul.nav-links
%li{class: ('active' if @scope.nil?)}
diff --git a/app/views/projects/show.html.haml b/app/views/projects/show.html.haml
index 15f0d85194b..f6e81af2638 100644
--- a/app/views/projects/show.html.haml
+++ b/app/views/projects/show.html.haml
@@ -13,7 +13,7 @@
= render "home_panel"
.project-stats.row-content-block.second-block
- %div{ class: (container_class) }
+ %div{ class: container_class }
%ul.nav
%li
= link_to project_files_path(@project) do
diff --git a/app/views/projects/tags/index.html.haml b/app/views/projects/tags/index.html.haml
index 4ca1f58ac5c..c375bb6dd1b 100644
--- a/app/views/projects/tags/index.html.haml
+++ b/app/views/projects/tags/index.html.haml
@@ -2,7 +2,7 @@
- page_title "Tags"
= render "projects/commits/head"
-%div{ class: (container_class) }
+%div{ class: container_class }
.top-area
.nav-text
Tags give the ability to mark specific points in history as being important
@@ -25,7 +25,7 @@
= sort_title_oldest_updated
.tags
- - unless @tags.empty?
+ - if @tags.any?
%ul.content-list
= render partial: 'tag', collection: @tags
diff --git a/app/views/projects/tree/show.html.haml b/app/views/projects/tree/show.html.haml
index 2abcfcdd7b2..bf5360b4dee 100644
--- a/app/views/projects/tree/show.html.haml
+++ b/app/views/projects/tree/show.html.haml
@@ -7,7 +7,7 @@
= render 'projects/last_push'
= render "projects/commits/head"
-%div{ class: (container_class) }
+%div{ class: container_class }
.tree-controls
= render 'projects/find_file_link'
- if can? current_user, :download_code, @project
diff --git a/app/views/projects/wikis/_new.html.haml b/app/views/projects/wikis/_new.html.haml
index 4f8abcdc8e1..c32cb122c26 100644
--- a/app/views/projects/wikis/_new.html.haml
+++ b/app/views/projects/wikis/_new.html.haml
@@ -1,6 +1,6 @@
- @no_container = true
-%div{ class: (container_class) }
+%div{ class: container_class }
%div#modal-new-wiki.modal
.modal-dialog
.modal-content
diff --git a/app/views/projects/wikis/edit.html.haml b/app/views/projects/wikis/edit.html.haml
index 817bf9b3f69..233538bb488 100644
--- a/app/views/projects/wikis/edit.html.haml
+++ b/app/views/projects/wikis/edit.html.haml
@@ -2,7 +2,7 @@
- page_title "Edit", @page.title.capitalize, "Wiki"
= render 'nav'
-%div{ class: (container_class) }
+%div{ class: container_class }
.top-area
.nav-text
%strong
diff --git a/app/views/projects/wikis/git_access.html.haml b/app/views/projects/wikis/git_access.html.haml
index 6caf7230f35..b8811a28dd6 100644
--- a/app/views/projects/wikis/git_access.html.haml
+++ b/app/views/projects/wikis/git_access.html.haml
@@ -2,7 +2,7 @@
- page_title "Git Access", "Wiki"
= render 'nav'
-%div{ class: (container_class) }
+%div{ class: container_class }
.sub-header-block
%span.oneline
Git access for
diff --git a/app/views/projects/wikis/history.html.haml b/app/views/projects/wikis/history.html.haml
index 630ee35b70b..4c0b14e2c42 100644
--- a/app/views/projects/wikis/history.html.haml
+++ b/app/views/projects/wikis/history.html.haml
@@ -1,6 +1,6 @@
- page_title "History", @page.title.capitalize, "Wiki"
= render 'nav'
-%div{ class: (container_class) }
+%div{ class: container_class }
.top-area
.nav-text
%strong
diff --git a/app/views/projects/wikis/pages.html.haml b/app/views/projects/wikis/pages.html.haml
index 81d9f391c1c..9c10acd4cb6 100644
--- a/app/views/projects/wikis/pages.html.haml
+++ b/app/views/projects/wikis/pages.html.haml
@@ -3,7 +3,7 @@
= render 'nav'
-%div{ class: (container_class) }
+%div{ class: container_class }
%ul.content-list
- @wiki_pages.each do |wiki_page|
%li
diff --git a/app/views/projects/wikis/show.html.haml b/app/views/projects/wikis/show.html.haml
index 76f9b1ecd76..5cebb538cf5 100644
--- a/app/views/projects/wikis/show.html.haml
+++ b/app/views/projects/wikis/show.html.haml
@@ -2,7 +2,7 @@
- page_title @page.title.capitalize, "Wiki"
= render 'nav'
-%div{ class: (container_class) }
+%div{ class: container_class }
.top-area
.nav-text
%strong= @page.title.capitalize
diff --git a/app/views/shared/_file_highlight.html.haml b/app/views/shared/_file_highlight.html.haml
index ad944a19ca1..e26693bf5b9 100644
--- a/app/views/shared/_file_highlight.html.haml
+++ b/app/views/shared/_file_highlight.html.haml
@@ -1,3 +1,5 @@
+- repository = nil unless local_assigns.key?(:repository)
+
.file-content.code.js-syntax-highlight
.line-numbers
- if blob.data.present?
@@ -11,4 +13,4 @@
= link_icon
= i
.blob-content{data: {blob_id: blob.id}}
- = highlight(blob.name, blob.data, plain: blob.no_highlighting?)
+ = highlight(blob.path, blob.data, repository: repository, plain: blob.no_highlighting?)
diff --git a/app/views/shared/_labels_row.html.haml b/app/views/shared/_labels_row.html.haml
index 87028ececd4..5507a05f6c1 100644
--- a/app/views/shared/_labels_row.html.haml
+++ b/app/views/shared/_labels_row.html.haml
@@ -1,6 +1,6 @@
- labels.each do |label|
%span.label-row.btn-group{ role: "group", aria: { label: escape_once(label.name) }, style: "color: #{text_color_for_bg(label.color)}" }
- = link_to namespace_project_label_path(@project.namespace, @project, label),
+ = link_to 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),
diff --git a/app/views/users/calendar_activities.html.haml b/app/views/users/calendar_activities.html.haml
index 630d97e339d..f51599212db 100644
--- a/app/views/users/calendar_activities.html.haml
+++ b/app/views/users/calendar_activities.html.haml
@@ -14,7 +14,7 @@
- else
= event_action_name(event)
- if event.target
- %strong= link_to "##{event.target_iid}", [event.project.namespace.becomes(Namespace), event.project, event.target]
+ %strong= link_to "#{event.target.to_reference}", [event.project.namespace.becomes(Namespace), event.project, event.target]
at
%strong
diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb
index f3327ca9e61..09035a7cf2d 100644
--- a/app/workers/post_receive.rb
+++ b/app/workers/post_receive.rb
@@ -4,10 +4,10 @@ class PostReceive
sidekiq_options queue: :post_receive
def perform(repo_path, identifier, changes)
- if repo_path.start_with?(Gitlab.config.gitlab_shell.repos_path.to_s)
- repo_path.gsub!(Gitlab.config.gitlab_shell.repos_path.to_s, "")
+ if path = Gitlab.config.repositories.storages.find { |p| repo_path.start_with?(p[1].to_s) }
+ repo_path.gsub!(path[1].to_s, "")
else
- log("Check gitlab.yml config for correct gitlab_shell.repos_path variable. \"#{Gitlab.config.gitlab_shell.repos_path}\" does not match \"#{repo_path}\"")
+ log("Check gitlab.yml config for correct repositories.storages values. No repository storage path matches \"#{repo_path}\"")
end
post_received = Gitlab::GitPostReceive.new(repo_path, identifier, changes)
diff --git a/app/workers/repository_fork_worker.rb b/app/workers/repository_fork_worker.rb
index d947f105516..f7604e48f83 100644
--- a/app/workers/repository_fork_worker.rb
+++ b/app/workers/repository_fork_worker.rb
@@ -12,7 +12,7 @@ class RepositoryForkWorker
return
end
- result = gitlab_shell.fork_repository(source_path, target_path)
+ result = gitlab_shell.fork_repository(project.repository_storage_path, source_path, target_path)
unless result
logger.error("Unable to fork project #{project_id} for repository #{source_path} -> #{target_path}")
project.mark_import_as_failed('The project could not be forked.')