summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGELOG32
-rw-r--r--GITLAB_SHELL_VERSION2
-rw-r--r--Gemfile.lock2
-rw-r--r--README.md6
-rw-r--r--app/assets/images/msapplication-tile.pngbin6102 -> 5798 bytes
-rw-r--r--app/assets/javascripts/merge_request_widget.js.coffee10
-rw-r--r--app/assets/javascripts/project.js.coffee15
-rw-r--r--app/assets/stylesheets/generic/mobile.scss4
-rw-r--r--app/assets/stylesheets/pages/merge_requests.scss146
-rw-r--r--app/assets/stylesheets/pages/projects.scss11
-rw-r--r--app/controllers/abuse_reports_controller.rb24
-rw-r--r--app/controllers/admin/abuse_reports_controller.rb11
-rw-r--r--app/controllers/admin/users_controller.rb8
-rw-r--r--app/controllers/autocomplete_controller.rb2
-rw-r--r--app/controllers/import/bitbucket_controller.rb1
-rw-r--r--app/controllers/projects/branches_controller.rb7
-rw-r--r--app/controllers/projects/compare_controller.rb9
-rw-r--r--app/controllers/projects/merge_requests_controller.rb12
-rw-r--r--app/controllers/projects/notes_controller.rb7
-rw-r--r--app/helpers/issues_helper.rb15
-rw-r--r--app/helpers/merge_requests_helper.rb10
-rw-r--r--app/helpers/notes_helper.rb15
-rw-r--r--app/helpers/projects_helper.rb4
-rw-r--r--app/models/abuse_report.rb9
-rw-r--r--app/models/concerns/issuable.rb1
-rw-r--r--app/models/group.rb18
-rw-r--r--app/models/key.rb5
-rw-r--r--app/models/merge_request.rb56
-rw-r--r--app/models/merge_request_diff.rb32
-rw-r--r--app/models/namespace.rb8
-rw-r--r--app/models/note.rb3
-rw-r--r--app/models/project.rb14
-rw-r--r--app/models/project_services/ci_service.rb2
-rw-r--r--app/models/project_services/gitlab_ci_service.rb4
-rw-r--r--app/models/repository.rb30
-rw-r--r--app/models/user.rb2
-rw-r--r--app/services/base_service.rb4
-rw-r--r--app/services/compare_service.rb41
-rw-r--r--app/services/files/base_service.rb9
-rw-r--r--app/services/git_push_service.rb10
-rw-r--r--app/services/issues/update_service.rb2
-rw-r--r--app/services/merge_requests/auto_merge_service.rb75
-rw-r--r--app/services/merge_requests/base_merge_service.rb10
-rw-r--r--app/services/merge_requests/build_service.rb14
-rw-r--r--app/services/merge_requests/merge_service.rb61
-rw-r--r--app/services/merge_requests/post_merge_service.rb22
-rw-r--r--app/services/merge_requests/refresh_service.rb4
-rw-r--r--app/services/merge_requests/update_service.rb2
-rw-r--r--app/services/notes/update_service.rb19
-rw-r--r--app/services/notification_service.rb49
-rw-r--r--app/services/post_commit_service.rb8
-rw-r--r--app/services/projects/destroy_service.rb1
-rw-r--r--app/services/projects/transfer_service.rb6
-rw-r--r--app/views/abuse_reports/new.html.haml24
-rw-r--r--app/views/admin/abuse_reports/_abuse_report.html.haml23
-rw-r--r--app/views/admin/abuse_reports/index.html.haml17
-rw-r--r--app/views/admin/users/show.html.haml10
-rw-r--r--app/views/events/_event.html.haml10
-rw-r--r--app/views/events/event/_created_project.html.haml4
-rw-r--r--app/views/events/event/_push.html.haml11
-rw-r--r--app/views/explore/projects/_project.html.haml4
-rw-r--r--app/views/import/bitbucket/status.html.haml33
-rw-r--r--app/views/layouts/_head.html.haml4
-rw-r--r--app/views/layouts/_user_styles.html.haml24
-rw-r--r--app/views/layouts/nav/_admin.html.haml7
-rw-r--r--app/views/projects/_home_panel.html.haml9
-rw-r--r--app/views/projects/buttons/_dropdown.html.haml29
-rw-r--r--app/views/projects/buttons/_fork.html.haml4
-rw-r--r--app/views/projects/buttons/_star.html.haml4
-rw-r--r--app/views/projects/issues/show.html.haml8
-rw-r--r--app/views/projects/merge_requests/_new_compare.html.haml2
-rw-r--r--app/views/projects/merge_requests/_new_submit.html.haml4
-rw-r--r--app/views/projects/merge_requests/_show.html.haml51
-rw-r--r--app/views/projects/merge_requests/merge.js.haml (renamed from app/views/projects/merge_requests/automerge.js.haml)0
-rw-r--r--app/views/projects/merge_requests/show/_commits.html.haml2
-rw-r--r--app/views/projects/merge_requests/show/_diffs.html.haml2
-rw-r--r--app/views/projects/merge_requests/show/_mr_title.html.haml10
-rw-r--r--app/views/projects/merge_requests/widget/_heading.html.haml31
-rw-r--r--app/views/projects/merge_requests/widget/_open.html.haml2
-rw-r--r--app/views/projects/merge_requests/widget/_show.html.haml4
-rw-r--r--app/views/projects/merge_requests/widget/open/_accept.html.haml8
-rw-r--r--app/views/projects/merge_requests/widget/open/_conflicts.html.haml12
-rw-r--r--app/views/projects/merge_requests/widget/open/_no_satellite.html.haml3
-rw-r--r--app/views/projects/notes/_note.html.haml9
-rw-r--r--app/views/projects/notes/discussions/_diff.html.haml15
-rw-r--r--app/views/users/show.html.haml10
-rw-r--r--app/workers/auto_merge_worker.rb13
-rw-r--r--app/workers/merge_worker.rb19
-rw-r--r--app/workers/repository_import_worker.rb1
-rw-r--r--config/routes.rb9
-rw-r--r--db/migrate/20150730122406_add_updated_by_to_issuables_and_notes.rb7
-rw-r--r--db/migrate/20150806104937_create_abuse_reports.rb11
-rw-r--r--db/schema.rb15
-rw-r--r--doc/development/architecture.md6
-rw-r--r--doc/install/installation.md8
-rw-r--r--doc/install/requirements.md6
-rw-r--r--doc/install/structure.md4
-rw-r--r--doc/logs/logs.md12
-rw-r--r--doc/raketasks/backup_restore.md4
-rw-r--r--doc/raketasks/maintenance.md13
-rw-r--r--doc/release/monthly.md1
-rw-r--r--doc/release/patch.md1
-rw-r--r--doc/update/mysql_to_postgresql.md4
-rw-r--r--doc/update/patch_versions.md1
-rw-r--r--doc/workflow/README.md1
-rw-r--r--doc/workflow/merge_requests.md40
-rw-r--r--doc/workflow/notifications.md39
-rw-r--r--features/abuse_report.feature10
-rw-r--r--features/admin/abuse_report.feature8
-rw-r--r--features/steps/abuse_reports.rb28
-rw-r--r--features/steps/admin/abuse_reports.rb15
-rw-r--r--features/steps/admin/groups.rb2
-rw-r--r--features/steps/admin/users.rb2
-rw-r--r--features/steps/dashboard/help.rb2
-rw-r--r--features/steps/dashboard/merge_requests.rb8
-rw-r--r--features/steps/explore/groups.rb2
-rw-r--r--features/steps/invites.rb2
-rw-r--r--features/steps/project/forked_merge_requests.rb6
-rw-r--r--features/steps/project/merge_requests.rb5
-rw-r--r--features/steps/shared/paths.rb4
-rw-r--r--lib/api/merge_requests.rb6
-rw-r--r--lib/api/notes.rb12
-rw-r--r--lib/extracts_path.rb2
-rw-r--r--lib/gitlab.rb1
-rw-r--r--lib/gitlab/backend/shell.rb14
-rw-r--r--lib/gitlab/bitbucket_import/client.rb4
-rw-r--r--lib/gitlab/satellite/action.rb58
-rw-r--r--lib/gitlab/satellite/compare_action.rb44
-rw-r--r--lib/gitlab/satellite/logger.rb13
-rw-r--r--lib/gitlab/satellite/merge_action.rb146
-rw-r--r--lib/gitlab/satellite/satellite.rb148
-rw-r--r--lib/tasks/gitlab/check.rake56
-rw-r--r--lib/tasks/gitlab/enable_automerge.rake39
-rw-r--r--spec/controllers/admin/users_controller_spec.rb14
-rw-r--r--spec/controllers/autocomplete_controller_spec.rb22
-rw-r--r--spec/controllers/branches_controller_spec.rb20
-rw-r--r--spec/controllers/import/bitbucket_controller_spec.rb4
-rw-r--r--spec/controllers/profile_keys_controller_spec.rb11
-rw-r--r--spec/factories.rb2
-rw-r--r--spec/factories/abuse_reports.rb9
-rw-r--r--spec/features/projects_spec.rb4
-rw-r--r--spec/finders/projects_finder_spec.rb2
-rw-r--r--spec/lib/extracts_path_spec.rb10
-rw-r--r--spec/lib/gitlab/markdown/user_reference_filter_spec.rb2
-rw-r--r--spec/lib/gitlab/note_data_builder_spec.rb4
-rw-r--r--spec/lib/gitlab/reference_extractor_spec.rb8
-rw-r--r--spec/lib/gitlab/satellite/action_spec.rb116
-rw-r--r--spec/lib/gitlab/satellite/merge_action_spec.rb104
-rw-r--r--spec/models/abuse_report_spec.rb7
-rw-r--r--spec/models/hooks/system_hook_spec.rb4
-rw-r--r--spec/models/key_spec.rb7
-rw-r--r--spec/models/merge_request_spec.rb2
-rw-r--r--spec/models/note_spec.rb2
-rw-r--r--spec/models/project_services/slack_service_spec.rb2
-rw-r--r--spec/models/project_spec.rb1
-rw-r--r--spec/models/project_team_spec.rb6
-rw-r--r--spec/models/repository_spec.rb4
-rw-r--r--spec/models/user_spec.rb13
-rw-r--r--spec/requests/api/files_spec.rb2
-rw-r--r--spec/requests/api/groups_spec.rb2
-rw-r--r--spec/requests/api/merge_requests_spec.rb26
-rw-r--r--spec/routing/project_routing_spec.rb14
-rw-r--r--spec/services/merge_requests/create_service_spec.rb2
-rw-r--r--spec/services/merge_requests/merge_service_spec.rb5
-rw-r--r--spec/services/notification_service_spec.rb7
-rw-r--r--spec/support/markdown_feature.rb2
-rw-r--r--spec/support/mentionable_shared_examples.rb2
167 files changed, 1114 insertions, 1444 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 3e8c43b1d5c..ebffc0d90ab 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,8 +1,14 @@
Please view this file on the master branch, on stable branches it's out of date.
v 7.14.0 (unreleased)
+ - Show incompatible projects in Bitbucket import status (Stan Hu)
+ - Fix coloring of diffs on MR Discussion-tab (Gert Goet)
+ - Fix "Network" and "Graphs" pages for branches with encoded slashes (Stan Hu)
+ - Fix errors deleting and creating branches with encoded slashes (Stan Hu)
+ - Always add current user to autocomplete controller to support filter by "Me" (Stan Hu)
- Fix multi-line syntax highlighting (Stan Hu)
- Fix network graph when branch name has single quotes (Stan Hu)
+ - Add "Confirm user" button in user admin page (Stan Hu)
- Upgrade gitlab_git to version 7.2.6 to fix Error 500 when creating network graphs (Stan Hu)
- Add support for Unicode filenames in relative links (Hiroyuki Sato)
- Fix URL used for refreshing notes if relative_url is present (Bartłomiej Święcki)
@@ -16,6 +22,7 @@ v 7.14.0 (unreleased)
- Fix OAuth provider bug where GitLab would not go return to the redirect_uri after sign-in (Stan Hu)
- Fix file upload dialog for comment editing (Daniel Gerhardt)
- Set OmniAuth full_host parameter to ensure redirect URIs are correct (Stan Hu)
+ - Return comments in created order in merge request API (Stan Hu)
- Expire Rails cache entries after two weeks to prevent endless Redis growth
- Add support for destroying project milestones (Stan Hu)
- Add fetch command to the MR page.
@@ -24,12 +31,24 @@ v 7.14.0 (unreleased)
- Add project star and fork count, group avatar URL and user/group web URL attributes to API
- Fix bug causing Bitbucket importer to crash when OAuth application had been removed.
- Add fetch command to the MR page.
+ - Show who last edited a comment if it wasn't the original author
+ - Send notification to all participants when MR is merged.
- Add ability to manage user email addresses via the API.
- Show buttons to add license, changelog and contribution guide if they're missing.
+ - Tweak project page buttons.
- Disabled autocapitalize and autocorrect on login field (Daryl Chan)
- Mention group and project name in creation, update and deletion notices (Achilleas Pipinellis)
- Update gravatar link on profile page to link to configured gravatar host (Ben Bodenmiller)
- Remove redis-store TTL monkey patch
+ - Add support for CI skipped status
+ - Fetch code from forks to refs/merge-requests/:id/head when merge request created
+ - Remove satellites
+ - Remove comments and email addresses when publicly exposing ssh keys (Zeger-Jan van de Weg)
+ - Cache all events
+
+v 7.13.3
+ - Fix bug causing Bitbucket importer to crash when OAuth application had been removed.
+ - Allow users to send abuse reports
v 7.13.2
- Fix randomly failed spec
@@ -54,7 +73,6 @@ v 7.13.1
v 7.13.0
- Remove repository graph log to fix slow cache updates after push event (Stan Hu)
- - Return comments in created order in merge request API (Stan Hu)
- Only enable HSTS header for HTTPS and port 443 (Stan Hu)
- Fix user autocomplete for unauthenticated users accessing public projects (Stan Hu)
- Fix redirection to home page URL for unauthorized users (Daniel Gerhardt)
@@ -81,15 +99,15 @@ v 7.13.0
- Update ssl_ciphers in Nginx example to remove DHE settings. This will deny forward secrecy for Android 2.3.7, Java 6 and OpenSSL 0.9.8
- Admin can edit and remove user identities
- Convert CRLF newlines to LF when committing using the web editor.
- - API request /projects/:project_id/merge_requests?state=closed will return only closed merge requests without merged one. If you need ones that were merged - use state=merged.
+ - API request /projects/:project_id/merge_requests?state=closed will return only closed merge requests without merged one. If you need ones that were merged - use state=merged.
- Allow Administrators to filter the user list by those with or without Two-factor Authentication enabled.
- Show a user's Two-factor Authentication status in the administration area.
- Explicit error when commit not found in the CI
- - Improve performance for issue and merge request pages
+ - Improve performance for issue and merge request pages
- Users with guest access level can not set assignee, labels or milestones for issue and merge request
- Reporter role can manage issue tracker now: edit any issue, set assignee or milestone and manage labels
- Better performance for pages with events list, issues list and commits list
- - Faster automerge check and merge itself when source and target branches are in same repository
+ - Faster automerge check and merge itself when source and target branches are in same repository
- Correctly show anonymous authorized applications under Profile > Applications.
- Query Optimization in MySQL.
- Allow users to be blocked and unblocked via the API
@@ -97,17 +115,17 @@ v 7.13.0
- Redesign project page. Show README as default instead of activity. Move project activity to separate page
- Make left menu more hierarchical and less contextual by adding back item at top
- A fork can’t have a visibility level that is greater than the original project.
- - Faster code search in repository and wiki. Fixes search page timeout for big repositories
+ - Faster code search in repository and wiki. Fixes search page timeout for big repositories
- Allow administrators to disable 2FA for a specific user
- Add error message for SSH key linebreaks
- Store commits count in database (will populate with valid values only after first push)
- Rebuild cache after push to repository in background job
+ - Fix transferring of project to another group using the API.
v 7.12.2
- Correctly show anonymous authorized applications under Profile > Applications.
- Faster automerge check and merge itself when source and target branches are in same repository
- Audit log for user authentication
- - Fix transferring of project to another group using the API.
- Allow custom label to be set for authentication providers.
v 7.12.1
@@ -116,7 +134,7 @@ v 7.12.1
- Add SAML to list of social_provider (Matt Firtion)
- Fix merge requests API scope to keep compatibility in 7.12.x patch release (Dmitriy Zaporozhets)
- Fix closed merge request scope at milestone page (Dmitriy Zaporozhets)
- - Revert merge request states renaming
+ - Revert merge request states renaming
- Fix hooks for web based events with external issue references (Daniel Gerhardt)
- Improve performance for issue and merge request pages
- Compress database dumps to reduce backup size
diff --git a/GITLAB_SHELL_VERSION b/GITLAB_SHELL_VERSION
index ec1cf33c3f6..2714f5313ae 100644
--- a/GITLAB_SHELL_VERSION
+++ b/GITLAB_SHELL_VERSION
@@ -1 +1 @@
-2.6.3
+2.6.4
diff --git a/Gemfile.lock b/Gemfile.lock
index 58622f2ac10..e72b7fe4927 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -875,4 +875,4 @@ DEPENDENCIES
wikicloth (= 0.8.1)
BUNDLED WITH
- 1.10.5
+ 1.10.4
diff --git a/README.md b/README.md
index bd663b30f3e..52e12bb66ad 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,7 @@
# GitLab
[![build status](https://ci.gitlab.com/projects/1/status.png?ref=master)](https://ci.gitlab.com/projects/1?ref=master)
-[![Build Status](https://semaphoreapp.com/api/v1/projects/2f1a5809-418b-4cc2-a1f4-819607579fe7/243338/badge.png)](https://semaphoreapp.com/gitlabhq/gitlabhq)
+[![Build Status](https://semaphoreci.com/api/v1/projects/2f1a5809-418b-4cc2-a1f4-819607579fe7/400484/shields_badge.svg)](https://semaphoreci.com/gitlabhq/gitlabhq)
[![Code Climate](https://codeclimate.com/github/gitlabhq/gitlabhq.svg)](https://codeclimate.com/github/gitlabhq/gitlabhq)
[![Coverage Status](https://coveralls.io/repos/gitlabhq/gitlabhq/badge.png?branch=master)](https://coveralls.io/r/gitlabhq/gitlabhq?branch=master)
@@ -69,7 +69,7 @@ Instructions on how to start GitLab and how to run the tests can be found in the
GitLab is a Ruby on Rails application that runs on the following software:
- Ubuntu/Debian/CentOS/RHEL
-- Ruby (MRI) 2.0 or 2.1
+- Ruby (MRI) 2.1
- Git 1.7.10+
- Redis 2.0+
- MySQL or PostgreSQL
@@ -103,4 +103,4 @@ Please see [Getting help for GitLab](https://about.gitlab.com/getting-help/) on
## Is it awesome?
Thanks for [asking this question](https://twitter.com/supersloth/status/489462789384056832) Joshua.
-[These people](https://twitter.com/gitlab/favorites) seem to like it. \ No newline at end of file
+[These people](https://twitter.com/gitlab/favorites) seem to like it.
diff --git a/app/assets/images/msapplication-tile.png b/app/assets/images/msapplication-tile.png
index f8c5c8b28b4..58bbf2b20cb 100644
--- a/app/assets/images/msapplication-tile.png
+++ b/app/assets/images/msapplication-tile.png
Binary files differ
diff --git a/app/assets/javascripts/merge_request_widget.js.coffee b/app/assets/javascripts/merge_request_widget.js.coffee
index e4d815bb4e4..995a2f24093 100644
--- a/app/assets/javascripts/merge_request_widget.js.coffee
+++ b/app/assets/javascripts/merge_request_widget.js.coffee
@@ -19,7 +19,7 @@ class @MergeRequestWidget
when 'merged'
location.reload()
else
- setTimeout(merge_request_widget.mergeInProgress, 3000)
+ setTimeout(merge_request_widget.mergeInProgress, 2000)
dataType: 'json'
getMergeStatus: ->
@@ -36,7 +36,7 @@ class @MergeRequestWidget
showCiState: (state) ->
$('.ci_widget').hide()
- allowed_states = ["failed", "canceled", "running", "pending", "success", "not_found"]
+ allowed_states = ["failed", "canceled", "running", "pending", "success", "skipped", "not_found"]
if state in allowed_states
$('.ci_widget.ci-' + state).show()
switch state
@@ -49,10 +49,8 @@ class @MergeRequestWidget
@setMergeButtonClass('btn-danger')
showCiCoverage: (coverage) ->
- cov_html = $('<span>')
- cov_html.addClass('ci-coverage')
- cov_html.text('Coverage ' + coverage + '%')
- $('.ci_widget:visible').append(cov_html)
+ text = 'Coverage ' + coverage + '%'
+ $('.ci_widget:visible .ci-coverage').text(text)
setMergeButtonClass: (css_class) ->
$('.accept_merge_request').removeClass("btn-create").addClass(css_class)
diff --git a/app/assets/javascripts/project.js.coffee b/app/assets/javascripts/project.js.coffee
index eb8c1fa1426..87c1b67a772 100644
--- a/app/assets/javascripts/project.js.coffee
+++ b/app/assets/javascripts/project.js.coffee
@@ -1,12 +1,12 @@
class @Project
constructor: ->
# Git clone panel switcher
- scope = $ '.git-clone-holder'
- if scope.length > 0
- $('a, button', scope).click ->
- $('a, button', scope).removeClass 'active'
+ cloneHolder = $('.git-clone-holder')
+ if cloneHolder.length
+ $('a, button', cloneHolder).click ->
+ $('a, button', cloneHolder).removeClass 'active'
$(@).addClass 'active'
- $('#project_clone', scope).val $(@).data 'clone'
+ $('#project_clone', cloneHolder).val $(@).data 'clone'
$(".clone").text("").append $(@).data 'clone'
# Ref switcher
@@ -24,3 +24,8 @@ class @Project
$.cookie('hide_no_password_message', 'false', { path: path })
$(@).parents('.no-password-message').remove()
e.preventDefault()
+
+ $('.js-toggle-clone-holder').on 'click', (e) ->
+ cloneHolder.toggle()
+
+ cloneHolder.hide() unless $('.empty-project').length
diff --git a/app/assets/stylesheets/generic/mobile.scss b/app/assets/stylesheets/generic/mobile.scss
index 24c828e0d97..bb7b9356c70 100644
--- a/app/assets/stylesheets/generic/mobile.scss
+++ b/app/assets/stylesheets/generic/mobile.scss
@@ -48,6 +48,10 @@
display: block;
}
+ .project-home-desc {
+ font-size: 21px;
+ }
+
.project-repo-buttons,
.git-clone-holder {
display: none;
diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss
index 61071320973..bb61a51029b 100644
--- a/app/assets/stylesheets/pages/merge_requests.scss
+++ b/app/assets/stylesheets/pages/merge_requests.scss
@@ -1,9 +1,15 @@
-
- /**
- * MR -> show: Automerge widget
+/**
+ * MR -> show: Automerge widget
*
*/
.mr-state-widget {
+ background: #FAFAFA;
+ margin-bottom: 20px;
+ color: #666;
+ border: 1px solid #e5e5e5;
+ @include box-shadow(0 1px 1px rgba(0, 0, 0, 0.05));
+ @include border-radius(3px);
+
form {
margin-bottom: 0;
.clearfix {
@@ -20,22 +26,71 @@
display: inline-block;
margin: 0;
margin-left: 20px;
- padding: 10px 0;
+ padding: 5px;
line-height: 20px;
- font-weight: bold;
.remove_source_checkbox {
margin: 0;
- font-weight: bold;
}
}
}
+
+ .ci_widget {
+ border-bottom: 1px solid #EEE;
+
+ i {
+ margin-right: 4px;
+ }
+
+ &.ci-success {
+ color: $gl-success;
+ }
+
+ &.ci-skipped {
+ background-color: #eee;
+ color: #888;
+ }
+
+ &.ci-pending,
+ &.ci-running {
+ color: $gl-warning;
+ }
+
+ &.ci-failed,
+ &.ci-canceled,
+ &.ci-error {
+ color: $gl-danger;
+ }
+ }
+
+ .mr-widget-body,
+ .ci_widget,
+ .mr-widget-footer {
+ padding: 15px;
+ }
+
+ .mr-widget-body {
+ h4 {
+ font-weight: bold;
+ margin: 5px 0;
+ }
+
+ p:last-child {
+ margin-bottom: 0;
+ }
+ }
+
+ .mr-widget-footer {
+ border-top: 1px solid #EEE;
+ }
+
+ .ci-coverage {
+ float: right;
+ }
}
@media(min-width: $screen-sm-max) {
.merge-request .merge-request-tabs{
- margin: 20px 0;
-
li {
a {
padding: 15px 40px;
@@ -45,6 +100,11 @@
}
}
+.merge-request .merge-request-tabs{
+ margin-top: 30px;
+ margin-bottom: 20px;
+}
+
.mr_source_commit,
.mr_target_commit {
.commit {
@@ -58,23 +118,10 @@
}
.label-branch {
- @include border-radius(4px);
- padding: 3px 4px;
- border: none;
- background: $hover;
- color: #333;
+ color: #222;
font-family: $monospace_font;
- font-weight: normal;
+ font-weight: bold;
overflow: hidden;
-
- .label-project {
- @include border-radius-left(4px);
- padding: 3px 4px;
- background: #279;
- position: relative;
- left: -4px;
- letter-spacing: -1px;
- }
}
.mr-list {
@@ -121,59 +168,6 @@
display: none;
}
-.mr-state-widget {
- font-size: 13px;
- background: #FAFAFA;
- margin-bottom: 20px;
- color: #666;
- border: 1px solid #e5e5e5;
- @include box-shadow(0 1px 1px rgba(0, 0, 0, 0.05));
- @include border-radius(3px);
-
- .ci_widget {
- padding: 10px 15px;
- font-size: 15px;
- border-bottom: 1px solid #EEE;
-
- &.ci-success {
- color: $gl-success;
- }
-
- &.ci-pending,
- &.ci-running {
- color: $gl-warning;
- }
-
- &.ci-failed,
- &.ci-canceled,
- &.ci-error {
- color: $gl-danger;
- }
- }
-
- .mr-widget-body {
- padding: 10px 15px;
-
- h4 {
- font-weight: bold;
- margin: 5px 0;
- }
-
- p:last-child {
- margin-bottom: 0;
- }
- }
-
- .mr-widget-footer {
- padding: 10px 15px;
- border-top: 1px solid #EEE;
- }
-
- .ci-coverage {
- float: right;
- }
-}
-
.merge-request-show-labels {
a {
margin-right: 5px;
diff --git a/app/assets/stylesheets/pages/projects.scss b/app/assets/stylesheets/pages/projects.scss
index 21d958db80c..29d3dbc25eb 100644
--- a/app/assets/stylesheets/pages/projects.scss
+++ b/app/assets/stylesheets/pages/projects.scss
@@ -16,7 +16,6 @@
.project-home-panel {
text-align: center;
- margin-bottom: 20px;
.project-identicon-holder {
margin-bottom: 15px;
@@ -31,7 +30,13 @@
}
}
- .lead {
+ .project-home-desc {
+ h1 {
+ margin: 0;
+ margin-bottom: 10px;
+ font-size: 26px;
+ }
+
p {
display: inline;
}
@@ -39,7 +44,7 @@
.git-clone-holder {
max-width: 600px;
- margin: 0 auto;
+ margin: 20px auto;
}
.visibility-level-label {
diff --git a/app/controllers/abuse_reports_controller.rb b/app/controllers/abuse_reports_controller.rb
new file mode 100644
index 00000000000..65dbd5ef551
--- /dev/null
+++ b/app/controllers/abuse_reports_controller.rb
@@ -0,0 +1,24 @@
+class AbuseReportsController < ApplicationController
+ def new
+ @abuse_report = AbuseReport.new
+ @abuse_report.user_id = params[:user_id]
+ end
+
+ def create
+ @abuse_report = AbuseReport.new(report_params)
+ @abuse_report.reporter = current_user
+
+ if @abuse_report.save
+ message = "Thank you for your report. A GitLab administrator will look into it shortly."
+ redirect_to root_path, notice: message
+ else
+ render :new
+ end
+ end
+
+ private
+
+ def report_params
+ params.require(:abuse_report).permit(:user_id, :message)
+ end
+end
diff --git a/app/controllers/admin/abuse_reports_controller.rb b/app/controllers/admin/abuse_reports_controller.rb
new file mode 100644
index 00000000000..34f37bca4ad
--- /dev/null
+++ b/app/controllers/admin/abuse_reports_controller.rb
@@ -0,0 +1,11 @@
+class Admin::AbuseReportsController < Admin::ApplicationController
+ def index
+ @abuse_reports = AbuseReport.order(id: :desc).page(params[:page])
+ end
+
+ def destroy
+ AbuseReport.find(params[:id]).destroy
+
+ redirect_to admin_abuse_reports_path, notice: 'Report was removed'
+ end
+end
diff --git a/app/controllers/admin/users_controller.rb b/app/controllers/admin/users_controller.rb
index 770fe00af51..6092c79c254 100644
--- a/app/controllers/admin/users_controller.rb
+++ b/app/controllers/admin/users_controller.rb
@@ -55,6 +55,14 @@ class Admin::UsersController < Admin::ApplicationController
end
end
+ def confirm
+ if user.confirm!
+ redirect_to :back, notice: "Successfully confirmed"
+ else
+ redirect_to :back, alert: "Error occurred. User was not confirmed"
+ end
+ end
+
def disable_two_factor
user.disable_two_factor!
redirect_to admin_user_path(user),
diff --git a/app/controllers/autocomplete_controller.rb b/app/controllers/autocomplete_controller.rb
index 52e9c58b47c..5c3ca8e23c9 100644
--- a/app/controllers/autocomplete_controller.rb
+++ b/app/controllers/autocomplete_controller.rb
@@ -33,6 +33,8 @@ class AutocompleteController < ApplicationController
@users = @users.search(params[:search]) if params[:search].present?
@users = @users.active
@users = @users.page(params[:page]).per(PER_PAGE)
+ # Always include current user if available to filter by "Me"
+ @users = User.find(@users.pluck(:id) + [current_user.id]).uniq if current_user
render json: @users, only: [:name, :username, :id], methods: [:avatar_url]
end
diff --git a/app/controllers/import/bitbucket_controller.rb b/app/controllers/import/bitbucket_controller.rb
index af0b841f0b7..4e6c0b66634 100644
--- a/app/controllers/import/bitbucket_controller.rb
+++ b/app/controllers/import/bitbucket_controller.rb
@@ -22,6 +22,7 @@ class Import::BitbucketController < Import::BaseController
def status
@repos = client.projects
+ @incompatible_repos = client.incompatible_projects
@already_added_projects = current_user.created_projects.where(import_type: "bitbucket")
already_added_projects_names = @already_added_projects.pluck(:import_source)
diff --git a/app/controllers/projects/branches_controller.rb b/app/controllers/projects/branches_controller.rb
index 117ae3aaa3d..3ac0a75fa70 100644
--- a/app/controllers/projects/branches_controller.rb
+++ b/app/controllers/projects/branches_controller.rb
@@ -17,7 +17,9 @@ class Projects::BranchesController < Projects::ApplicationController
def create
branch_name = sanitize(strip_tags(params[:branch_name]))
+ branch_name = Addressable::URI.unescape(branch_name)
ref = sanitize(strip_tags(params[:ref]))
+ ref = Addressable::URI.unescape(ref)
result = CreateBranchService.new(project, current_user).
execute(branch_name, ref)
@@ -32,9 +34,8 @@ class Projects::BranchesController < Projects::ApplicationController
end
def destroy
- status = DeleteBranchService.new(project, current_user).execute(params[:id])
- @branch_name = params[:id]
-
+ @branch_name = Addressable::URI.unescape(params[:id])
+ status = DeleteBranchService.new(project, current_user).execute(@branch_name)
respond_to do |format|
format.html do
redirect_to namespace_project_branches_path(@project.namespace,
diff --git a/app/controllers/projects/compare_controller.rb b/app/controllers/projects/compare_controller.rb
index c5f085c236f..d9b3adae95b 100644
--- a/app/controllers/projects/compare_controller.rb
+++ b/app/controllers/projects/compare_controller.rb
@@ -13,13 +13,8 @@ class Projects::CompareController < Projects::ApplicationController
base_ref = Addressable::URI.unescape(params[:from])
@ref = head_ref = Addressable::URI.unescape(params[:to])
- compare_result = CompareService.new.execute(
- current_user,
- @project,
- head_ref,
- @project,
- base_ref
- )
+ compare_result = CompareService.new.
+ execute(@project, head_ref, @project, base_ref)
@commits = compare_result.commits
@diffs = compare_result.diffs
diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb
index d1265198318..f3054881daf 100644
--- a/app/controllers/projects/merge_requests_controller.rb
+++ b/app/controllers/projects/merge_requests_controller.rb
@@ -1,9 +1,7 @@
-require 'gitlab/satellite/satellite'
-
class Projects::MergeRequestsController < Projects::ApplicationController
before_action :module_enabled
before_action :merge_request, only: [
- :edit, :update, :show, :diffs, :commits, :automerge, :automerge_check,
+ :edit, :update, :show, :diffs, :commits, :merge, :merge_check,
:ci_status, :toggle_subscription
]
before_action :closes_issues, only: [:edit, :update, :show, :diffs, :commits]
@@ -137,7 +135,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
end
end
- def automerge_check
+ def merge_check
if @merge_request.unchecked?
@merge_request.check_if_can_be_merged
end
@@ -147,11 +145,11 @@ class Projects::MergeRequestsController < Projects::ApplicationController
render partial: "projects/merge_requests/widget/show.html.haml", layout: false
end
- def automerge
+ def merge
return access_denied! unless @merge_request.can_be_merged_by?(current_user)
- if @merge_request.automergeable?
- AutoMergeWorker.perform_async(@merge_request.id, current_user.id, params)
+ if @merge_request.mergeable?
+ MergeWorker.perform_async(@merge_request.id, current_user.id, params)
@status = true
else
@status = false
diff --git a/app/controllers/projects/notes_controller.rb b/app/controllers/projects/notes_controller.rb
index c4a87e9dbd8..0f5d82ce133 100644
--- a/app/controllers/projects/notes_controller.rb
+++ b/app/controllers/projects/notes_controller.rb
@@ -30,13 +30,10 @@ class Projects::NotesController < Projects::ApplicationController
end
def update
- if note.editable?
- note.update_attributes(note_params)
- note.reset_events_cache
- end
+ @note = Notes::UpdateService.new(project, current_user, note_params).execute(note)
respond_to do |format|
- format.json { render_note_json(note) }
+ format.json { render_note_json(@note) }
format.html { redirect_to :back }
end
end
diff --git a/app/helpers/issues_helper.rb b/app/helpers/issues_helper.rb
index d4c345fe431..6ddb37cd0dc 100644
--- a/app/helpers/issues_helper.rb
+++ b/app/helpers/issues_helper.rb
@@ -43,21 +43,6 @@ module IssuesHelper
end
end
- def issue_timestamp(issue)
- # Shows the created at time and the updated at time if different
- ts = time_ago_with_tooltip(issue.created_at, placement: 'bottom', html_class: 'note_created_ago')
- if issue.updated_at != issue.created_at
- ts << capture_haml do
- haml_tag :span do
- haml_concat '&middot;'
- haml_concat icon('edit', title: 'edited')
- haml_concat time_ago_with_tooltip(issue.updated_at, placement: 'bottom', html_class: 'issue_edited_ago')
- end
- end
- end
- ts.html_safe
- end
-
def bulk_update_milestone_options
options_for_select([['None (backlog)', -1]]) +
options_from_collection_for_select(project_active_milestones, 'id',
diff --git a/app/helpers/merge_requests_helper.rb b/app/helpers/merge_requests_helper.rb
index 45ee4fe4135..f8169b4f288 100644
--- a/app/helpers/merge_requests_helper.rb
+++ b/app/helpers/merge_requests_helper.rb
@@ -61,4 +61,14 @@ module MergeRequestsHelper
}
)
end
+
+ def source_branch_with_namespace(merge_request)
+ if merge_request.for_fork?
+ namespace = link_to(merge_request.source_project_namespace,
+ project_path(merge_request.source_project))
+ namespace + ":#{merge_request.source_branch}"
+ else
+ merge_request.source_branch
+ end
+ end
end
diff --git a/app/helpers/notes_helper.rb b/app/helpers/notes_helper.rb
index dda9b17d61d..5f0c921413a 100644
--- a/app/helpers/notes_helper.rb
+++ b/app/helpers/notes_helper.rb
@@ -23,21 +23,6 @@ module NotesHelper
end
end
- def note_timestamp(note)
- # Shows the created at time and the updated at time if different
- ts = time_ago_with_tooltip(note.created_at, placement: 'bottom', html_class: 'note_created_ago')
- if note.updated_at != note.created_at
- ts << capture_haml do
- haml_tag :span do
- haml_concat '&middot;'
- haml_concat icon('edit', title: 'edited')
- haml_concat time_ago_with_tooltip(note.updated_at, placement: 'bottom', html_class: 'note_edited_ago')
- end
- end
- end
- ts.html_safe
- end
-
def noteable_json(noteable)
{
id: noteable.id,
diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb
index f5b78533896..525a46291f6 100644
--- a/app/helpers/projects_helper.rb
+++ b/app/helpers/projects_helper.rb
@@ -21,7 +21,7 @@ module ProjectsHelper
end
def link_to_member(project, author, opts = {})
- default_opts = { avatar: true, name: true, size: 16 }
+ default_opts = { avatar: true, name: true, size: 16, author_class: 'author' }
opts = default_opts.merge(opts)
return "(deleted)" unless author
@@ -32,7 +32,7 @@ module ProjectsHelper
author_html << image_tag(avatar_icon(author.try(:email), opts[:size]), width: opts[:size], class: "avatar avatar-inline #{"s#{opts[:size]}" if opts[:size]}", alt:'') if opts[:avatar]
# Build name span tag
- author_html << content_tag(:span, sanitize(author.name), class: 'author') if opts[:name]
+ author_html << content_tag(:span, sanitize(author.name), class: opts[:author_class]) if opts[:name]
author_html = author_html.html_safe
diff --git a/app/models/abuse_report.rb b/app/models/abuse_report.rb
new file mode 100644
index 00000000000..c8c39db11bc
--- /dev/null
+++ b/app/models/abuse_report.rb
@@ -0,0 +1,9 @@
+class AbuseReport < ActiveRecord::Base
+ belongs_to :reporter, class_name: "User"
+ belongs_to :user
+
+ validates :reporter, presence: true
+ validates :user, presence: true
+ validates :message, presence: true
+ validates :user_id, uniqueness: { scope: :reporter_id }
+end
diff --git a/app/models/concerns/issuable.rb b/app/models/concerns/issuable.rb
index c21e7fd0e3b..40642dc63ba 100644
--- a/app/models/concerns/issuable.rb
+++ b/app/models/concerns/issuable.rb
@@ -12,6 +12,7 @@ module Issuable
included do
belongs_to :author, class_name: "User"
belongs_to :assignee, class_name: "User"
+ belongs_to :updated_by, class_name: "User"
belongs_to :milestone
has_many :notes, as: :noteable, dependent: :destroy
has_many :label_links, as: :target, dependent: :destroy
diff --git a/app/models/group.rb b/app/models/group.rb
index cfb8faa1491..4ff610f8e9d 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -76,8 +76,24 @@ class Group < Namespace
add_users([user], access_level, current_user)
end
+ def add_guest(user, current_user = nil)
+ add_user(user, Gitlab::Access::GUEST, current_user)
+ end
+
+ def add_reporter(user, current_user = nil)
+ add_user(user, Gitlab::Access::REPORTER, current_user)
+ end
+
+ def add_developer(user, current_user = nil)
+ add_user(user, Gitlab::Access::DEVELOPER, current_user)
+ end
+
+ def add_master(user, current_user = nil)
+ add_user(user, Gitlab::Access::MASTER, current_user)
+ end
+
def add_owner(user, current_user = nil)
- self.add_user(user, Gitlab::Access::OWNER, current_user)
+ add_user(user, Gitlab::Access::OWNER, current_user)
end
def has_owner?(user)
diff --git a/app/models/key.rb b/app/models/key.rb
index 2dcae059c0e..406a1257b5d 100644
--- a/app/models/key.rb
+++ b/app/models/key.rb
@@ -39,6 +39,11 @@ class Key < ActiveRecord::Base
self.key = key.strip unless key.blank?
end
+ def publishable_key
+ #Removes anything beyond the keytype and key itself
+ self.key.split[0..1].join(' ')
+ end
+
# projects that has this key
def projects
user.authorized_projects
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 1ef76d16700..467b90861f9 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -41,8 +41,6 @@ class MergeRequest < ActiveRecord::Base
delegate :commits, :diffs, :last_commit, :last_commit_short_sha, to: :merge_request_diff, prefix: nil
- attr_accessor :should_remove_source_branch
-
# When this attribute is true some MR validation is ignored
# It allows us to close or modify broken merge requests
attr_accessor :allow_broken
@@ -57,7 +55,7 @@ class MergeRequest < ActiveRecord::Base
transition [:reopened, :opened] => :closed
end
- event :merge do
+ event :mark_as_merged do
transition [:reopened, :opened, :locked] => :merged
end
@@ -206,11 +204,7 @@ class MergeRequest < ActiveRecord::Base
def check_if_can_be_merged
can_be_merged =
- if for_fork?
- Gitlab::Satellite::MergeAction.new(self.author, self).can_be_merged?
- else
- project.repository.can_be_merged?(source_branch, target_branch)
- end
+ project.repository.can_be_merged?(source_sha, target_branch)
if can_be_merged
mark_as_mergeable
@@ -227,18 +221,6 @@ class MergeRequest < ActiveRecord::Base
self.target_project.events.where(target_id: self.id, target_type: "MergeRequest", action: Event::CLOSED).last
end
- def automerge!(current_user, commit_message = nil)
- return unless automergeable?
-
- MergeRequests::AutoMergeService.
- new(target_project, current_user).
- execute(self, commit_message)
- end
-
- def remove_source_branch?
- self.should_remove_source_branch && !self.source_project.root_ref?(self.source_branch) && !self.for_fork?
- end
-
def open?
opened? || reopened?
end
@@ -247,11 +229,11 @@ class MergeRequest < ActiveRecord::Base
title =~ /\A\[?WIP\]?:? /i
end
- def automergeable?
+ def mergeable?
open? && !work_in_progress? && can_be_merged?
end
- def automerge_status
+ def gitlab_merge_status
if work_in_progress?
"work_in_progress"
else
@@ -278,14 +260,14 @@ class MergeRequest < ActiveRecord::Base
#
# see "git diff"
def to_diff(current_user)
- Gitlab::Satellite::MergeAction.new(current_user, self).diff_in_satellite
+ target_project.repository.diff_text(target_branch, source_sha)
end
# Returns the commit as a series of email patches.
#
# see "git format-patch"
def to_patch(current_user)
- Gitlab::Satellite::MergeAction.new(current_user, self).format_patch
+ target_project.repository.format_patch(target_branch, source_sha)
end
def hook_attrs
@@ -436,4 +418,30 @@ class MergeRequest < ActiveRecord::Base
"Open"
end
end
+
+ def target_sha
+ @target_sha ||= target_project.
+ repository.commit(target_branch).sha
+ end
+
+ def source_sha
+ commits.first.sha
+ end
+
+ def fetch_ref
+ target_project.repository.fetch_ref(
+ source_project.repository.path_to_repo,
+ "refs/heads/#{source_branch}",
+ "refs/merge-requests/#{iid}/head"
+ )
+ end
+
+ def in_locked_state
+ begin
+ lock_mr
+ yield
+ ensure
+ unlock_mr if locked?
+ end
+ end
end
diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb
index df1c2b78758..e317c8eac4d 100644
--- a/app/models/merge_request_diff.rb
+++ b/app/models/merge_request_diff.rb
@@ -16,9 +16,8 @@ require Rails.root.join("app/models/commit")
class MergeRequestDiff < ActiveRecord::Base
include Sortable
- # Prevent store of diff
- # if commits amount more then 200
- COMMITS_SAFE_SIZE = 200
+ # Prevent store of diff if commits amount more then 500
+ COMMITS_SAFE_SIZE = 500
attr_reader :commits, :diffs
@@ -124,12 +123,12 @@ class MergeRequestDiff < ActiveRecord::Base
if new_diffs.any?
if new_diffs.size > Commit::DIFF_HARD_LIMIT_FILES
self.state = :overflow_diff_files_limit
- new_diffs = []
+ new_diffs = new_diffs.first[Commit::DIFF_HARD_LIMIT_LINES]
end
if new_diffs.sum { |diff| diff.diff.lines.count } > Commit::DIFF_HARD_LIMIT_LINES
self.state = :overflow_diff_lines_limit
- new_diffs = []
+ new_diffs = new_diffs.first[Commit::DIFF_HARD_LIMIT_LINES]
end
end
@@ -160,12 +159,21 @@ class MergeRequestDiff < ActiveRecord::Base
private
def compare_result
- @compare_result ||= CompareService.new.execute(
- merge_request.author,
- merge_request.source_project,
- merge_request.source_branch,
- merge_request.target_project,
- merge_request.target_branch,
- )
+ @compare_result ||=
+ begin
+ # Update ref for merge request
+ merge_request.fetch_ref
+
+ # Get latest sha of branch from source project
+ source_sha = merge_request.source_project.commit(source_branch).sha
+
+ Gitlab::CompareResult.new(
+ Gitlab::Git::Compare.new(
+ merge_request.target_project.repository.raw_repository,
+ merge_request.target_branch,
+ source_sha,
+ )
+ )
+ end
end
end
diff --git a/app/models/namespace.rb b/app/models/namespace.rb
index 03d2ab165ea..161a16ca61c 100644
--- a/app/models/namespace.rb
+++ b/app/models/namespace.rb
@@ -114,13 +114,15 @@ class Namespace < ActiveRecord::Base
end
def move_dir
+ # Ensure old directory exists before moving it
+ gitlab_shell.add_namespace(path_was)
+
if gitlab_shell.mv_namespace(path_was, path)
- # If repositories moved successfully we need to remove old satellites
- # and send update instructions to users.
+ # 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
- gitlab_shell.rm_satellites(path_was)
send_update_instructions
rescue
# Returning false does not rollback after_* transaction but gives
diff --git a/app/models/note.rb b/app/models/note.rb
index 62567f471dc..a99d428b02d 100644
--- a/app/models/note.rb
+++ b/app/models/note.rb
@@ -31,8 +31,9 @@ class Note < ActiveRecord::Base
participant :author, :mentioned_users
belongs_to :project
- belongs_to :noteable, polymorphic: true, touch: true
+ belongs_to :noteable, polymorphic: true
belongs_to :author, class_name: "User"
+ belongs_to :updated_by, class_name: "User"
delegate :name, to: :project, prefix: true
delegate :name, :email, to: :author, prefix: true
diff --git a/app/models/project.rb b/app/models/project.rb
index 3dc1729e812..4628f478ca6 100644
--- a/app/models/project.rb
+++ b/app/models/project.rb
@@ -520,14 +520,6 @@ class Project < ActiveRecord::Base
!repository.exists? || repository.empty?
end
- def ensure_satellite_exists
- self.satellite.create unless self.satellite.exists?
- end
-
- def satellite
- @satellite ||= Gitlab::Satellite::Satellite.new(self)
- end
-
def repo
repository.raw
end
@@ -597,14 +589,11 @@ class Project < ActiveRecord::Base
new_path_with_namespace = File.join(namespace_dir, path)
if gitlab_shell.mv_repository(old_path_with_namespace, new_path_with_namespace)
- # If repository moved successfully we need to remove old satellite
- # and send update instructions to users.
+ # 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.rm_satellites(old_path_with_namespace)
- ensure_satellite_exists
send_move_instructions
reset_events_cache
rescue
@@ -702,7 +691,6 @@ class Project < ActiveRecord::Base
def create_repository
if forked?
if gitlab_shell.fork_repository(forked_from_project.path_with_namespace, self.namespace.path)
- ensure_satellite_exists
true
else
errors.add(:base, 'Failed to fork repository via gitlab-shell')
diff --git a/app/models/project_services/ci_service.rb b/app/models/project_services/ci_service.rb
index 77d48d4af5e..803402c83ee 100644
--- a/app/models/project_services/ci_service.rb
+++ b/app/models/project_services/ci_service.rb
@@ -41,7 +41,7 @@ class CiService < Service
# Return string with build status or :error symbol
#
- # Allowed states: 'success', 'failed', 'running', 'pending'
+ # Allowed states: 'success', 'failed', 'running', 'pending', 'skipped'
#
#
# Ex.
diff --git a/app/models/project_services/gitlab_ci_service.rb b/app/models/project_services/gitlab_ci_service.rb
index 5aaa4e85cbc..ecdcd48ae60 100644
--- a/app/models/project_services/gitlab_ci_service.rb
+++ b/app/models/project_services/gitlab_ci_service.rb
@@ -74,6 +74,8 @@ class GitlabCiService < CiService
else
:error
end
+ rescue Errno::ECONNREFUSED
+ :error
end
def fork_registration(new_project, private_token)
@@ -103,6 +105,8 @@ class GitlabCiService < CiService
if response.code == 200 and response["coverage"]
response["coverage"]
end
+ rescue Errno::ECONNREFUSED
+ nil
end
def build_page(sha, ref)
diff --git a/app/models/repository.rb b/app/models/repository.rb
index 807b33b2a3e..46efbede2a2 100644
--- a/app/models/repository.rb
+++ b/app/models/repository.rb
@@ -411,15 +411,36 @@ class Repository
}
end
- def can_be_merged?(source_branch, target_branch)
+ def can_be_merged?(source_sha, target_branch)
our_commit = rugged.branches[target_branch].target
- their_commit = rugged.branches[source_branch].target
+ their_commit = rugged.lookup(source_sha)
if our_commit && their_commit
!rugged.merge_commits(our_commit, their_commit).conflicts?
+ else
+ false
end
end
+ def merge(source_sha, target_branch, options = {})
+ our_commit = rugged.branches[target_branch].target
+ their_commit = rugged.lookup(source_sha)
+
+ raise "Invalid merge target" if our_commit.nil?
+ raise "Invalid merge source" if their_commit.nil?
+
+ merge_index = rugged.merge_commits(our_commit, their_commit)
+ return false if merge_index.conflicts?
+
+ actual_options = options.merge(
+ parents: [our_commit, their_commit],
+ tree: merge_index.write_tree(rugged),
+ update_ref: "refs/heads/#{target_branch}"
+ )
+
+ Rugged::Commit.create(rugged, actual_options)
+ end
+
def search_files(query, ref)
offset = 2
args = %W(git grep -i -n --before-context #{offset} --after-context #{offset} #{query} #{ref || root_ref})
@@ -453,6 +474,11 @@ class Repository
)
end
+ def fetch_ref(source_path, source_ref, target_ref)
+ args = %W(git fetch #{source_path} #{source_ref}:#{target_ref})
+ Gitlab::Popen.popen(args, path_to_repo)
+ end
+
private
def cache
diff --git a/app/models/user.rb b/app/models/user.rb
index 2beefb1d614..57145cc6b6e 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -619,7 +619,7 @@ class User < ActiveRecord::Base
end
def all_ssh_keys
- keys.map(&:key)
+ keys.map(&:publishable_key)
end
def temp_oauth_email?
diff --git a/app/services/base_service.rb b/app/services/base_service.rb
index 6d9ed345914..f00ec7408b6 100644
--- a/app/services/base_service.rb
+++ b/app/services/base_service.rb
@@ -31,6 +31,10 @@ class BaseService
SystemHooksService.new
end
+ def repository
+ project.repository
+ end
+
# Add an error to the specified model for restricted visibility levels
def deny_visibility_level(model, denied_visibility_level = nil)
denied_visibility_level ||= model.visibility_level
diff --git a/app/services/compare_service.rb b/app/services/compare_service.rb
index 6aa9df4b194..70f642baaaa 100644
--- a/app/services/compare_service.rb
+++ b/app/services/compare_service.rb
@@ -1,27 +1,28 @@
+require 'securerandom'
+
# Compare 2 branches for one repo or between repositories
# and return Gitlab::CompareResult object that responds to commits and diffs
class CompareService
- def execute(current_user, source_project, source_branch, target_project, target_branch)
- # Try to compare branches to get commits list and diffs
- #
- # Note: Use satellite only when need to compare between two repos
- # because satellites are slower than operations on bare repo
- if target_project == source_project
- Gitlab::CompareResult.new(
- Gitlab::Git::Compare.new(
- target_project.repository.raw_repository,
- target_branch,
- source_branch,
- )
+ def execute(source_project, source_branch, target_project, target_branch)
+ source_sha = source_project.commit(source_branch).sha
+
+ # If compare with other project we need to fetch ref first
+ unless target_project == source_project
+ random_string = SecureRandom.hex
+
+ target_project.repository.fetch_ref(
+ source_project.repository.path_to_repo,
+ "refs/heads/#{source_branch}",
+ "refs/tmp/#{random_string}/head"
)
- else
- Gitlab::Satellite::CompareAction.new(
- current_user,
- target_project,
- target_branch,
- source_project,
- source_branch
- ).result
end
+
+ Gitlab::CompareResult.new(
+ Gitlab::Git::Compare.new(
+ target_project.repository.raw_repository,
+ target_branch,
+ source_sha,
+ )
+ )
end
end
diff --git a/app/services/files/base_service.rb b/app/services/files/base_service.rb
index 646784f2d9d..d7b40ee8906 100644
--- a/app/services/files/base_service.rb
+++ b/app/services/files/base_service.rb
@@ -33,15 +33,8 @@ module Files
private
- def repository
- project.repository
- end
-
def after_commit(sha, branch)
- commit = repository.commit(sha)
- full_ref = "#{Gitlab::Git::BRANCH_REF_PREFIX}#{branch}"
- old_sha = commit.parent_id || Gitlab::Git::BLANK_SHA
- GitPushService.new.execute(project, current_user, old_sha, sha, full_ref)
+ PostCommitService.new(project, current_user).execute(sha, branch)
end
def current_branch
diff --git a/app/services/git_push_service.rb b/app/services/git_push_service.rb
index 3511392d1d8..81535450ac1 100644
--- a/app/services/git_push_service.rb
+++ b/app/services/git_push_service.rb
@@ -10,16 +10,14 @@ class GitPushService
#
# Next, this method:
# 1. Creates the push event
- # 2. Ensures that the project satellite exists
- # 3. Updates merge requests
- # 4. Recognizes cross-references from commit messages
- # 5. Executes the project's web hooks
- # 6. Executes the project's services
+ # 2. Updates merge requests
+ # 3. Recognizes cross-references from commit messages
+ # 4. Executes the project's web hooks
+ # 5. Executes the project's services
#
def execute(project, user, oldrev, newrev, ref)
@project, @user = project, user
- project.ensure_satellite_exists
project.repository.expire_cache
if push_remove_branch?(ref, newrev)
diff --git a/app/services/issues/update_service.rb b/app/services/issues/update_service.rb
index eabab65c9b0..2fc6ef7f356 100644
--- a/app/services/issues/update_service.rb
+++ b/app/services/issues/update_service.rb
@@ -14,7 +14,7 @@ module Issues
filter_params
old_labels = issue.labels.to_a
- if params.present? && issue.update_attributes(params)
+ if params.present? && issue.update_attributes(params.merge(updated_by: current_user))
issue.reset_events_cache
if issue.labels != old_labels
diff --git a/app/services/merge_requests/auto_merge_service.rb b/app/services/merge_requests/auto_merge_service.rb
deleted file mode 100644
index db824d452d0..00000000000
--- a/app/services/merge_requests/auto_merge_service.rb
+++ /dev/null
@@ -1,75 +0,0 @@
-module MergeRequests
- # AutoMergeService class
- #
- # Do git merge in satellite and in case of success
- # mark merge request as merged and execute all hooks and notifications
- # Called when you do merge via GitLab UI
- class AutoMergeService < BaseMergeService
- attr_reader :merge_request, :commit_message
-
- def execute(merge_request, commit_message)
- @commit_message = commit_message
- @merge_request = merge_request
-
- merge_request.lock_mr
-
- if merge!
- merge_request.merge
- create_merge_event(merge_request, current_user)
- create_note(merge_request)
- notification_service.merge_mr(merge_request, current_user)
- execute_hooks(merge_request, 'merge')
- true
- else
- merge_request.unlock_mr
- false
- end
- rescue
- merge_request.unlock_mr if merge_request.locked?
- merge_request.mark_as_unmergeable
- false
- end
-
- def merge!
- if merge_request.for_fork?
- Gitlab::Satellite::MergeAction.new(current_user, merge_request).merge!(commit_message)
- else
- # Merge local branches using rugged instead of satellites
- if sha = commit
- after_commit(sha, merge_request.target_branch)
-
- if merge_request.remove_source_branch?
- DeleteBranchService.new(merge_request.source_project, current_user).execute(merge_request.source_branch)
- end
-
- true
- else
- false
- end
- end
- end
-
- def commit
- committer = repository.user_to_comitter(current_user)
-
- options = {
- message: commit_message,
- author: committer,
- committer: committer
- }
-
- repository.merge(merge_request.source_branch, merge_request.target_branch, options)
- end
-
- def after_commit(sha, branch)
- commit = repository.commit(sha)
- full_ref = "#{Gitlab::Git::BRANCH_REF_PREFIX}#{branch}"
- old_sha = commit.parent_id || Gitlab::Git::BLANK_SHA
- GitPushService.new.execute(project, current_user, old_sha, sha, full_ref)
- end
-
- def repository
- project.repository
- end
- end
-end
diff --git a/app/services/merge_requests/base_merge_service.rb b/app/services/merge_requests/base_merge_service.rb
deleted file mode 100644
index 9579573adf9..00000000000
--- a/app/services/merge_requests/base_merge_service.rb
+++ /dev/null
@@ -1,10 +0,0 @@
-module MergeRequests
- class BaseMergeService < MergeRequests::BaseService
-
- private
-
- def create_merge_event(merge_request, current_user)
- EventCreateService.new.merge_mr(merge_request, current_user)
- end
- end
-end
diff --git a/app/services/merge_requests/build_service.rb b/app/services/merge_requests/build_service.rb
index 956480938c3..a9b29f9654d 100644
--- a/app/services/merge_requests/build_service.rb
+++ b/app/services/merge_requests/build_service.rb
@@ -12,12 +12,16 @@ module MergeRequests
merge_request.target_project ||= (project.forked_from_project || project)
merge_request.target_branch ||= merge_request.target_project.default_branch
- unless merge_request.target_branch && merge_request.source_branch
- return build_failed(merge_request, nil)
+ if merge_request.target_branch.blank? || merge_request.source_branch.blank?
+ message =
+ if params[:source_branch] || params[:target_branch]
+ "You must select source and target branch"
+ end
+
+ return build_failed(merge_request, message)
end
compare_result = CompareService.new.execute(
- current_user,
merge_request.source_project,
merge_request.source_branch,
merge_request.target_project,
@@ -40,7 +44,6 @@ module MergeRequests
merge_request.compare_diffs = diffs
elsif diffs == false
- # satellite timeout return false
merge_request.can_be_created = false
merge_request.compare_failed = true
end
@@ -59,9 +62,6 @@ module MergeRequests
end
merge_request
-
- rescue Gitlab::Satellite::BranchesWithoutParent
- return build_failed(merge_request, "Selected branches have no common commit so they cannot be merged.")
end
def build_failed(merge_request, message)
diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb
index 327ead4ff3f..2107529a21a 100644
--- a/app/services/merge_requests/merge_service.rb
+++ b/app/services/merge_requests/merge_service.rb
@@ -1,22 +1,57 @@
module MergeRequests
# MergeService class
#
- # Mark existing merge request as merged
- # and execute all hooks and notifications
- # Called when you do merge via command line and push code
- # to target branch
- class MergeService < BaseMergeService
+ # Do git merge and in case of success
+ # mark merge request as merged and execute all hooks and notifications
+ # Executed when you do merge via GitLab UI
+ #
+ class MergeService < MergeRequests::BaseService
+ attr_reader :merge_request, :commit_message
+
def execute(merge_request, commit_message)
- merge_request.merge
+ @commit_message = commit_message
+ @merge_request = merge_request
- create_merge_event(merge_request, current_user)
- create_note(merge_request)
- notification_service.merge_mr(merge_request, current_user)
- execute_hooks(merge_request, 'merge')
+ unless @merge_request.mergeable?
+ return error('Merge request is not mergeable')
+ end
+
+ merge_request.in_locked_state do
+ if merge_changes
+ after_merge
+ success
+ else
+ error('Can not merge changes')
+ end
+ end
+ end
+
+ private
+
+ def merge_changes
+ if sha = commit
+ after_commit(sha, merge_request.target_branch)
+ end
+ end
+
+ def commit
+ committer = repository.user_to_comitter(current_user)
+
+ options = {
+ message: commit_message,
+ author: committer,
+ committer: committer
+ }
+
+ repository.merge(merge_request.source_sha, merge_request.target_branch, options)
+ end
+
+ def after_commit(sha, branch)
+ PostCommitService.new(project, current_user).execute(sha, branch)
+ end
- true
- rescue
- false
+ def after_merge
+ MergeRequests::PostMergeService.new(project, current_user).execute(merge_request)
end
end
end
diff --git a/app/services/merge_requests/post_merge_service.rb b/app/services/merge_requests/post_merge_service.rb
new file mode 100644
index 00000000000..aceb8cb9021
--- /dev/null
+++ b/app/services/merge_requests/post_merge_service.rb
@@ -0,0 +1,22 @@
+module MergeRequests
+ # PostMergeService class
+ #
+ # Mark existing merge request as merged
+ # and execute all hooks and notifications
+ #
+ class PostMergeService < MergeRequests::BaseService
+ def execute(merge_request)
+ merge_request.mark_as_merged
+ create_merge_event(merge_request, current_user)
+ create_note(merge_request)
+ notification_service.merge_mr(merge_request, current_user)
+ execute_hooks(merge_request, 'merge')
+ end
+
+ private
+
+ def create_merge_event(merge_request, current_user)
+ EventCreateService.new.merge_mr(merge_request, current_user)
+ end
+ end
+end
diff --git a/app/services/merge_requests/refresh_service.rb b/app/services/merge_requests/refresh_service.rb
index d0648da049b..e903e48e3cd 100644
--- a/app/services/merge_requests/refresh_service.rb
+++ b/app/services/merge_requests/refresh_service.rb
@@ -33,9 +33,9 @@ module MergeRequests
merge_requests.uniq.select(&:source_project).each do |merge_request|
- MergeRequests::MergeService.
+ MergeRequests::PostMergeService.
new(merge_request.target_project, @current_user).
- execute(merge_request, nil)
+ execute(merge_request)
end
end
diff --git a/app/services/merge_requests/update_service.rb b/app/services/merge_requests/update_service.rb
index 589fad16165..25d79e22e39 100644
--- a/app/services/merge_requests/update_service.rb
+++ b/app/services/merge_requests/update_service.rb
@@ -24,7 +24,7 @@ module MergeRequests
filter_params
old_labels = merge_request.labels.to_a
- if params.present? && merge_request.update_attributes(params)
+ if params.present? && merge_request.update_attributes(params.merge(updated_by: current_user))
merge_request.reset_events_cache
if merge_request.labels != old_labels
diff --git a/app/services/notes/update_service.rb b/app/services/notes/update_service.rb
index b5611d46257..c22a9333ef6 100644
--- a/app/services/notes/update_service.rb
+++ b/app/services/notes/update_service.rb
@@ -1,22 +1,11 @@
module Notes
class UpdateService < BaseService
- def execute
- note = project.notes.find(params[:note_id])
- note.note = params[:note]
- if note.save
- notification_service.new_note(note)
+ def execute(note)
+ return note unless note.editable?
- # Skip system notes, like status changes and cross-references.
- unless note.system
- event_service.leave_note(note, note.author)
+ note.update_attributes(params.merge(updated_by: current_user))
- # Create a cross-reference note if this Note contains GFM that
- # names an issue, merge request, or commit.
- note.references.each do |mentioned|
- SystemNoteService.cross_reference(mentioned, note.noteable, note.author)
- end
- end
- end
+ note.reset_events_cache
note
end
diff --git a/app/services/notification_service.rb b/app/services/notification_service.rb
index 312b56eb87b..3735a136365 100644
--- a/app/services/notification_service.rb
+++ b/app/services/notification_service.rb
@@ -70,12 +70,6 @@ class NotificationService
reassign_resource_email(merge_request, merge_request.target_project, current_user, 'reassigned_merge_request_email')
end
- # When we close a merge request we should send next emails:
- #
- # * merge_request author if their notification level is not Disabled
- # * merge_request assignee if their notification level is not Disabled
- # * project team members with notification level higher then Participating
- #
def close_mr(merge_request, current_user)
close_resource_email(merge_request, merge_request.target_project, current_user, 'closed_merge_request_email')
end
@@ -84,26 +78,8 @@ class NotificationService
reopen_resource_email(issue, issue.project, current_user, 'issue_status_changed_email', 'reopened')
end
- # When we merge a merge request we should send next emails:
- #
- # * merge_request author if their notification level is not Disabled
- # * merge_request assignee if their notification level is not Disabled
- # * project team members with notification level higher then Participating
- #
def merge_mr(merge_request, current_user)
- recipients = [merge_request.author, merge_request.assignee]
-
- recipients = add_project_watchers(recipients, merge_request.target_project)
- recipients = reject_muted_users(recipients, merge_request.target_project)
-
- recipients = add_subscribed_users(recipients, merge_request)
- recipients = reject_unsubscribed_users(recipients, merge_request)
-
- recipients.delete(current_user)
-
- recipients.each do |recipient|
- mailer.merged_merge_request_email(recipient.id, merge_request.id, current_user.id)
- end
+ close_resource_email(merge_request, merge_request.target_project, current_user, 'merged_merge_request_email')
end
def reopen_mr(merge_request, current_user)
@@ -364,8 +340,7 @@ class NotificationService
end
def new_resource_email(target, project, method)
- recipients = build_recipients(target, project)
- recipients.delete(target.author)
+ recipients = build_recipients(target, project, target.author)
recipients.each do |recipient|
mailer.send(method, recipient.id, target.id)
@@ -373,8 +348,7 @@ class NotificationService
end
def close_resource_email(target, project, current_user, method)
- recipients = build_recipients(target, project)
- recipients.delete(current_user)
+ recipients = build_recipients(target, project, current_user)
recipients.each do |recipient|
mailer.send(method, recipient.id, target.id, current_user.id)
@@ -383,8 +357,7 @@ class NotificationService
def reassign_resource_email(target, project, current_user, method)
assignee_id_was = previous_record(target, "assignee_id")
- recipients = build_recipients(target, project)
- recipients.delete(current_user)
+ recipients = build_recipients(target, project, current_user)
recipients.each do |recipient|
mailer.send(method, recipient.id, target.id, assignee_id_was, current_user.id)
@@ -392,21 +365,15 @@ class NotificationService
end
def reopen_resource_email(target, project, current_user, method, status)
- recipients = build_recipients(target, project)
- recipients.delete(current_user)
+ recipients = build_recipients(target, project, current_user)
recipients.each do |recipient|
mailer.send(method, recipient.id, target.id, status, current_user.id)
end
end
- def build_recipients(target, project)
- recipients =
- if target.respond_to?(:participants)
- target.participants
- else
- [target.author, target.assignee]
- end
+ def build_recipients(target, project, current_user)
+ recipients = target.participants(current_user)
recipients = add_project_watchers(recipients, project)
recipients = reject_mention_users(recipients, project)
@@ -415,6 +382,8 @@ class NotificationService
recipients = add_subscribed_users(recipients, target)
recipients = reject_unsubscribed_users(recipients, target)
+ recipients.delete(current_user)
+
recipients
end
diff --git a/app/services/post_commit_service.rb b/app/services/post_commit_service.rb
new file mode 100644
index 00000000000..7d7e5fbc32e
--- /dev/null
+++ b/app/services/post_commit_service.rb
@@ -0,0 +1,8 @@
+class PostCommitService < BaseService
+ def execute(sha, branch)
+ commit = repository.commit(sha)
+ full_ref = 'refs/heads/' + branch
+ old_sha = commit.parent_id || Gitlab::Git::BLANK_SHA
+ GitPushService.new.execute(project, current_user, old_sha, sha, full_ref)
+ end
+end
diff --git a/app/services/projects/destroy_service.rb b/app/services/projects/destroy_service.rb
index 403f419ec50..28872c89259 100644
--- a/app/services/projects/destroy_service.rb
+++ b/app/services/projects/destroy_service.rb
@@ -27,7 +27,6 @@ module Projects
end
end
- project.satellite.destroy
log_info("Project \"#{project.name}\" was removed")
system_hook_service.execute_hooks_for(project, :destroy)
true
diff --git a/app/services/projects/transfer_service.rb b/app/services/projects/transfer_service.rb
index f43c0ef70e9..550ed6897dd 100644
--- a/app/services/projects/transfer_service.rb
+++ b/app/services/projects/transfer_service.rb
@@ -33,9 +33,6 @@ module Projects
raise TransferError.new("Project with same path in target namespace already exists")
end
- # Remove old satellite
- project.satellite.destroy
-
# Apply new namespace id
project.namespace = new_namespace
project.save!
@@ -51,9 +48,6 @@ module Projects
# Move wiki repo also if present
gitlab_shell.mv_repository("#{old_path}.wiki", "#{new_path}.wiki")
- # Create a new satellite (reload project from DB)
- Project.find(project.id).ensure_satellite_exists
-
# clear project cached events
project.reset_events_cache
diff --git a/app/views/abuse_reports/new.html.haml b/app/views/abuse_reports/new.html.haml
new file mode 100644
index 00000000000..cffd7684008
--- /dev/null
+++ b/app/views/abuse_reports/new.html.haml
@@ -0,0 +1,24 @@
+- page_title "Report abuse"
+%h3.page-title Report abuse
+%p Please use this form to report users who create spam issues, comments or behave inappropriately.
+%hr
+= form_for @abuse_report, html: { class: 'form-horizontal'} do |f|
+ = f.hidden_field :user_id
+ - if @abuse_report.errors.any?
+ .alert.alert-danger
+ - @abuse_report.errors.full_messages.each do |msg|
+ %p= msg
+ .form-group
+ = f.label :user_id, class: 'control-label'
+ .col-sm-10
+ - name = "#{@abuse_report.user.name} (@#{@abuse_report.user.username})"
+ = text_field_tag :user_name, name, class: "form-control", readonly: true
+ .form-group
+ = f.label :message, class: 'control-label'
+ .col-sm-10
+ = f.text_area :message, class: "form-control", rows: 2, required: true
+ .help-block
+ Explain the problem with this user. If appropriate, provide a link to the relevant issue or comment.
+
+ .form-actions
+ = f.submit "Send report", class: "btn btn-create"
diff --git a/app/views/admin/abuse_reports/_abuse_report.html.haml b/app/views/admin/abuse_reports/_abuse_report.html.haml
new file mode 100644
index 00000000000..4449721ae38
--- /dev/null
+++ b/app/views/admin/abuse_reports/_abuse_report.html.haml
@@ -0,0 +1,23 @@
+- reporter = abuse_report.reporter
+- user = abuse_report.user
+%tr
+ %td
+ - if reporter
+ = link_to reporter.name, [:admin, reporter]
+ - else
+ (removed)
+ %td
+ = abuse_report.created_at.to_s(:short)
+ %td
+ = abuse_report.message
+ %td
+ - if user
+ = link_to user.name, [:admin, user]
+ - else
+ (removed)
+ %td
+ - if user
+ = link_to 'Block', block_admin_user_path(user), data: {confirm: 'USER WILL BE BLOCKED! Are you sure?'}, method: :put, class: "btn btn-xs btn-warning"
+ = link_to 'Remove user', [:admin, user], data: { confirm: "USER #{user.name} WILL BE REMOVED! Are you sure?" }, method: :delete, class: "btn btn-xs btn-remove"
+ %td
+ = link_to 'Remove report', [:admin, abuse_report], method: :delete, class: "btn btn-xs btn-close"
diff --git a/app/views/admin/abuse_reports/index.html.haml b/app/views/admin/abuse_reports/index.html.haml
new file mode 100644
index 00000000000..4a25848f156
--- /dev/null
+++ b/app/views/admin/abuse_reports/index.html.haml
@@ -0,0 +1,17 @@
+- page_title "Abuse Reports"
+%h3.page-title Abuse Reports
+%hr
+- if @abuse_reports.present?
+ %table.table
+ %thead
+ %tr
+ %th Reported by
+ %th Reported at
+ %th Message
+ %th User
+ %th
+ %th
+ = render @abuse_reports
+ = paginate @abuse_reports
+- else
+ %h4 There are no abuse reports
diff --git a/app/views/admin/users/show.html.haml b/app/views/admin/users/show.html.haml
index 33730ff05df..a383ea57384 100644
--- a/app/views/admin/users/show.html.haml
+++ b/app/views/admin/users/show.html.haml
@@ -105,6 +105,16 @@
.col-md-6
- unless @user == current_user
+ - unless @user.confirmed?
+ .panel.panel-info
+ .panel-heading
+ Confirm user
+ .panel-body
+ - if @user.unconfirmed_email.present?
+ - email = " (#{@user.unconfirmed_email})"
+ %p This user has an unconfirmed email address#{email}. You may force a confirmation.
+ %br
+ = link_to 'Confirm user', confirm_admin_user_path(@user), method: :put, class: "btn btn-info", data: { confirm: 'Are you sure?' }
- if @user.blocked?
.panel.panel-info
.panel-heading
diff --git a/app/views/events/_event.html.haml b/app/views/events/_event.html.haml
index 5ab5ffc238c..0377760a9b8 100644
--- a/app/views/events/_event.html.haml
+++ b/app/views/events/_event.html.haml
@@ -3,13 +3,11 @@
.event-item-timestamp
#{time_ago_with_tooltip(event.created_at)}
- - if event.created_project?
- = cache [event, current_user] do
- = image_tag avatar_icon(event.author_email, 24), class: "avatar s24", alt:''
- = render "events/event/created_project", event: event
- - else
+ = cache event, "v1" do
= image_tag avatar_icon(event.author_email, 24), class: "avatar s24", alt:''
- - if event.push?
+ - if event.created_project?
+ = render "events/event/created_project", event: event
+ - elsif event.push?
= render "events/event/push", event: event
- elsif event.commented?
= render "events/event/note", event: event
diff --git a/app/views/events/event/_created_project.html.haml b/app/views/events/event/_created_project.html.haml
index c2577a24982..8cf36c711b4 100644
--- a/app/views/events/event/_created_project.html.haml
+++ b/app/views/events/event/_created_project.html.haml
@@ -8,8 +8,8 @@
- else
= event.project_name
-- if current_user == event.author && !event.project.private? && twitter_sharing_enabled?
- .event-body
+- if !event.project.private? && twitter_sharing_enabled?
+ .event-body{"data-user-is" => event.author_id}
.event-note
.md
%p
diff --git a/app/views/events/event/_push.html.haml b/app/views/events/event/_push.html.haml
index 34a7c00dc43..8bed5cdb9cc 100644
--- a/app/views/events/event/_push.html.haml
+++ b/app/views/events/event/_push.html.haml
@@ -17,7 +17,7 @@
- few_commits.each do |commit|
= render "events/commit", commit: commit, project: project
- - create_mr = current_user == event.author && event.new_ref? && create_mr_button?(event.project.default_branch, event.ref_name, event.project)
+ - create_mr = event.new_ref? && create_mr_button?(event.project.default_branch, event.ref_name, event.project)
- if event.commits_count > 1
%li.commits-stat
- if event.commits_count > 2
@@ -34,10 +34,11 @@
Compare #{from_label}...#{truncate_sha(event.commit_to)}
- if create_mr
- or
- = link_to create_mr_path(event.project.default_branch, event.ref_name, event.project) do
- create a merge request
+ %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
+ create a merge request
- elsif create_mr
- %li.commits-stat
+ %li.commits-stat{"data-user-is" => event.author_id}
= link_to create_mr_path(event.project.default_branch, event.ref_name, event.project) do
Create Merge Request
diff --git a/app/views/explore/projects/_project.html.haml b/app/views/explore/projects/_project.html.haml
index d769c91545d..1e8a89e3661 100644
--- a/app/views/explore/projects/_project.html.haml
+++ b/app/views/explore/projects/_project.html.haml
@@ -9,8 +9,8 @@
.project-info
- if project.description.present?
- %p.project-description.str-truncated
- = project.description
+ .project-description.str-truncated
+ = markdown(project.description, pipeline: :description)
.repo-info
- unless project.empty_repo?
diff --git a/app/views/import/bitbucket/status.html.haml b/app/views/import/bitbucket/status.html.haml
index 9d2858e4e72..98ae509096e 100644
--- a/app/views/import/bitbucket/status.html.haml
+++ b/app/views/import/bitbucket/status.html.haml
@@ -3,11 +3,16 @@
%i.fa.fa-bitbucket
Import projects from Bitbucket
-%p.light
- Select projects you want to import.
-%hr
-%p
- = button_tag 'Import all projects', class: "btn btn-success js-import-all"
+- if @repos.any?
+ %p.light
+ Select projects you want to import.
+ %hr
+ %p
+ - if @incompatible_repos.any?
+ = button_tag 'Import all compatible projects', class: "btn btn-success js-import-all"
+ - else
+ = button_tag 'Import all projects', class: "btn btn-success js-import-all"
+
%table.table.import-jobs
%thead
@@ -41,6 +46,24 @@
= "#{repo["owner"]}/#{repo["slug"]}"
%td.import-actions.job-status
= button_tag "Import", class: "btn js-add-to-import"
+ - @incompatible_repos.each do |repo|
+ %tr{id: "repo_#{repo["owner"]}___#{repo["slug"]}"}
+ %td
+ = link_to "#{repo["owner"]}/#{repo["slug"]}", "https://bitbucket.org/#{repo["owner"]}/#{repo["slug"]}", target: "_blank"
+ %td.import-target
+ %td.import-actions-job-status
+ = label_tag "Incompatible Project", nil, class: "label label-danger"
+
+- if @incompatible_repos.any?
+ %p
+ One or more of your Bitbucket projects cannot be imported into GitLab
+ directly because they use Subversion or Mercurial for version control,
+ rather than Git. Please convert
+ = link_to "them to Git,", "https://www.atlassian.com/git/tutorials/migrating-overview"
+ and go through the
+ = link_to "import flow", status_import_bitbucket_path
+ again.
+
:coffeescript
new ImporterStatus("#{jobs_import_bitbucket_path}", "#{import_bitbucket_path}")
diff --git a/app/views/layouts/_head.html.haml b/app/views/layouts/_head.html.haml
index 54cddc30b74..397649dacf8 100644
--- a/app/views/layouts/_head.html.haml
+++ b/app/views/layouts/_head.html.haml
@@ -27,7 +27,7 @@
= favicon_link_tag 'touch-icon-ipad-retina.png', rel: 'apple-touch-icon', sizes: '152x152'
-# Windows 8 pinned site tile
- %meta{name: 'msapplication-TileImage', content: image_url('msapplication-tile.png')}
+ %meta{name: 'msapplication-TileImage', content: image_path('msapplication-tile.png')}
%meta{name: 'msapplication-TileColor', content: '#30353E'}
= yield :meta_tags
@@ -35,3 +35,5 @@
= render 'layouts/google_analytics' if extra_config.has_key?('google_analytics_id')
= render 'layouts/piwik' if extra_config.has_key?('piwik_url') && extra_config.has_key?('piwik_site_id')
= render 'layouts/bootlint' if Rails.env.development?
+
+ = render 'layouts/user_styles'
diff --git a/app/views/layouts/_user_styles.html.haml b/app/views/layouts/_user_styles.html.haml
new file mode 100644
index 00000000000..b76b3cb5510
--- /dev/null
+++ b/app/views/layouts/_user_styles.html.haml
@@ -0,0 +1,24 @@
+:css
+ [data-user-is] {
+ display: none !important;
+ }
+
+ [data-user-is="#{current_user.try(:id)}"] {
+ display: block !important;
+ }
+
+ [data-user-is="#{current_user.try(:id)}"][data-display="inline"] {
+ display: inline !important;
+ }
+
+ [data-user-is-not] {
+ display: block !important;
+ }
+
+ [data-user-is-not][data-display="inline"] {
+ display: inline !important;
+ }
+
+ [data-user-is-not="#{current_user.try(:id)}"] {
+ display: none !important;
+ }
diff --git a/app/views/layouts/nav/_admin.html.haml b/app/views/layouts/nav/_admin.html.haml
index a3191593dae..2065be3828a 100644
--- a/app/views/layouts/nav/_admin.html.haml
+++ b/app/views/layouts/nav/_admin.html.haml
@@ -57,6 +57,13 @@
%span
Service Templates
+ = nav_link(controller: :abuse_reports) do
+ = link_to admin_abuse_reports_path, title: "Abuse reports" do
+ = icon('exclamation-circle fw')
+ %span
+ Abuse Reports
+ %span.count= AbuseReport.count(:all)
+
= nav_link(controller: :application_settings, html_options: { class: 'separate-item'}) do
= link_to admin_application_settings_path, title: 'Settings', data: {placement: 'right'} do
= icon('cogs fw')
diff --git a/app/views/projects/_home_panel.html.haml b/app/views/projects/_home_panel.html.haml
index 7b6b4b35c8d..71e92970305 100644
--- a/app/views/projects/_home_panel.html.haml
+++ b/app/views/projects/_home_panel.html.haml
@@ -3,6 +3,7 @@
.project-identicon-holder
= project_icon(@project, alt: '', class: 'project-avatar avatar s90')
.project-home-desc.lead
+ %h1= @project.name
- if @project.description.present?
= markdown(@project.description, pipeline: :description)
@@ -20,8 +21,14 @@
= forked_from_project.namespace.try(:name)
- if can? current_user, :download_code, @project
+ = link_to "#", class: 'btn js-toggle-clone-holder' do
+ = icon('cloud-download fw')
+ Clone
+
+ - if can? current_user, :download_code, @project
= link_to archive_namespace_project_repository_path(@project.namespace, @project, ref: @ref, format: 'zip'), class: 'btn', rel: 'nofollow' do
- %i.fa.fa-download
+ = icon('download fw')
+ Download
= render 'projects/buttons/dropdown'
diff --git a/app/views/projects/buttons/_dropdown.html.haml b/app/views/projects/buttons/_dropdown.html.haml
index 99c2ed62545..cade930c8cc 100644
--- a/app/views/projects/buttons/_dropdown.html.haml
+++ b/app/views/projects/buttons/_dropdown.html.haml
@@ -1,31 +1,32 @@
- if current_user
%span.dropdown
%a.dropdown-toggle.btn.btn-new{href: '#', "data-toggle" => "dropdown"}
- %i.fa.fa-plus
+ = icon('plus')
%ul.dropdown-menu
- - if @project.issues_enabled && can?(current_user, :create_issue, @project)
+ - if can?(current_user, :create_issue, @project)
%li
- = link_to url_for_new_issue, title: "New Issue" do
+ = link_to url_for_new_issue do
+ = icon('exclamation-circle fw')
New issue
- - if @project.merge_requests_enabled && can?(current_user, :create_merge_request, @project)
+ - if can?(current_user, :create_merge_request, @project)
%li
- = link_to new_namespace_project_merge_request_path(@project.namespace, @project), title: "New Merge Request" do
+ = link_to new_namespace_project_merge_request_path(@project.namespace, @project) do
+ = icon('tasks fw')
New merge request
- - if @project.snippets_enabled && can?(current_user, :create_snippet, @project)
+ - if can?(current_user, :create_snippet, @project)
%li
- = link_to new_namespace_project_snippet_path(@project.namespace, @project), title: "New Snippet" do
+ = link_to new_namespace_project_snippet_path(@project.namespace, @project) do
+ = icon('file-text-o fw')
New snippet
- - if can?(current_user, :admin_project_member, @project)
- %li
- = link_to namespace_project_project_members_path(@project.namespace, @project), title: "New project member" do
- New project member
- - if can? current_user, :push_code, @project
+ - if can?(current_user, :push_code, @project)
%li.divider
%li
= link_to new_namespace_project_branch_path(@project.namespace, @project) do
- New git branch
+ = icon('code-fork fw')
+ New branch
%li
= link_to new_namespace_project_tag_path(@project.namespace, @project) do
- New git tag
+ = icon('tags fw')
+ New tag
diff --git a/app/views/projects/buttons/_fork.html.haml b/app/views/projects/buttons/_fork.html.haml
index f0483c79edc..854c154824d 100644
--- a/app/views/projects/buttons/_fork.html.haml
+++ b/app/views/projects/buttons/_fork.html.haml
@@ -1,13 +1,13 @@
- if current_user && can?(current_user, :fork_project, @project)
- if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2
= link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: 'Go to your fork', class: 'btn' do
- = icon('code-fork')
+ = icon('code-fork fw')
Fork
%span.count
= @project.forks_count
- else
= link_to new_namespace_project_fork_path(@project.namespace, @project), title: "Fork project", class: 'btn' do
- = icon('code-fork')
+ = icon('code-fork fw')
Fork
%span.count
= @project.forks_count
diff --git a/app/views/projects/buttons/_star.html.haml b/app/views/projects/buttons/_star.html.haml
index b5f14b43bfd..5d7df5ae099 100644
--- a/app/views/projects/buttons/_star.html.haml
+++ b/app/views/projects/buttons/_star.html.haml
@@ -1,6 +1,6 @@
- if current_user
= link_to toggle_star_namespace_project_path(@project.namespace, @project), class: 'btn star-btn toggle-star', method: :post, remote: true do
- = icon('star')
+ = icon('star fw')
- if current_user.starred?(@project)
Unstar
- else
@@ -16,7 +16,7 @@
- else
= link_to new_user_session_path, class: 'btn has_tooltip star-btn', title: 'You must sign in to star a project' do
- = icon('star')
+ = icon('star fw')
Star
%span.count
= @project.star_count
diff --git a/app/views/projects/issues/show.html.haml b/app/views/projects/issues/show.html.haml
index 54d33a5ddd1..e7b14e7582c 100644
--- a/app/views/projects/issues/show.html.haml
+++ b/app/views/projects/issues/show.html.haml
@@ -9,7 +9,13 @@
Open
Issue ##{@issue.iid}
%small.creator
- &middot; created by #{link_to_member(@project, @issue.author)} #{issue_timestamp(@issue)}
+ &middot; created by #{link_to_member(@project, @issue.author)}
+ = time_ago_with_tooltip(@issue.created_at, placement: 'bottom', html_class: 'issue_created_ago')
+ - if @issue.updated_at != @issue.created_at
+ %span
+ &middot;
+ = icon('edit', title: 'edited')
+ = time_ago_with_tooltip(@issue.updated_at, placement: 'bottom', html_class: 'issue_edited_ago')
.pull-right
- if can?(current_user, :create_issue, @project)
diff --git a/app/views/projects/merge_requests/_new_compare.html.haml b/app/views/projects/merge_requests/_new_compare.html.haml
index ff9c0cdb283..7709330611a 100644
--- a/app/views/projects/merge_requests/_new_compare.html.haml
+++ b/app/views/projects/merge_requests/_new_compare.html.haml
@@ -35,7 +35,7 @@
- if @merge_request.compare_failed
.alert.alert-danger
%h4 Compare failed
- %p We can't compare selected branches. It may be because of huge diff or satellite timeout. Please try again or select different branches.
+ %p We can't compare selected branches. It may be because of huge diff. Please try again or select different branches.
- else
.light-well
.center
diff --git a/app/views/projects/merge_requests/_new_submit.html.haml b/app/views/projects/merge_requests/_new_submit.html.haml
index 633a54f3620..76f44211dac 100644
--- a/app/views/projects/merge_requests/_new_submit.html.haml
+++ b/app/views/projects/merge_requests/_new_submit.html.haml
@@ -24,7 +24,7 @@
= icon('history')
Commits
%span.badge= @commits.size
- %li.diffs-tab
+ %li.diffs-tab.active
= link_to url_for(params), data: {target: '#diffs', action: 'diffs', toggle: 'tab'} do
= icon('list-alt')
Changes
@@ -33,7 +33,7 @@
.tab-content
#commits.commits.tab-pane
= render "projects/commits/commits", project: @project
- #diffs.diffs.tab-pane
+ #diffs.diffs.tab-pane.active
- if @diffs.present?
= render "projects/diffs/diffs", diffs: @diffs, project: @project
- elsif @commits.size > MergeRequestDiff::COMMITS_SAFE_SIZE
diff --git a/app/views/projects/merge_requests/_show.html.haml b/app/views/projects/merge_requests/_show.html.haml
index c57eee14143..2662e3aff6b 100644
--- a/app/views/projects/merge_requests/_show.html.haml
+++ b/app/views/projects/merge_requests/_show.html.haml
@@ -6,40 +6,25 @@
= render "projects/merge_requests/show/mr_box"
%hr
.append-bottom-20
- .slead
- %span From
- - if @merge_request.for_fork?
- %strong.label-branch<
- - if @merge_request.source_project
- = link_to @merge_request.source_project_namespace, namespace_project_path(@merge_request.source_project.namespace, @merge_request.source_project)
- - else
- \ #{@merge_request.source_project_namespace}
- \:#{@merge_request.source_branch}
+ - if @merge_request.open?
+ .btn-group.btn-group-sm.pull-right
+ %a.btn.btn-sm.dropdown-toggle{ data: {toggle: :dropdown} }
+ = icon('download')
+ Download as
+ %span.caret
+ %ul.dropdown-menu
+ %li= link_to "Email Patches", merge_request_path(@merge_request, format: :patch)
+ %li= link_to "Plain Diff", merge_request_path(@merge_request, format: :diff)
+ .light
+ %div
+ %span From
+ %span.label-branch #{source_branch_with_namespace(@merge_request)}
%span into
- %strong.label-branch #{@merge_request.target_project_namespace}:#{@merge_request.target_branch}
- - else
- %strong.label-branch #{@merge_request.source_branch}
- %span into
- %strong.label-branch #{@merge_request.target_branch}
- - if @merge_request.open?
- .btn-group.btn-group-sm.pull-right
- %a.btn.btn-sm.dropdown-toggle{ data: {toggle: :dropdown} }
- = icon('download')
- Download as
- %span.caret
- %ul.dropdown-menu
- %li= link_to "Email Patches", merge_request_path(@merge_request, format: :patch)
- %li= link_to "Plain Diff", merge_request_path(@merge_request, format: :diff)
-
- - if @merge_request.open? and @merge_request.source_branch_exists?
- .append-bottom-20
- .slead
- %span
- Fetch the branch with
- %strong.label-branch<
- git fetch
- \ #{@merge_request.source_project.http_url_to_repo}
- \ #{@merge_request.source_branch}
+ %span.label-branch #{@merge_request.target_branch}
+ - if @merge_request.open? && !@merge_request.branch_missing?
+ %div
+ If you want to try or merge this request manually, you can use the
+ = link_to "command line", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal"
= render "projects/merge_requests/show/how_to_merge"
= render "projects/merge_requests/widget/show.html.haml"
diff --git a/app/views/projects/merge_requests/automerge.js.haml b/app/views/projects/merge_requests/merge.js.haml
index 33321651e32..33321651e32 100644
--- a/app/views/projects/merge_requests/automerge.js.haml
+++ b/app/views/projects/merge_requests/merge.js.haml
diff --git a/app/views/projects/merge_requests/show/_commits.html.haml b/app/views/projects/merge_requests/show/_commits.html.haml
index 3b7f283daf0..a71b181a6a5 100644
--- a/app/views/projects/merge_requests/show/_commits.html.haml
+++ b/app/views/projects/merge_requests/show/_commits.html.haml
@@ -1 +1 @@
-= render "projects/commits/commits", project: @merge_request.source_project
+= render "projects/commits/commits", project: @merge_request.project
diff --git a/app/views/projects/merge_requests/show/_diffs.html.haml b/app/views/projects/merge_requests/show/_diffs.html.haml
index 786b5f39063..626970f39be 100644
--- a/app/views/projects/merge_requests/show/_diffs.html.haml
+++ b/app/views/projects/merge_requests/show/_diffs.html.haml
@@ -1,5 +1,5 @@
- if @merge_request_diff.collected?
- = render "projects/diffs/diffs", diffs: @merge_request.diffs, project: @merge_request.source_project
+ = render "projects/diffs/diffs", diffs: @merge_request.diffs, project: @merge_request.project
- elsif @merge_request_diff.empty?
.nothing-here-block Nothing to merge from #{@merge_request.source_branch} into #{@merge_request.target_branch}
- else
diff --git a/app/views/projects/merge_requests/show/_mr_title.html.haml b/app/views/projects/merge_requests/show/_mr_title.html.haml
index 4e8144b4de2..9a1eb36fc88 100644
--- a/app/views/projects/merge_requests/show/_mr_title.html.haml
+++ b/app/views/projects/merge_requests/show/_mr_title.html.haml
@@ -1,10 +1,16 @@
%h4.page-title
.issue-box{ class: issue_box_class(@merge_request) }
= @merge_request.state_human_name
- = "Merge Request ##{@merge_request.iid}"
+ Merge Request ##{@merge_request.iid}
%small.creator
&middot;
- created by #{link_to_member(@project, @merge_request.author)} #{time_ago_with_tooltip(@merge_request.created_at)}
+ created by #{link_to_member(@project, @merge_request.author)}
+ = time_ago_with_tooltip(@merge_request.created_at)
+ - if @merge_request.updated_at != @merge_request.created_at
+ %span
+ &middot;
+ = icon('edit', title: 'edited')
+ = time_ago_with_tooltip(@merge_request.updated_at, placement: 'bottom')
.issue-btn-group.pull-right
- if can?(current_user, :update_merge_request, @merge_request)
diff --git a/app/views/projects/merge_requests/widget/_heading.html.haml b/app/views/projects/merge_requests/widget/_heading.html.haml
index 4cc9c652b61..17d529766e6 100644
--- a/app/views/projects/merge_requests/widget/_heading.html.haml
+++ b/app/views/projects/merge_requests/widget/_heading.html.haml
@@ -1,22 +1,14 @@
- if @merge_request.has_ci?
.mr-widget-heading
- .ci_widget.ci-success{style: "display:none"}
- = icon("check")
- %span CI build passed
- for #{@merge_request.last_commit_short_sha}.
- = link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink"
-
- .ci_widget.ci-failed{style: "display:none"}
- = icon("times")
- %span CI build failed
- for #{@merge_request.last_commit_short_sha}.
- = link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink"
-
- - [:running, :pending].each do |status|
+ - [:success, :skipped, :canceled, :failed, :running, :pending].each do |status|
.ci_widget{class: "ci-#{status}", style: "display:none"}
- = icon("clock-o")
+ - if status == :success
+ = icon("check-circle")
+ - else
+ = icon("circle")
%span CI build #{status}
for #{@merge_request.last_commit_short_sha}.
+ %span.ci-coverage
= link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink"
.ci_widget
@@ -24,19 +16,12 @@
Checking for CI status for #{@merge_request.last_commit_short_sha}
.ci_widget.ci-not_found{style: "display:none"}
- = icon("times")
+ = icon("times-circle")
%span Can not find commit in the CI server
for #{@merge_request.last_commit_short_sha}.
-
-
- .ci_widget.ci-canceled{style: "display:none"}
- = icon("times")
- %span CI build canceled
- for #{@merge_request.last_commit_short_sha}.
- = link_to "View build page", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink"
.ci_widget.ci-error{style: "display:none"}
- = icon("times")
+ = icon("times-circle")
%span Cannot connect to the CI server. Please check your settings and try again.
:coffeescript
diff --git a/app/views/projects/merge_requests/widget/_open.html.haml b/app/views/projects/merge_requests/widget/_open.html.haml
index bb794912f8f..f420cdcab49 100644
--- a/app/views/projects/merge_requests/widget/_open.html.haml
+++ b/app/views/projects/merge_requests/widget/_open.html.haml
@@ -3,8 +3,6 @@
.mr-widget-body
- if @project.archived?
= render 'projects/merge_requests/widget/open/archived'
- - elsif !@project.satellite.exists?
- = render 'projects/merge_requests/widget/open/no_satellite'
- elsif @merge_request.commits.blank?
= render 'projects/merge_requests/widget/open/nothing'
- elsif @merge_request.branch_missing?
diff --git a/app/views/projects/merge_requests/widget/_show.html.haml b/app/views/projects/merge_requests/widget/_show.html.haml
index 263cab7a9e8..a489d4f9b24 100644
--- a/app/views/projects/merge_requests/widget/_show.html.haml
+++ b/app/views/projects/merge_requests/widget/_show.html.haml
@@ -11,10 +11,10 @@
var merge_request_widget;
merge_request_widget = new MergeRequestWidget({
- url_to_automerge_check: "#{automerge_check_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}",
+ url_to_automerge_check: "#{merge_check_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}",
check_enable: #{@merge_request.unchecked? ? "true" : "false"},
url_to_ci_check: "#{ci_status_namespace_project_merge_request_path(@project.namespace, @project, @merge_request)}",
ci_enable: #{@project.ci_service ? "true" : "false"},
- current_status: "#{@merge_request.automerge_status}",
+ current_status: "#{@merge_request.gitlab_merge_status}",
});
diff --git a/app/views/projects/merge_requests/widget/open/_accept.html.haml b/app/views/projects/merge_requests/widget/open/_accept.html.haml
index f5bacaf280a..1be98cbe8de 100644
--- a/app/views/projects/merge_requests/widget/open/_accept.html.haml
+++ b/app/views/projects/merge_requests/widget/open/_accept.html.haml
@@ -1,4 +1,4 @@
-= form_for [:automerge, @project.namespace.becomes(Namespace), @project, @merge_request], remote: true, method: :post, html: { class: 'accept-mr-form js-requires-input' } do |f|
+= form_for [:merge, @project.namespace.becomes(Namespace), @project, @merge_request], remote: true, method: :post, html: { class: 'accept-mr-form js-requires-input' } do |f|
= hidden_field_tag :authenticity_token, form_authenticity_token
.accept-merge-holder.clearfix.js-toggle-container
.accept-action
@@ -18,12 +18,6 @@
text: @merge_request.merge_commit_message,
rows: 14, hint: true
- %br
- .light
- If you want to merge this request manually, you can use the
- %strong
- = link_to "command line", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal"
-
:coffeescript
$('.accept-mr-form').on 'ajax:before', ->
btn = $('.accept_merge_request')
diff --git a/app/views/projects/merge_requests/widget/open/_conflicts.html.haml b/app/views/projects/merge_requests/widget/open/_conflicts.html.haml
index d1db5fec43a..440a7aa1c61 100644
--- a/app/views/projects/merge_requests/widget/open/_conflicts.html.haml
+++ b/app/views/projects/merge_requests/widget/open/_conflicts.html.haml
@@ -1,9 +1,11 @@
+%h4
+ This merge request contains merge conflicts that must be resolved.
+
- if @merge_request.can_be_merged_by?(current_user)
- %h4
- This merge request contains merge conflicts that must be resolved.
- You can try it manually on the
+ %p
+ You can merge it manually using the
%strong
= link_to "command line", "#modal_merge_info", class: "how_to_merge_link vlink", title: "How To Merge", "data-toggle" => "modal"
- else
- %strong This merge request contains merge conflicts that must be resolved.
- Only those with write access to this repository can merge merge requests.
+ %p
+ Only those with write access to this repository can merge merge requests.
diff --git a/app/views/projects/merge_requests/widget/open/_no_satellite.html.haml b/app/views/projects/merge_requests/widget/open/_no_satellite.html.haml
deleted file mode 100644
index 3718cfd8333..00000000000
--- a/app/views/projects/merge_requests/widget/open/_no_satellite.html.haml
+++ /dev/null
@@ -1,3 +0,0 @@
-%p
- %span
- %strong This repository does not have a satellite. Please ask an administrator to fix this issue!
diff --git a/app/views/projects/notes/_note.html.haml b/app/views/projects/notes/_note.html.haml
index 4a1009686c6..de75d44fc41 100644
--- a/app/views/projects/notes/_note.html.haml
+++ b/app/views/projects/notes/_note.html.haml
@@ -33,7 +33,14 @@
%span.note-last-update
= link_to "##{dom_id(note)}", name: dom_id(note), title: "Link here" do
- = note_timestamp(note)
+ = time_ago_with_tooltip(note.created_at, placement: 'bottom', html_class: 'note_created_ago')
+ - if note.updated_at != note.created_at
+ %span
+ &middot;
+ = icon('edit', title: 'edited')
+ = time_ago_with_tooltip(note.updated_at, placement: 'bottom', html_class: 'note_edited_ago')
+ - if note.updated_by && note.updated_by != note.author
+ by #{link_to_member(note.project, note.updated_by, avatar: false, author_class: nil)}
- if note.superceded?(@notes)
- if note.upvote?
diff --git a/app/views/projects/notes/discussions/_diff.html.haml b/app/views/projects/notes/discussions/_diff.html.haml
index 711aa39101b..0301445b5b2 100644
--- a/app/views/projects/notes/discussions/_diff.html.haml
+++ b/app/views/projects/notes/discussions/_diff.html.haml
@@ -12,18 +12,19 @@
.diff-content
%table
- note.truncated_diff_lines.each do |line|
+ - type = line.type
- line_code = generate_line_code(note.file_path, line)
- %tr.line_holder{ id: line_code }
- - if line.type == "match"
+ %tr.line_holder{ id: line_code, class: "#{type}" }
+ - if type == "match"
%td.old_line= "..."
%td.new_line= "..."
%td.line_content.matched= line.text
- else
- %td.old_line{class: line.type == "new" ? "new" : "old"}
- = raw(line.type == "new" ? "&nbsp;" : line.old_pos)
- %td.new_line{class: line.type == "new" ? "new" : "old"}
- = raw(line.type == "old" ? "&nbsp;" : line.new_pos)
- %td.line_content{class: "noteable_line #{line.type} #{line_code}", "line_code" => line_code}= raw diff_line_content(line.text)
+ %td.old_line
+ = raw(type == "new" ? "&nbsp;" : line.old_pos)
+ %td.new_line
+ = raw(type == "old" ? "&nbsp;" : line.new_pos)
+ %td.line_content{class: "noteable_line #{type} #{line_code}", "line_code" => line_code}= raw diff_line_content(line.text)
- if line_code == note.line_code
= render "projects/notes/diff_notes_with_reply", notes: discussion_notes
diff --git a/app/views/users/show.html.haml b/app/views/users/show.html.haml
index 43d847831d6..64b7f25ad37 100644
--- a/app/views/users/show.html.haml
+++ b/app/views/users/show.html.haml
@@ -18,6 +18,16 @@
= link_to profile_path, class: 'btn btn-sm' do
%i.fa.fa-pencil-square-o
Edit Profile settings
+ - elsif current_user
+ .pull-right
+ %span.dropdown
+ %a.light.dropdown-toggle.btn.btn-sm{href: '#', "data-toggle" => "dropdown"}
+ = icon('exclamation-circle')
+ %ul.dropdown-menu.dropdown-menu-right
+ %li
+ = link_to new_abuse_report_path(user_id: @user.id) do
+ Report abuse
+
.username
@#{@user.username}
.description
diff --git a/app/workers/auto_merge_worker.rb b/app/workers/auto_merge_worker.rb
deleted file mode 100644
index a6dd73eee5f..00000000000
--- a/app/workers/auto_merge_worker.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-class AutoMergeWorker
- include Sidekiq::Worker
-
- sidekiq_options queue: :default
-
- def perform(merge_request_id, current_user_id, params)
- params = params.with_indifferent_access
- current_user = User.find(current_user_id)
- merge_request = MergeRequest.find(merge_request_id)
- merge_request.should_remove_source_branch = params[:should_remove_source_branch]
- merge_request.automerge!(current_user, params[:commit_message])
- end
-end
diff --git a/app/workers/merge_worker.rb b/app/workers/merge_worker.rb
new file mode 100644
index 00000000000..6a8665c179a
--- /dev/null
+++ b/app/workers/merge_worker.rb
@@ -0,0 +1,19 @@
+class MergeWorker
+ include Sidekiq::Worker
+
+ sidekiq_options queue: :default
+
+ def perform(merge_request_id, current_user_id, params)
+ params = params.with_indifferent_access
+ current_user = User.find(current_user_id)
+ merge_request = MergeRequest.find(merge_request_id)
+
+ result = MergeRequests::MergeService.new(merge_request.target_project, current_user).
+ execute(merge_request, params[:commit_message])
+
+ if result[:status] == :success && params[:should_remove_source_branch].present?
+ DeleteBranchService.new(merge_request.source_project, current_user).
+ execute(merge_request.source_branch)
+ end
+ end
+end
diff --git a/app/workers/repository_import_worker.rb b/app/workers/repository_import_worker.rb
index 94832872d13..b546f8777e1 100644
--- a/app/workers/repository_import_worker.rb
+++ b/app/workers/repository_import_worker.rb
@@ -27,7 +27,6 @@ class RepositoryImportWorker
project.import_finish
project.save
- project.satellite.create unless project.satellite.exists?
ProjectCacheWorker.perform_async(project.id)
Gitlab::BitbucketImport::KeyDeleter.new(project).execute if project.import_type == 'bitbucket'
end
diff --git a/config/routes.rb b/config/routes.rb
index 2e16c3ecb39..d7307a61ede 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -65,6 +65,9 @@ Gitlab::Application.routes.draw do
end
end
+ # Spam reports
+ resources :abuse_reports, only: [:new, :create]
+
#
# Import
#
@@ -159,11 +162,13 @@ Gitlab::Application.routes.draw do
put :block
put :unblock
put :unlock
+ put :confirm
patch :disable_two_factor
delete 'remove/:email_id', action: 'remove_email', as: 'remove_email'
end
end
+ resources :abuse_reports, only: [:index, :destroy]
resources :applications
resources :groups, constraints: { id: /[^\/]+/ } do
@@ -458,8 +463,8 @@ Gitlab::Application.routes.draw do
member do
get :diffs
get :commits
- post :automerge
- get :automerge_check
+ post :merge
+ get :merge_check
get :ci_status
post :toggle_subscription
end
diff --git a/db/migrate/20150730122406_add_updated_by_to_issuables_and_notes.rb b/db/migrate/20150730122406_add_updated_by_to_issuables_and_notes.rb
new file mode 100644
index 00000000000..78d45c7f96b
--- /dev/null
+++ b/db/migrate/20150730122406_add_updated_by_to_issuables_and_notes.rb
@@ -0,0 +1,7 @@
+class AddUpdatedByToIssuablesAndNotes < ActiveRecord::Migration
+ def change
+ add_column :notes, :updated_by_id, :integer
+ add_column :issues, :updated_by_id, :integer
+ add_column :merge_requests, :updated_by_id, :integer
+ end
+end
diff --git a/db/migrate/20150806104937_create_abuse_reports.rb b/db/migrate/20150806104937_create_abuse_reports.rb
new file mode 100644
index 00000000000..e97dc4cf04c
--- /dev/null
+++ b/db/migrate/20150806104937_create_abuse_reports.rb
@@ -0,0 +1,11 @@
+class CreateAbuseReports < ActiveRecord::Migration
+ def change
+ create_table :abuse_reports do |t|
+ t.integer :reporter_id
+ t.integer :user_id
+ t.text :message
+
+ t.timestamps
+ end
+ end
+end
diff --git a/db/schema.rb b/db/schema.rb
index a63c2d05821..6e919f2883b 100644
--- a/db/schema.rb
+++ b/db/schema.rb
@@ -11,11 +11,19 @@
#
# It's strongly recommended that you check this file into your version control system.
-ActiveRecord::Schema.define(version: 20150717130904) do
+ActiveRecord::Schema.define(version: 20150806104937) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
+ create_table "abuse_reports", force: true do |t|
+ t.integer "reporter_id"
+ t.integer "user_id"
+ t.text "message"
+ t.datetime "created_at"
+ t.datetime "updated_at"
+ end
+
create_table "application_settings", force: true do |t|
t.integer "default_projects_limit"
t.boolean "signup_enabled"
@@ -128,12 +136,13 @@ ActiveRecord::Schema.define(version: 20150717130904) do
t.integer "project_id"
t.datetime "created_at"
t.datetime "updated_at"
- t.integer "position", default: 0
+ t.integer "position", default: 0
t.string "branch_name"
t.text "description"
t.integer "milestone_id"
t.string "state"
t.integer "iid"
+ t.integer "updated_by_id"
end
add_index "issues", ["assignee_id"], name: "index_issues_on_assignee_id", using: :btree
@@ -230,6 +239,7 @@ ActiveRecord::Schema.define(version: 20150717130904) do
t.text "description"
t.integer "position", default: 0
t.datetime "locked_at"
+ t.integer "updated_by_id"
end
add_index "merge_requests", ["assignee_id"], name: "index_merge_requests_on_assignee_id", using: :btree
@@ -289,6 +299,7 @@ ActiveRecord::Schema.define(version: 20150717130904) do
t.integer "noteable_id"
t.boolean "system", default: false, null: false
t.text "st_diff"
+ t.integer "updated_by_id"
end
add_index "notes", ["author_id"], name: "index_notes_on_author_id", using: :btree
diff --git a/doc/development/architecture.md b/doc/development/architecture.md
index 541af487bb1..c00d290371e 100644
--- a/doc/development/architecture.md
+++ b/doc/development/architecture.md
@@ -56,9 +56,9 @@ To serve repositories over SSH there's an add-on application called gitlab-shell
A typical install of GitLab will be on GNU/Linux. It uses Nginx or Apache as a web front end to proxypass the Unicorn web server. By default, communication between Unicorn and the front end is via a Unix domain socket but forwarding requests via TCP is also supported. The web front end accesses `/home/git/gitlab/public` bypassing the Unicorn server to serve static pages, uploads (e.g. avatar images or attachments), and precompiled assets. GitLab serves web pages and a [GitLab API](https://gitlab.com/gitlab-org/gitlab-ce/tree/master/doc/api) using the Unicorn web server. It uses Sidekiq as a job queue which, in turn, uses redis as a non-persistent database backend for job information, meta data, and incoming jobs.
-The GitLab web app uses MySQL or PostgreSQL for persistent database information (e.g. users, permissions, issues, other meta data). GitLab stores the bare git repositories it serves in `/home/git/repositories` by default. It also keeps default branch and hook information with the bare repository. `/home/git/gitlab-satellites` keeps checked out repositories when performing actions such as a merge request, editing files in the web interface, etc.
+The GitLab web app uses MySQL or PostgreSQL for persistent database information (e.g. users, permissions, issues, other meta data). GitLab stores the bare git repositories it serves in `/home/git/repositories` by default. It also keeps default branch and hook information with the bare repository.
-The satellite repository is used by the web interface for editing repositories and the wiki which is also a git repository. When serving repositories over HTTP/HTTPS GitLab utilizes the GitLab API to resolve authorization and access as well as serving git objects.
+When serving repositories over HTTP/HTTPS GitLab utilizes the GitLab API to resolve authorization and access as well as serving git objects.
The add-on component gitlab-shell serves repositories over SSH. It manages the SSH keys within `/home/git/.ssh/authorized_keys` which should not be manually edited. gitlab-shell accesses the bare repositories directly to serve git objects and communicates with redis to submit jobs to Sidekiq for GitLab to process. gitlab-shell queries the GitLab API to determine authorization and access.
@@ -129,7 +129,7 @@ Note: `/home/git/` is shorthand for `/home/git`.
gitlabhq (includes Unicorn and Sidekiq logs)
-- `/home/git/gitlab/log/` contains `application.log`, `production.log`, `sidekiq.log`, `unicorn.stdout.log`, `githost.log`, `satellites.log`, and `unicorn.stderr.log` normally.
+- `/home/git/gitlab/log/` contains `application.log`, `production.log`, `sidekiq.log`, `unicorn.stdout.log`, `githost.log` and `unicorn.stderr.log` normally.
gitlab-shell
diff --git a/doc/install/installation.md b/doc/install/installation.md
index 8b918cba133..55b6f216dde 100644
--- a/doc/install/installation.md
+++ b/doc/install/installation.md
@@ -195,9 +195,9 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da
### Clone the Source
# Clone GitLab repository
- sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 7-12-stable gitlab
+ sudo -u git -H git clone https://gitlab.com/gitlab-org/gitlab-ce.git -b 7-13-stable gitlab
-**Note:** You can change `7-12-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server!
+**Note:** You can change `7-13-stable` to `master` if you want the *bleeding edge* version, but never install master on a production server!
### Configure It
@@ -216,10 +216,6 @@ We recommend using a PostgreSQL database. For MySQL check [MySQL setup guide](da
sudo chmod -R u+rwX,go-w log/
sudo chmod -R u+rwX tmp/
- # Create directory for satellites
- sudo -u git -H mkdir /home/git/gitlab-satellites
- sudo chmod u+rwx,g=rx,o-rwx /home/git/gitlab-satellites
-
# Make sure GitLab can write to the tmp/pids/ and tmp/sockets/ directories
sudo chmod -R u+rwX tmp/pids/
sudo chmod -R u+rwX tmp/sockets/
diff --git a/doc/install/requirements.md b/doc/install/requirements.md
index 1efc1f7bddf..e44ce25b6b4 100644
--- a/doc/install/requirements.md
+++ b/doc/install/requirements.md
@@ -32,7 +32,7 @@ Please consider using a virtual machine to run GitLab.
## Ruby versions
-GitLab requires Ruby (MRI) 2.0 or 2.1
+GitLab requires Ruby (MRI) 2.1
You will have to use the standard MRI implementation of Ruby.
We love [JRuby](http://jruby.org/) and [Rubinius](http://rubini.us/) but GitLab needs several Gems that have native extensions.
@@ -40,7 +40,7 @@ We love [JRuby](http://jruby.org/) and [Rubinius](http://rubini.us/) but GitLab
### Storage
-The necessary hard drive space largely depends on the size of the repos you want to store in GitLab but as a *rule of thumb* you should have at least twice as much free space as all your repos combined take up. You need twice the storage because [GitLab satellites](structure.md) contain an extra copy of each repo.
+The necessary hard drive space largely depends on the size of the repos you want to store in GitLab but as a *rule of thumb* you should have at least as much free space as all your repos combined take up.
If you want to be flexible about growing your hard drive space in the future consider mounting it using LVM so you can add more hard drives when you need them.
@@ -113,4 +113,4 @@ On a very active server (10,000 active users) the Sidekiq process can use 1GB+ o
### Common UI problems with IE
-If you experience UI issues with Internet Explorer, please make sure that you have the `Compatibility View` mode disabled. \ No newline at end of file
+If you experience UI issues with Internet Explorer, please make sure that you have the `Compatibility View` mode disabled.
diff --git a/doc/install/structure.md b/doc/install/structure.md
index 5c03f073c18..d58b0040eef 100644
--- a/doc/install/structure.md
+++ b/doc/install/structure.md
@@ -6,16 +6,14 @@ This is the directory structure you will end up with following the instructions
| |-- git
| |-- .ssh
| |-- gitlab
- | |-- gitlab-satellites
| |-- gitlab-shell
| |-- repositories
* `/home/git/.ssh` - contains openssh settings. Specifically the `authorized_keys` file managed by gitlab-shell.
* `/home/git/gitlab` - GitLab core software.
-* `/home/git/gitlab-satellites` - checked out repositories for merge requests and file editing from web UI. This can be treated as a temporary files directory.
* `/home/git/gitlab-shell` - Core add-on component of GitLab. Maintains SSH cloning and other functionality.
* `/home/git/repositories` - bare repositories for all projects organized by namespace. This is where the git repositories which are pushed/pulled are maintained for all projects. **This area is critical data for projects. [Keep a backup](../raketasks/backup_restore.md)**
-*Note: the default locations for gitlab-satellites and repositories can be configured in `config/gitlab.yml` of GitLab and `config.yml` of gitlab-shell.*
+*Note: the default locations for repositories can be configured in `config/gitlab.yml` of GitLab and `config.yml` of gitlab-shell.*
To see a more in-depth overview see the [GitLab architecture doc](../development/architecture.md).
diff --git a/doc/logs/logs.md b/doc/logs/logs.md
index 83c32b09253..27937e51764 100644
--- a/doc/logs/logs.md
+++ b/doc/logs/logs.md
@@ -51,16 +51,6 @@ December 03, 2014 13:20 -> ERROR -> Command failed [1]: /usr/bin/git --git-dir=/
error: failed to push some refs to '/Users/vsizov/gitlab-development-kit/repositories/gitlabhq/gitlab_git.git'
```
-#### satellites.log
-This file lives in `/var/log/gitlab/gitlab-rails/satellites.log` for omnibus package or in `/home/git/gitlab/log/satellites.log` for installations from the source.
-
-In some cases GitLab should perform write actions to git repository, for example when it is needed to merge the merge request or edit a file with online editor. If something went wrong you can look into this file to find out what exactly happened.
-```
-October 07, 2014 11:36: Failed to create satellite for Chesley Weimann III / project1817
-October 07, 2014 11:36: PID: 1872: git clone /Users/vsizov/gitlab-development-kit/gitlab/tmp/tests/repositories/conrad6841/gitlabhq.git /Users/vsizov/gitlab-development-kit/gitlab/tmp/tests/gitlab-satellites/conrad6841/gitlabhq
-October 07, 2014 11:36: PID: 1872: -> fatal: repository '/Users/vsizov/gitlab-development-kit/gitlab/tmp/tests/repositories/conrad6841/gitlabhq.git' does not exist
-```
-
#### sidekiq.log
This file lives in `/var/log/gitlab/gitlab-rails/sidekiq.log` for omnibus package or in `/home/git/gitlab/log/sidekiq.log` for installations from the source.
@@ -99,4 +89,4 @@ W, [2015-02-13T07:16:01.313000 #9094] WARN -- : Unicorn::WorkerKiller send SIGQ
I, [2015-02-13T07:16:01.530733 #9047] INFO -- : reaped #<Process::Status: pid 9094 exit 0> worker=1
I, [2015-02-13T07:16:01.534501 #13379] INFO -- : worker=1 spawned pid=13379
I, [2015-02-13T07:16:01.534848 #13379] INFO -- : worker=1 ready
-``` \ No newline at end of file
+```
diff --git a/doc/raketasks/backup_restore.md b/doc/raketasks/backup_restore.md
index 05324b33022..6a68c8e8286 100644
--- a/doc/raketasks/backup_restore.md
+++ b/doc/raketasks/backup_restore.md
@@ -7,7 +7,7 @@
A backup creates an archive file that contains the database, all repositories and all attachments.
This archive will be saved in backup_path (see `config/gitlab.yml`).
The filename will be `[TIMESTAMP]_gitlab_backup.tar`. This timestamp can be used to restore an specific backup.
-You can only restore a backup to exactly the same version of GitLab that you created it on, for example 7.2.1.
+You can only restore a backup to exactly the same version of GitLab that you created it on, for example 7.2.1. The best way to migrate your repositories from one server to another is through backup restore.
You need to keep a separate copy of `/etc/gitlab/gitlab-secrets.json`
(for omnibus packages) or `/home/git/gitlab/.secret` (for installations
@@ -249,7 +249,7 @@ Deleting tmp directories...[DONE]
We will assume that you have installed GitLab from an omnibus package and run
`sudo gitlab-ctl reconfigure` at least once.
-First make sure your backup tar file is in `/var/opt/gitlab/backups`.
+First make sure your backup tar file is in `/var/opt/gitlab/backups` (or wherever `gitlab_rails['backup_path']` points to).
```shell
sudo cp 1393513186_gitlab_backup.tar /var/opt/gitlab/backups/
diff --git a/doc/raketasks/maintenance.md b/doc/raketasks/maintenance.md
index 69171cd1765..d9dce2af480 100644
--- a/doc/raketasks/maintenance.md
+++ b/doc/raketasks/maintenance.md
@@ -105,24 +105,11 @@ Log directory writable? ... yes
Tmp directory writable? ... yes
Init script exists? ... yes
Init script up-to-date? ... yes
-Projects have satellites? ... yes
Redis version >= 2.0.0? ... yes
Checking GitLab ... Finished
```
-## (Re-)Create satellite repositories
-
-This will create satellite repositories for all your projects.
-
-If necessary, remove the `repo_satellites` directory and rerun the commands below.
-
-```
-sudo -u git -H mkdir -p /home/git/gitlab-satellites
-sudo -u git -H bundle exec rake gitlab:satellites:create RAILS_ENV=production
-sudo chmod u+rwx,g=rx,o-rwx /home/git/gitlab-satellites
-```
-
## Rebuild authorized_keys file
In some case it is necessary to rebuild the `authorized_keys` file.
diff --git a/doc/release/monthly.md b/doc/release/monthly.md
index 552b24195b1..b10e7420675 100644
--- a/doc/release/monthly.md
+++ b/doc/release/monthly.md
@@ -81,6 +81,7 @@ workday to quickly fix any issues.
- [ ] Merge CE stable into EE stable (#LINK)
- [ ] Create the 'x.y.0' tag with the [release tools](https://dev.gitlab.org/gitlab/release-tools) (#LINK)
+- [ ] Create the 'x.y.0' version on version.gitlab.com
- [ ] Try to do before 11AM CET: Create and push omnibus tags for x.y.0 (will auto-release the packages) (#LINK)
- [ ] Try to do before 12AM CET: Publish the release blog post (#LINK)
- [ ] Tweet about the release (blog post) (#LINK)
diff --git a/doc/release/patch.md b/doc/release/patch.md
index a569bb3da8d..6aa11b283df 100644
--- a/doc/release/patch.md
+++ b/doc/release/patch.md
@@ -52,5 +52,6 @@ bundle exec rake release["x.x.x"]
1. Create and publish a blog post, see [patch release blog template](https://gitlab.com/gitlab-com/www-gitlab-com/blob/master/doc/patch_release_blog_template.md)
1. Send tweets about the release from `@gitlab`, tweet should include the most important feature that the release is addressing and link to the blog post
1. Note in the 'GitLab X.X regressions' issue that the patch was published (CE only)
+1. Create the 'x.y.0' version on version.gitlab.com
1. [Create new AMIs](https://dev.gitlab.org/gitlab/AMI/blob/master/README.md)
1. Create a new patch release issue for the next potential release \ No newline at end of file
diff --git a/doc/update/mysql_to_postgresql.md b/doc/update/mysql_to_postgresql.md
index 26605c7c3a3..a596ea38456 100644
--- a/doc/update/mysql_to_postgresql.md
+++ b/doc/update/mysql_to_postgresql.md
@@ -1,5 +1,5 @@
# Migrating GitLab from MySQL to Postgres
-*Make sure you view this [guide from the `master` branch](../../../master/doc/update/mysql_to_postgresql.md) for the most up to date instructions.*
+*Make sure you view this [guide from the `master` branch](https://gitlab.com/gitlab-org/gitlab-ce/blob/master/doc/update/mysql_to_postgresql.md#migrating-gitlab-from-mysql-to-postgres) for the most up to date instructions.*
If you are replacing MySQL with Postgres while keeping GitLab on the same server all you need to do is to export from MySQL, convert the resulting SQL file, and import it into Postgres. If you are also moving GitLab to another server, or if you are switching to omnibus-gitlab, you may want to use a GitLab backup file. The second part of this documents explains the procedure to do this.
@@ -70,5 +70,5 @@ sudo -u git -H gzip db/database.sql
sudo -u git -H tar rf TIMESTAMP_gitlab_backup.tar db/database.sql.gz
# Done! TIMESTAMP_gitlab_backup.tar can now be restored into a Postgres GitLab
-# installation. Remember to recreate the indexes after the import.
+# installation.
```
diff --git a/doc/update/patch_versions.md b/doc/update/patch_versions.md
index e29ee2a7b3d..22b9be059d6 100644
--- a/doc/update/patch_versions.md
+++ b/doc/update/patch_versions.md
@@ -22,6 +22,7 @@ sudo -u git -H bundle exec rake gitlab:backup:create RAILS_ENV=production
```bash
cd /home/git/gitlab
sudo -u git -H git fetch --all
+sudo -u git -H git checkout -- Gemfile.lock db/schema.rb
sudo -u git -H git checkout LATEST_TAG
```
diff --git a/doc/workflow/README.md b/doc/workflow/README.md
index 3915198ad2a..5b8d72dfd34 100644
--- a/doc/workflow/README.md
+++ b/doc/workflow/README.md
@@ -13,4 +13,5 @@
- [Project users](add-user/add-user.md)
- [Protected branches](protected_branches.md)
- [Web Editor](web_editor.md)
+- [Merge Requests](merge_requests.md)
- ["Work In Progress" Merge Requests](wip_merge_requests.md)
diff --git a/doc/workflow/merge_requests.md b/doc/workflow/merge_requests.md
new file mode 100644
index 00000000000..751e19da7f1
--- /dev/null
+++ b/doc/workflow/merge_requests.md
@@ -0,0 +1,40 @@
+# Merge Requests
+
+Merge requests allow you to exchange changes you made to source code
+
+## Checkout merge requests locally
+
+Locate the section for your GitLab remote in the `.git/config` file. It looks like this:
+
+```
+[remote "origin"]
+ url = https://gitlab.com/gitlab-org/gitlab-ce.git
+ fetch = +refs/heads/*:refs/remotes/origin/*
+```
+
+Now add the line `fetch = +refs/merge-requests/*/head:refs/remotes/origin/merge-requests/*` to this section.
+
+It should looks like this:
+
+```
+[remote "origin"]
+ url = https://gitlab.com/gitlab-org/gitlab-ce.git
+ fetch = +refs/heads/*:refs/remotes/origin/*
+ fetch = +refs/merge-requests/*/head:refs/remotes/origin/merge-requests/*
+```
+
+Now you can fetch all the merge requests requests:
+
+```
+$ git fetch origin
+From https://gitlab.com/gitlab-org/gitlab-ce.git
+ * [new ref] refs/merge-requests/1/head -> origin/merge-requests/1
+ * [new ref] refs/merge-requests/2/head -> origin/merge-requests/2
+...
+```
+
+To check out a particular merge request:
+
+```
+$ git checkout origin/merge-requests/1
+```
diff --git a/doc/workflow/notifications.md b/doc/workflow/notifications.md
index 2b5f06dd1fa..025992deece 100644
--- a/doc/workflow/notifications.md
+++ b/doc/workflow/notifications.md
@@ -52,18 +52,35 @@ Below is the table of events users can be notified of:
| New SSH key added | User | Security email, always sent. |
| New email added | User | Security email, always sent. |
| New user created | User | Sent on user creation, except for omniauth (LDAP)|
-| New issue created | Issue assignee [1], project members [2] | [1] not disabled, [2] higher than participating |
| User added to project | User | Sent when user is added to project |
| Project access level changed | User | Sent when user project access level is changed |
| User added to group | User | Sent when user is added to group |
-| Project moved | Project members [1] | [1] not disabled |
| Group access level changed | User | Sent when user group access level is changed |
-| Close issue | Issue author [1], issue assignee [2], project members [3] | [1] [2] not disabled, [3] higher than participating |
-| Reassign issue | New issue assignee [1], old issue assignee [2] | [1] [2] not disabled |
-| Reopen issue | Project members [1] | [1] higher than participating |
-| New merge request | MR assignee [1] | [1] not disabled |
-| Reassign merge request | New MR assignee [1], old MR assignee [2] | [1] [2] not disabled |
-| Close merge request | MR author [1], MR assignee [2], project members [3] | [1] [2] not disabled, [3] higher than participating |
-| Reopen merge request | Project members [1] | [1] higher than participating |
-| Merge merge request | MR author [1], MR assignee [2], project members [3] | [1] [2] not disabled, [3] higher than participating |
-| New comment | Mentioned users [1], users participating [2], project members [3] | [1] [2] not disabled, [3] higher than participating |
+| Project moved | Project members [1] | [1] not disabled |
+
+### Issue / Merge Request events
+
+In all of the below cases, the notification will be sent to:
+- Participants:
+ - the author and assignee of the issue/merge request
+ - authors of comments on the issue/merge request
+ - anyone mentioned by `@username` in the issue/merge request description
+ - anyone mentioned by `@username` in any of the comments on the issue/merge request
+
+ ...with notification level "Participating" or higher
+
+- Watchers: project members with notification level "Watch"
+- Subscribers: anyone who manually subscribed to the issue/merge request
+
+| Event | Sent to |
+|------------------------|---------|
+| New issue | |
+| Close issue | |
+| Reassign issue | The above, plus the old assignee |
+| Reopen issue | |
+| New merge request | |
+| Reassign merge request | The above, plus the old assignee |
+| Close merge request | |
+| Reopen merge request | |
+| Merge merge request | |
+| New comment | The above, plus anyone mentioned by `@username` in the comment, with notification level "Mention" or higher |
diff --git a/features/abuse_report.feature b/features/abuse_report.feature
new file mode 100644
index 00000000000..3e1cb455b77
--- /dev/null
+++ b/features/abuse_report.feature
@@ -0,0 +1,10 @@
+Feature: Abuse reports
+ Background:
+ Given I sign in as a user
+ And user "Mike" exists
+
+ Scenario: Report abuse
+ Given I visit "Mike" user page
+ And I click "Report abuse" button
+ When I fill and submit abuse form
+ Then I should see success message
diff --git a/features/admin/abuse_report.feature b/features/admin/abuse_report.feature
new file mode 100644
index 00000000000..7d4ec2556e5
--- /dev/null
+++ b/features/admin/abuse_report.feature
@@ -0,0 +1,8 @@
+Feature: Admin Abuse reports
+ Background:
+ Given I sign in as an admin
+ And abuse reports exist
+
+ Scenario: Browse abuse reports
+ When I visit abuse reports page
+ Then I should see list of abuse reports
diff --git a/features/steps/abuse_reports.rb b/features/steps/abuse_reports.rb
new file mode 100644
index 00000000000..8f9ddb2899f
--- /dev/null
+++ b/features/steps/abuse_reports.rb
@@ -0,0 +1,28 @@
+class Spinach::Features::AbuseReports < Spinach::FeatureSteps
+ include SharedAuthentication
+
+ step 'I visit "Mike" user page' do
+ visit user_path(user_mike)
+ end
+
+ step 'I click "Report abuse" button' do
+ click_link 'Report abuse'
+ end
+
+ step 'I fill and submit abuse form' do
+ fill_in 'abuse_report_message', with: 'This user send spam'
+ click_button 'Send report'
+ end
+
+ step 'I should see success message' do
+ page.should have_content 'Thank you for your report'
+ end
+
+ step 'user "Mike" exists' do
+ user_mike
+ end
+
+ def user_mike
+ @user_mike ||= create(:user, name: 'Mike')
+ end
+end
diff --git a/features/steps/admin/abuse_reports.rb b/features/steps/admin/abuse_reports.rb
new file mode 100644
index 00000000000..0149416c919
--- /dev/null
+++ b/features/steps/admin/abuse_reports.rb
@@ -0,0 +1,15 @@
+class Spinach::Features::AdminAbuseReports < Spinach::FeatureSteps
+ include SharedAuthentication
+ include SharedPaths
+ include SharedAdmin
+
+ step 'I should see list of abuse reports' do
+ page.should have_content("Abuse Reports")
+ page.should have_content AbuseReport.first.message
+ page.should have_link("Remove user")
+ end
+
+ step 'abuse reports exist' do
+ create(:abuse_report)
+ end
+end
diff --git a/features/steps/admin/groups.rb b/features/steps/admin/groups.rb
index 9cc74a97c3a..83a3f48abe3 100644
--- a/features/steps/admin/groups.rb
+++ b/features/steps/admin/groups.rb
@@ -58,7 +58,7 @@ class Spinach::Features::AdminGroups < Spinach::FeatureSteps
end
step 'we have user "John Doe" in group' do
- current_group.add_user(user_john, Gitlab::Access::REPORTER)
+ current_group.add_reporter(user_john)
end
step 'I remove user "John Doe" from group' do
diff --git a/features/steps/admin/users.rb b/features/steps/admin/users.rb
index 49e64eeff71..2e17d5c4c2e 100644
--- a/features/steps/admin/users.rb
+++ b/features/steps/admin/users.rb
@@ -79,7 +79,7 @@ class Spinach::Features::AdminUsers < Spinach::FeatureSteps
project.team << [user, :developer]
group = create(:group)
- group.add_user(user, Gitlab::Access::DEVELOPER)
+ group.add_developer(user)
end
step 'click on "Mike" link' do
diff --git a/features/steps/dashboard/help.rb b/features/steps/dashboard/help.rb
index 86ab31a58ab..800e869533e 100644
--- a/features/steps/dashboard/help.rb
+++ b/features/steps/dashboard/help.rb
@@ -16,6 +16,6 @@ class Spinach::Features::DashboardHelp < Spinach::FeatureSteps
end
step 'Header "Rebuild project satellites" should have correct ids and links' do
- header_should_have_correct_id_and_link(2, '(Re-)Create satellite repositories', 're-create-satellite-repositories', '.documentation')
+ header_should_have_correct_id_and_link(2, 'Check GitLab configuration', 'check-gitlab-configuration', '.documentation')
end
end
diff --git a/features/steps/dashboard/merge_requests.rb b/features/steps/dashboard/merge_requests.rb
index cec8d06adee..28c8c6b6015 100644
--- a/features/steps/dashboard/merge_requests.rb
+++ b/features/steps/dashboard/merge_requests.rb
@@ -66,7 +66,7 @@ class Spinach::Features::DashboardMergeRequests < Spinach::FeatureSteps
def authored_merge_request
@authored_merge_request ||= create :merge_request,
- source_branch: 'simple_merge_request',
+ source_branch: 'markdown',
author: current_user,
target_project: project,
source_project: project
@@ -74,14 +74,14 @@ class Spinach::Features::DashboardMergeRequests < Spinach::FeatureSteps
def other_merge_request
@other_merge_request ||= create :merge_request,
- source_branch: '2_3_notes_fix',
+ source_branch: 'fix',
target_project: project,
source_project: project
end
def authored_merge_request_from_fork
@authored_merge_request_from_fork ||= create :merge_request,
- source_branch: 'basic_page',
+ source_branch: 'feature_conflict',
author: current_user,
target_project: public_project,
source_project: forked_project
@@ -89,7 +89,7 @@ class Spinach::Features::DashboardMergeRequests < Spinach::FeatureSteps
def assigned_merge_request_from_fork
@assigned_merge_request_from_fork ||= create :merge_request,
- source_branch: 'basic_page_fix',
+ source_branch: 'markdown',
assignee: current_user,
target_project: public_project,
source_project: forked_project
diff --git a/features/steps/explore/groups.rb b/features/steps/explore/groups.rb
index 89b82293ef2..87cd33c37eb 100644
--- a/features/steps/explore/groups.rb
+++ b/features/steps/explore/groups.rb
@@ -19,7 +19,7 @@ class Spinach::Features::ExploreGroups < Spinach::FeatureSteps
step '"John Doe" is owner of group "TestGroup"' do
group = Group.find_by(name: "TestGroup") || create(:group, name: "TestGroup")
user = create(:user, name: "John Doe")
- group.add_user(user, Gitlab::Access::OWNER)
+ group.add_owner(user)
end
step 'I visit group "TestGroup" page' do
diff --git a/features/steps/invites.rb b/features/steps/invites.rb
index d051cc3edc8..5e8feff5095 100644
--- a/features/steps/invites.rb
+++ b/features/steps/invites.rb
@@ -6,7 +6,7 @@ class Spinach::Features::Invites < Spinach::FeatureSteps
step '"John Doe" has invited "user@example.com" to group "Owned"' do
user = User.find_by(name: "John Doe")
group = Group.find_by(name: "Owned")
- group.add_user("user@example.com", Gitlab::Access::DEVELOPER, user)
+ group.add_developer("user@example.com", user)
end
step 'I visit the invitation page' do
diff --git a/features/steps/project/forked_merge_requests.rb b/features/steps/project/forked_merge_requests.rb
index 58c16d59d05..2a333222fb2 100644
--- a/features/steps/project/forked_merge_requests.rb
+++ b/features/steps/project/forked_merge_requests.rb
@@ -9,7 +9,6 @@ class Spinach::Features::ProjectForkedMergeRequests < Spinach::FeatureSteps
@project = Project.find_by(name: "Shop")
@project ||= create(:project, name: "Shop")
@project.team << [@user, :reporter]
- @project.ensure_satellite_exists
end
step 'I have a project forked off of "Shop" called "Forked Shop"' do
@@ -138,10 +137,11 @@ class Spinach::Features::ProjectForkedMergeRequests < Spinach::FeatureSteps
end
step 'I should see the users from the target project ID' do
- expect(page).to have_selector('.user-result', visible: true, count: 2)
+ expect(page).to have_selector('.user-result', visible: true, count: 3)
users = page.all('.user-name')
expect(users[0].text).to eq 'Unassigned'
- expect(users[1].text).to eq @project.users.first.name
+ expect(users[1].text).to eq current_user.name
+ expect(users[2].text).to eq @project.users.first.name
end
# Verify a link is generated against the correct project
diff --git a/features/steps/project/merge_requests.rb b/features/steps/project/merge_requests.rb
index a1a26abd8ca..f2198f58c13 100644
--- a/features/steps/project/merge_requests.rb
+++ b/features/steps/project/merge_requests.rb
@@ -198,15 +198,10 @@ class Spinach::Features::ProjectMergeRequests < Spinach::FeatureSteps
end
step 'merge request "Bug NS-05" is mergeable' do
- merge_request.project.satellite.create
merge_request.mark_as_mergeable
end
step 'I accept this merge request' do
- Gitlab::Satellite::MergeAction.any_instance.stub(
- merge!: true,
- )
-
page.within '.mr-state-widget' do
click_button "Accept Merge Request"
end
diff --git a/features/steps/shared/paths.rb b/features/steps/shared/paths.rb
index 88a98a37807..bb0cd9ac105 100644
--- a/features/steps/shared/paths.rb
+++ b/features/steps/shared/paths.rb
@@ -139,6 +139,10 @@ module SharedPaths
visit admin_root_path
end
+ step 'I visit abuse reports page' do
+ visit admin_abuse_reports_path
+ end
+
step 'I visit admin projects page' do
visit admin_namespaces_projects_path
end
diff --git a/lib/api/merge_requests.rb b/lib/api/merge_requests.rb
index ce21c699e8f..7412274b045 100644
--- a/lib/api/merge_requests.rb
+++ b/lib/api/merge_requests.rb
@@ -198,7 +198,11 @@ module API
if merge_request.open? && !merge_request.work_in_progress?
if merge_request.can_be_merged?
- merge_request.automerge!(current_user, params[:merge_commit_message] || merge_request.merge_commit_message)
+ commit_message = params[:merge_commit_message] || merge_request.merge_commit_message
+
+ ::MergeRequests::MergeService.new(merge_request.target_project, current_user).
+ execute(merge_request, commit_message)
+
present merge_request, with: Entities::MergeRequest
else
render_api_error!('Branch cannot be merged', 405)
diff --git a/lib/api/notes.rb b/lib/api/notes.rb
index 3726be7c537..3efdfe2d46e 100644
--- a/lib/api/notes.rb
+++ b/lib/api/notes.rb
@@ -78,17 +78,15 @@ module API
put ":id/#{noteables_str}/:#{noteable_id_str}/notes/:note_id" do
required_attributes! [:body]
- authorize! :admin_note, user_project.notes.find(params[:note_id])
+ note = user_project.notes.find(params[:note_id])
+
+ authorize! :admin_note, note
opts = {
- note: params[:body],
- note_id: params[:note_id],
- noteable_type: noteables_str.classify,
- noteable_id: params[noteable_id_str]
+ note: params[:body]
}
- @note = ::Notes::UpdateService.new(user_project, current_user,
- opts).execute
+ @note = ::Notes::UpdateService.new(user_project, current_user, opts).execute(note)
if @note.valid?
present @note, with: Entities::Note
diff --git a/lib/extracts_path.rb b/lib/extracts_path.rb
index 3f420553d42..322aed5e27c 100644
--- a/lib/extracts_path.rb
+++ b/lib/extracts_path.rb
@@ -94,7 +94,7 @@ module ExtractsPath
@options = params.select {|key, value| allowed_options.include?(key) && !value.blank? }
@options = HashWithIndifferentAccess.new(@options)
- @id = get_id
+ @id = Addressable::URI.unescape(get_id)
@ref, @path = extract_ref(@id)
@repo = @project.repository
if @options[:extended_sha1].blank?
diff --git a/lib/gitlab.rb b/lib/gitlab.rb
index 5fc1862c3e9..6108697bc20 100644
--- a/lib/gitlab.rb
+++ b/lib/gitlab.rb
@@ -1,5 +1,4 @@
require 'gitlab/git'
module Gitlab
- autoload :Satellite, 'gitlab/satellite/satellite'
end
diff --git a/lib/gitlab/backend/shell.rb b/lib/gitlab/backend/shell.rb
index 172d4902add..14ee4701e7b 100644
--- a/lib/gitlab/backend/shell.rb
+++ b/lib/gitlab/backend/shell.rb
@@ -217,20 +217,6 @@ module Gitlab
FileUtils.mv(full_path(old_name), full_path(new_name))
end
- # Remove GitLab Satellites for provided path (namespace or repo dir)
- #
- # Ex.
- # rm_satellites("gitlab")
- #
- # rm_satellites("gitlab/gitlab-ci.git")
- #
- def rm_satellites(path)
- raise ArgumentError.new("Path can't be blank") if path.blank?
-
- satellites_path = File.join(Gitlab.config.satellites.path, path)
- FileUtils.rm_r(satellites_path, force: true)
- end
-
def url_to_repo(path)
Gitlab.config.gitlab_shell.ssh_path_prefix + "#{path}.git"
end
diff --git a/lib/gitlab/bitbucket_import/client.rb b/lib/gitlab/bitbucket_import/client.rb
index 778b76f6890..aec44b8c87b 100644
--- a/lib/gitlab/bitbucket_import/client.rb
+++ b/lib/gitlab/bitbucket_import/client.rb
@@ -87,6 +87,10 @@ module Gitlab
JSON.parse(get("/api/1.0/user/repositories").body).select { |repo| repo["scm"] == "git" }
end
+ def incompatible_projects
+ JSON.parse(get("/api/1.0/user/repositories").body).reject { |repo| repo["scm"] == "git" }
+ end
+
private
def get(url)
diff --git a/lib/gitlab/satellite/action.rb b/lib/gitlab/satellite/action.rb
deleted file mode 100644
index 489070f1a3f..00000000000
--- a/lib/gitlab/satellite/action.rb
+++ /dev/null
@@ -1,58 +0,0 @@
-module Gitlab
- module Satellite
- class Action
- DEFAULT_OPTIONS = { git_timeout: Gitlab.config.satellites.timeout.seconds }
-
- attr_accessor :options, :project, :user
-
- def initialize(user, project, options = {})
- @options = DEFAULT_OPTIONS.merge(options)
- @project = project
- @user = user
- end
-
- protected
-
- # * Sets a 30s timeout for Git
- # * Locks the satellite repo
- # * Yields the prepared satellite repo
- def in_locked_and_timed_satellite
- Gitlab::ShellEnv.set_env(user)
-
- Grit::Git.with_timeout(options[:git_timeout]) do
- project.satellite.lock do
- return yield project.satellite.repo
- end
- end
- rescue Errno::ENOMEM => ex
- return handle_exception(ex)
- rescue Grit::Git::GitTimeout => ex
- return handle_exception(ex)
- ensure
- Gitlab::ShellEnv.reset_env
- end
-
- # * Recreates the satellite
- # * Sets up Git variables for the user
- #
- # Note: use this within #in_locked_and_timed_satellite
- def prepare_satellite!(repo)
- project.satellite.clear_and_update!
-
- if user
- repo.config['user.name'] = user.name
- repo.config['user.email'] = user.email
- end
- end
-
- def default_options(options = {})
- { raise: true, timeout: true }.merge(options)
- end
-
- def handle_exception(exception)
- Gitlab::GitLogger.error(exception.message)
- false
- end
- end
- end
-end
diff --git a/lib/gitlab/satellite/compare_action.rb b/lib/gitlab/satellite/compare_action.rb
deleted file mode 100644
index 46c98a8f4ca..00000000000
--- a/lib/gitlab/satellite/compare_action.rb
+++ /dev/null
@@ -1,44 +0,0 @@
-module Gitlab
- module Satellite
- class BranchesWithoutParent < StandardError; end
-
- class CompareAction < Action
- def initialize(user, target_project, target_branch, source_project, source_branch)
- super user, target_project
-
- @target_project, @target_branch = target_project, target_branch
- @source_project, @source_branch = source_project, source_branch
- end
-
- # Compare 2 repositories and return Gitlab::CompareResult object
- def result
- in_locked_and_timed_satellite do |target_repo|
- prepare_satellite!(target_repo)
- update_satellite_source_and_target!(target_repo)
-
- Gitlab::CompareResult.new(compare(target_repo))
- end
- rescue Grit::Git::CommandFailed => ex
- raise BranchesWithoutParent
- end
-
- private
-
- # Assumes a satellite exists that is a fresh clone of the projects repo, prepares satellite for diffs
- def update_satellite_source_and_target!(target_repo)
- target_repo.remote_add('source', @source_project.repository.path_to_repo)
- target_repo.remote_fetch('source')
- rescue Grit::Git::CommandFailed => ex
- handle_exception(ex)
- end
-
- def compare(repo)
- @compare ||= Gitlab::Git::Compare.new(
- Gitlab::Git::Repository.new(repo.path),
- "origin/#{@target_branch}",
- "source/#{@source_branch}"
- )
- end
- end
- end
-end
diff --git a/lib/gitlab/satellite/logger.rb b/lib/gitlab/satellite/logger.rb
deleted file mode 100644
index 6f3f8255aca..00000000000
--- a/lib/gitlab/satellite/logger.rb
+++ /dev/null
@@ -1,13 +0,0 @@
-module Gitlab
- module Satellite
- class Logger < Gitlab::Logger
- def self.file_name
- 'satellites.log'
- end
-
- def format_message(severity, timestamp, progname, msg)
- "#{timestamp.to_s(:long)}: #{msg}\n"
- end
- end
- end
-end
diff --git a/lib/gitlab/satellite/merge_action.rb b/lib/gitlab/satellite/merge_action.rb
deleted file mode 100644
index f9bf286697e..00000000000
--- a/lib/gitlab/satellite/merge_action.rb
+++ /dev/null
@@ -1,146 +0,0 @@
-module Gitlab
- module Satellite
- # GitLab server-side merge
- class MergeAction < Action
- attr_accessor :merge_request
-
- def initialize(user, merge_request)
- super user, merge_request.target_project
- @merge_request = merge_request
- end
-
- # Checks if a merge request can be executed without user interaction
- def can_be_merged?
- in_locked_and_timed_satellite do |merge_repo|
- prepare_satellite!(merge_repo)
- merge_in_satellite!(merge_repo)
- end
- end
-
- # Merges the source branch into the target branch in the satellite and
- # pushes it back to the repository.
- # It also removes the source branch if requested in the merge request (and this is permitted by the merge request).
- #
- # Returns false if the merge produced conflicts
- # Returns false if pushing from the satellite to the repository failed or was rejected
- # Returns true otherwise
- def merge!(merge_commit_message = nil)
- in_locked_and_timed_satellite do |merge_repo|
- prepare_satellite!(merge_repo)
- if merge_in_satellite!(merge_repo, merge_commit_message)
- # push merge back to bare repo
- # will raise CommandFailed when push fails
- merge_repo.git.push(default_options, :origin, merge_request.target_branch)
-
- # remove source branch
- if merge_request.remove_source_branch?
- # will raise CommandFailed when push fails
- merge_repo.git.push(default_options, :origin, ":#{merge_request.source_branch}")
- end
- # merge, push and branch removal successful
- true
- end
- end
- rescue Grit::Git::CommandFailed => ex
- handle_exception(ex)
- end
-
- def diff_in_satellite
- in_locked_and_timed_satellite do |merge_repo|
- prepare_satellite!(merge_repo)
- update_satellite_source_and_target!(merge_repo)
-
- # Only show what is new in the source branch compared to the target branch, not the other way around.
- # The line below with merge_base is equivalent to diff with three dots (git diff branch1...branch2)
- # From the git documentation: "git diff A...B" is equivalent to "git diff $(git-merge-base A B) B"
- common_commit = merge_repo.git.native(:merge_base, default_options, ["origin/#{merge_request.target_branch}", "source/#{merge_request.source_branch}"]).strip
- merge_repo.git.native(:diff, default_options, common_commit, "source/#{merge_request.source_branch}")
- end
- rescue Grit::Git::CommandFailed => ex
- handle_exception(ex)
- end
-
- def diffs_between_satellite
- in_locked_and_timed_satellite do |merge_repo|
- prepare_satellite!(merge_repo)
- update_satellite_source_and_target!(merge_repo)
- if merge_request.for_fork?
- repository = Gitlab::Git::Repository.new(merge_repo.path)
- diffs = Gitlab::Git::Diff.between(
- repository,
- "source/#{merge_request.source_branch}",
- "origin/#{merge_request.target_branch}"
- )
- else
- raise "Attempt to determine diffs between for a non forked merge request in satellite MergeRequest.id:[#{merge_request.id}]"
- end
-
- return diffs
- end
- rescue Grit::Git::CommandFailed => ex
- handle_exception(ex)
- end
-
- # Get commit as an email patch
- def format_patch
- in_locked_and_timed_satellite do |merge_repo|
- prepare_satellite!(merge_repo)
- update_satellite_source_and_target!(merge_repo)
- patch = merge_repo.git.format_patch(default_options({ stdout: true }), "origin/#{merge_request.target_branch}..source/#{merge_request.source_branch}")
- end
- rescue Grit::Git::CommandFailed => ex
- handle_exception(ex)
- end
-
- # Retrieve an array of commits between the source and the target
- def commits_between
- in_locked_and_timed_satellite do |merge_repo|
- prepare_satellite!(merge_repo)
- update_satellite_source_and_target!(merge_repo)
- if merge_request.for_fork?
- repository = Gitlab::Git::Repository.new(merge_repo.path)
- commits = Gitlab::Git::Commit.between(
- repository,
- "origin/#{merge_request.target_branch}",
- "source/#{merge_request.source_branch}"
- )
- else
- raise "Attempt to determine commits between for a non forked merge request in satellite MergeRequest.id:[#{merge_request.id}]"
- end
-
- return commits
- end
- rescue Grit::Git::CommandFailed => ex
- handle_exception(ex)
- end
-
- private
- # Merges the source_branch into the target_branch in the satellite.
- #
- # Note: it will clear out the satellite before doing anything
- #
- # Returns false if the merge produced conflicts
- # Returns true otherwise
- def merge_in_satellite!(repo, message = nil)
- update_satellite_source_and_target!(repo)
-
- message ||= "Merge branch '#{merge_request.source_branch}' into '#{merge_request.target_branch}'"
-
- # merge the source branch into the satellite
- # will raise CommandFailed when merge fails
- repo.git.merge(default_options({ no_ff: true }), "-m#{message}", "source/#{merge_request.source_branch}")
- rescue Grit::Git::CommandFailed => ex
- handle_exception(ex)
- end
-
- # Assumes a satellite exists that is a fresh clone of the projects repo, prepares satellite for merges, diffs etc
- def update_satellite_source_and_target!(repo)
- repo.remote_add('source', merge_request.source_project.repository.path_to_repo)
- repo.remote_fetch('source')
- repo.git.checkout(default_options({ b: true }), merge_request.target_branch, "origin/#{merge_request.target_branch}")
- rescue Grit::Git::CommandFailed => ex
- handle_exception(ex)
- end
- end
- end
-end
diff --git a/lib/gitlab/satellite/satellite.rb b/lib/gitlab/satellite/satellite.rb
deleted file mode 100644
index 398643d68de..00000000000
--- a/lib/gitlab/satellite/satellite.rb
+++ /dev/null
@@ -1,148 +0,0 @@
-module Gitlab
- module Satellite
- autoload :DeleteFileAction, 'gitlab/satellite/files/delete_file_action'
- autoload :EditFileAction, 'gitlab/satellite/files/edit_file_action'
- autoload :FileAction, 'gitlab/satellite/files/file_action'
- autoload :NewFileAction, 'gitlab/satellite/files/new_file_action'
-
- class CheckoutFailed < StandardError; end
- class CommitFailed < StandardError; end
- class PushFailed < StandardError; end
-
- class Satellite
- include Gitlab::Popen
-
- PARKING_BRANCH = "__parking_branch"
-
- attr_accessor :project
-
- def initialize(project)
- @project = project
- end
-
- def log(message)
- Gitlab::Satellite::Logger.error(message)
- end
-
- def clear_and_update!
- project.ensure_satellite_exists
-
- @repo = nil
- clear_working_dir!
- delete_heads!
- remove_remotes!
- update_from_source!
- end
-
- def create
- output, status = popen(%W(git clone -- #{project.repository.path_to_repo} #{path}),
- Gitlab.config.satellites.path)
-
- log("PID: #{project.id}: git clone #{project.repository.path_to_repo} #{path}")
- log("PID: #{project.id}: -> #{output}")
-
- if status.zero?
- true
- else
- log("Failed to create satellite for #{project.name_with_namespace}")
- false
- end
- end
-
- def exists?
- File.exists? path
- end
-
- # * Locks the satellite
- # * Changes the current directory to the satellite's working dir
- # * Yields
- def lock
- project.ensure_satellite_exists
-
- File.open(lock_file, "w+") do |f|
- begin
- f.flock File::LOCK_EX
- yield
- ensure
- f.flock File::LOCK_UN
- end
- end
- end
-
- def lock_file
- create_locks_dir unless File.exists?(lock_files_dir)
- File.join(lock_files_dir, "satellite_#{project.id}.lock")
- end
-
- def path
- File.join(Gitlab.config.satellites.path, project.path_with_namespace)
- end
-
- def repo
- project.ensure_satellite_exists
-
- @repo ||= Grit::Repo.new(path)
- end
-
- def destroy
- FileUtils.rm_rf(path)
- end
-
- private
-
- # Clear the working directory
- def clear_working_dir!
- repo.git.reset(hard: true)
- repo.git.clean(f: true, d: true, x: true)
- end
-
- # Deletes all branches except the parking branch
- #
- # This ensures we have no name clashes or issues updating branches when
- # working with the satellite.
- def delete_heads!
- heads = repo.heads.map(&:name)
-
- # update or create the parking branch
- repo.git.checkout(default_options({ B: true }), PARKING_BRANCH)
-
- # remove the parking branch from the list of heads ...
- heads.delete(PARKING_BRANCH)
- # ... and delete all others
- heads.each { |head| repo.git.branch(default_options({ D: true }), head) }
- end
-
- # Deletes all remotes except origin
- #
- # This ensures we have no remote name clashes or issues updating branches when
- # working with the satellite.
- def remove_remotes!
- remotes = repo.git.remote.split(' ')
- remotes.delete('origin')
- remotes.each { |name| repo.git.remote(default_options,'rm', name)}
- end
-
- # Updates the satellite from bare repo
- #
- # Note: this will only update remote branches (i.e. origin/*)
- def update_from_source!
- repo.git.remote(default_options, 'set-url', :origin, project.repository.path_to_repo)
- repo.git.fetch(default_options, :origin)
- end
-
- def default_options(options = {})
- { raise: true, timeout: true }.merge(options)
- end
-
- # Create directory for storing
- # satellites lock files
- def create_locks_dir
- FileUtils.mkdir_p(lock_files_dir)
- end
-
- def lock_files_dir
- @lock_files_dir ||= File.join(Gitlab.config.satellites.path, "tmp")
- end
- end
- end
-end
diff --git a/lib/tasks/gitlab/check.rake b/lib/tasks/gitlab/check.rake
index badb47c6779..8acb6a7fd19 100644
--- a/lib/tasks/gitlab/check.rake
+++ b/lib/tasks/gitlab/check.rake
@@ -25,7 +25,6 @@ namespace :gitlab do
check_init_script_exists
check_init_script_up_to_date
check_projects_have_namespace
- check_satellites_exist
check_redis_version
check_ruby_version
check_git_version
@@ -238,37 +237,6 @@ namespace :gitlab do
end
end
- def check_satellites_exist
- print "Projects have satellites? ... "
-
- unless Project.count > 0
- puts "can't check, you have no projects".magenta
- return
- end
- puts ""
-
- Project.find_each(batch_size: 100) do |project|
- print sanitized_message(project)
-
- if project.satellite.exists?
- puts "yes".green
- elsif project.empty_repo?
- puts "can't create, repository is empty".magenta
- else
- puts "no".red
- try_fixing_it(
- sudo_gitlab("bundle exec rake gitlab:satellites:create RAILS_ENV=production"),
- "If necessary, remove the tmp/repo_satellites directory ...",
- "... and rerun the above command"
- )
- for_more_information(
- "doc/raketasks/maintenance.md "
- )
- fix_and_rerun
- end
- end
- end
-
def check_log_writable
print "Log directory writable? ... "
@@ -339,7 +307,6 @@ namespace :gitlab do
check_repo_base_is_not_symlink
check_repo_base_user_and_group
check_repo_base_permissions
- check_satellites_permissions
check_repos_hooks_directory_is_link
check_gitlab_shell_self_test
@@ -417,29 +384,6 @@ namespace :gitlab do
end
end
- def check_satellites_permissions
- print "Satellites access is drwxr-x---? ... "
-
- satellites_path = Gitlab.config.satellites.path
- unless File.exists?(satellites_path)
- puts "can't check because of previous errors".magenta
- return
- end
-
- if File.stat(satellites_path).mode.to_s(8).ends_with?("0750")
- puts "yes".green
- else
- puts "no".red
- try_fixing_it(
- "sudo chmod u+rwx,g=rx,o-rwx #{satellites_path}",
- )
- for_more_information(
- see_installation_guide_section "GitLab"
- )
- fix_and_rerun
- end
- end
-
def check_repo_base_user_and_group
gitlab_shell_ssh_user = Gitlab.config.gitlab_shell.ssh_user
gitlab_shell_owner_group = Gitlab.config.gitlab_shell.owner_group
diff --git a/lib/tasks/gitlab/enable_automerge.rake b/lib/tasks/gitlab/enable_automerge.rake
deleted file mode 100644
index 3dade9d75b8..00000000000
--- a/lib/tasks/gitlab/enable_automerge.rake
+++ /dev/null
@@ -1,39 +0,0 @@
-namespace :gitlab do
- namespace :satellites do
- desc "GitLab | Create satellite repos"
- task create: :environment do
- create_satellites
- end
- end
-
- def create_satellites
- warn_user_is_not_gitlab
-
- print "Creating satellites for ..."
- unless Project.count > 0
- puts "skipping, because you have no projects".magenta
- return
- end
- puts ""
-
- Project.find_each(batch_size: 100) do |project|
- print "#{project.name_with_namespace.yellow} ... "
-
- unless project.repo_exists?
- puts "skipping, because the repo is empty".magenta
- next
- end
-
- if project.satellite.exists?
- puts "exists already".green
- else
- print "\n... "
- if project.satellite.create
- puts "created".green
- else
- puts "error".red
- end
- end
- end
- end
-end
diff --git a/spec/controllers/admin/users_controller_spec.rb b/spec/controllers/admin/users_controller_spec.rb
index 6f4c8987637..c40b2c2a583 100644
--- a/spec/controllers/admin/users_controller_spec.rb
+++ b/spec/controllers/admin/users_controller_spec.rb
@@ -37,6 +37,20 @@ describe Admin::UsersController do
end
end
+ describe 'PUT confirm/:id' do
+ let(:user) { create(:user, confirmed_at: nil) }
+
+ before do
+ request.env["HTTP_REFERER"] = "/"
+ end
+
+ it 'confirms user' do
+ put :confirm, id: user.username
+ user.reload
+ expect(user.confirmed?).to be_truthy
+ end
+ end
+
describe 'PATCH disable_two_factor' do
let(:user) { create(:user) }
diff --git a/spec/controllers/autocomplete_controller_spec.rb b/spec/controllers/autocomplete_controller_spec.rb
index 1230017c270..3521d690259 100644
--- a/spec/controllers/autocomplete_controller_spec.rb
+++ b/spec/controllers/autocomplete_controller_spec.rb
@@ -4,6 +4,7 @@ describe AutocompleteController do
let!(:project) { create(:project) }
let!(:user) { create(:user) }
let!(:user2) { create(:user) }
+ let!(:non_member) { create(:user) }
context 'project members' do
before do
@@ -61,6 +62,27 @@ describe AutocompleteController do
end
end
+ context 'non-member login for public project' do
+ let!(:project) { create(:project, :public) }
+
+ before do
+ sign_in(non_member)
+ project.team << [user, :master]
+ end
+
+ let(:body) { JSON.parse(response.body) }
+
+ describe 'GET #users with project ID' do
+ before do
+ get(:users, project_id: project.id)
+ end
+
+ it { expect(body).to be_kind_of(Array) }
+ it { expect(body.size).to eq 2 }
+ it { expect(body.map { |u| u['username'] }).to match_array([user.username, non_member.username]) }
+ end
+ end
+
context 'all users' do
before do
sign_in(user)
diff --git a/spec/controllers/branches_controller_spec.rb b/spec/controllers/branches_controller_spec.rb
index bd4c946b64b..8e06d4bdc77 100644
--- a/spec/controllers/branches_controller_spec.rb
+++ b/spec/controllers/branches_controller_spec.rb
@@ -54,6 +54,13 @@ describe Projects::BranchesController do
let(:ref) { "<script>alert('ref');</script>" }
it { is_expected.to render_template('new') }
end
+
+ context "valid branch name with encoded slashes" do
+ let(:branch) { "feature%2Ftest" }
+ let(:ref) { "<script>alert('ref');</script>" }
+ it { is_expected.to render_template('new') }
+ it { project.repository.branch_names.include?('feature/test')}
+ end
end
describe "POST destroy" do
@@ -74,6 +81,19 @@ describe Projects::BranchesController do
it { expect(subject).to render_template('destroy') }
end
+ context "valid branch name with unencoded slashes" do
+ let(:branch) { "improve/awesome" }
+
+ it { expect(response.status).to eq(200) }
+ it { expect(subject).to render_template('destroy') }
+ end
+
+ context "valid branch name with encoded slashes" do
+ let(:branch) { "improve%2Fawesome" }
+
+ it { expect(response.status).to eq(200) }
+ it { expect(subject).to render_template('destroy') }
+ end
context "invalid branch name, valid ref" do
let(:branch) { "no-branch" }
diff --git a/spec/controllers/import/bitbucket_controller_spec.rb b/spec/controllers/import/bitbucket_controller_spec.rb
index d5d9310e603..89e595121a7 100644
--- a/spec/controllers/import/bitbucket_controller_spec.rb
+++ b/spec/controllers/import/bitbucket_controller_spec.rb
@@ -39,12 +39,14 @@ describe Import::BitbucketController do
it "assigns variables" do
@project = create(:project, import_type: 'bitbucket', creator_id: user.id)
- stub_client(projects: [@repo])
+ client = stub_client(projects: [@repo])
+ allow(client).to receive(:incompatible_projects).and_return([])
get :status
expect(assigns(:already_added_projects)).to eq([@project])
expect(assigns(:repos)).to eq([@repo])
+ expect(assigns(:incompatible_repos)).to eq([])
end
it "does not show already added project" do
diff --git a/spec/controllers/profile_keys_controller_spec.rb b/spec/controllers/profile_keys_controller_spec.rb
index 593d3e9eb56..b6573f105dc 100644
--- a/spec/controllers/profile_keys_controller_spec.rb
+++ b/spec/controllers/profile_keys_controller_spec.rb
@@ -48,6 +48,17 @@ describe Profiles::KeysController do
expect(response.body).not_to eq("")
expect(response.body).to eq(user.all_ssh_keys.join("\n"))
+
+ # Unique part of key 1
+ expect(response.body).to match(/PWx6WM4lhHNedGfBpPJNPpZ/)
+ # Key 2
+ expect(response.body).to match(/AQDmTillFzNTrrGgwaCKaSj/)
+ end
+
+ it "should not render the comment of the key" do
+ get :get_keys, username: user.username
+
+ expect(response.body).not_to match(/dummy@gitlab.com/)
end
it "should respond with text/plain content type" do
diff --git a/spec/factories.rb b/spec/factories.rb
index 05e3211d551..200f18f660d 100644
--- a/spec/factories.rb
+++ b/spec/factories.rb
@@ -100,7 +100,7 @@ FactoryGirl.define do
factory :key do
title
key do
- "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0="
+ "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0= dummy@gitlab.com"
end
factory :deploy_key, class: 'DeployKey' do
diff --git a/spec/factories/abuse_reports.rb b/spec/factories/abuse_reports.rb
new file mode 100644
index 00000000000..29fcbc5e197
--- /dev/null
+++ b/spec/factories/abuse_reports.rb
@@ -0,0 +1,9 @@
+# Read about factories at https://github.com/thoughtbot/factory_girl
+
+FactoryGirl.define do
+ factory :abuse_report do
+ reporter factory: :user
+ user
+ message 'User sends spam'
+ end
+end
diff --git a/spec/features/projects_spec.rb b/spec/features/projects_spec.rb
index c8d44efdc8b..a362c54b9ad 100644
--- a/spec/features/projects_spec.rb
+++ b/spec/features/projects_spec.rb
@@ -22,9 +22,9 @@ feature 'Project', feature: true do
end
it 'sanitizes unwanted tags' do
- project.update_attribute(:description, '# Project Description')
+ project.update_attribute(:description, "```\ncode\n```")
visit path
- expect(page).not_to have_css('.project-home-desc h1')
+ expect(page).not_to have_css('.project-home-desc code')
end
it 'permits `rel` attribute on links' do
diff --git a/spec/finders/projects_finder_spec.rb b/spec/finders/projects_finder_spec.rb
index 2ab71b05968..de9d4cd6128 100644
--- a/spec/finders/projects_finder_spec.rb
+++ b/spec/finders/projects_finder_spec.rb
@@ -39,7 +39,7 @@ describe ProjectsFinder do
end
context 'authenticated, group member' do
- before { group.add_user(user, Gitlab::Access::DEVELOPER) }
+ before { group.add_developer(user) }
subject { ProjectsFinder.new.execute(user, group: group) }
diff --git a/spec/lib/extracts_path_spec.rb b/spec/lib/extracts_path_spec.rb
index 4439775f612..9c115bbfc6a 100644
--- a/spec/lib/extracts_path_spec.rb
+++ b/spec/lib/extracts_path_spec.rb
@@ -29,6 +29,16 @@ describe ExtractsPath do
assign_ref_vars
expect(@logs_path).to eq("/#{@project.path_with_namespace}/refs/#{ref}/logs_tree/files/ruby/popen.rb")
end
+
+ context 'escaped sequences in ref' do
+ let(:ref) { "improve%2Fawesome" }
+
+ it "id should have no escape sequences" do
+ assign_ref_vars
+ expect(@ref).to eq('improve/awesome')
+ expect(@logs_path).to eq("/#{@project.path_with_namespace}/refs/#{ref}/logs_tree/files/ruby/popen.rb")
+ end
+ end
end
describe '#extract_ref' do
diff --git a/spec/lib/gitlab/markdown/user_reference_filter_spec.rb b/spec/lib/gitlab/markdown/user_reference_filter_spec.rb
index 08e6941028f..9c55b4ff38f 100644
--- a/spec/lib/gitlab/markdown/user_reference_filter_spec.rb
+++ b/spec/lib/gitlab/markdown/user_reference_filter_spec.rb
@@ -77,7 +77,7 @@ module Gitlab::Markdown
context 'that the current user can read' do
before do
- group.add_user(user, Gitlab::Access::DEVELOPER)
+ group.add_developer(user)
end
it 'links to the Group' do
diff --git a/spec/lib/gitlab/note_data_builder_spec.rb b/spec/lib/gitlab/note_data_builder_spec.rb
index 5826144e66b..448cd0c6880 100644
--- a/spec/lib/gitlab/note_data_builder_spec.rb
+++ b/spec/lib/gitlab/note_data_builder_spec.rb
@@ -36,7 +36,6 @@ describe 'Gitlab::NoteDataBuilder' do
let(:note) { create(:note_on_issue, noteable_id: issue.id) }
it 'returns the note and issue-specific data' do
- data[:issue]["updated_at"] = fixed_time
expect(data).to have_key(:issue)
expect(data[:issue]).to eq(issue.hook_attrs)
end
@@ -47,7 +46,6 @@ describe 'Gitlab::NoteDataBuilder' do
let(:note) { create(:note_on_merge_request, noteable_id: merge_request.id) }
it 'returns the note and merge request data' do
- data[:merge_request]["updated_at"] = fixed_time
expect(data).to have_key(:merge_request)
expect(data[:merge_request]).to eq(merge_request.hook_attrs)
end
@@ -58,7 +56,6 @@ describe 'Gitlab::NoteDataBuilder' do
let(:note) { create(:note_on_merge_request_diff, noteable_id: merge_request.id) }
it 'returns the note and merge request diff data' do
- data[:merge_request]["updated_at"] = fixed_time
expect(data).to have_key(:merge_request)
expect(data[:merge_request]).to eq(merge_request.hook_attrs)
end
@@ -69,7 +66,6 @@ describe 'Gitlab::NoteDataBuilder' do
let!(:note) { create(:note_on_project_snippet, noteable_id: snippet.id) }
it 'returns the note and project snippet data' do
- data[:snippet]["updated_at"] = fixed_time
expect(data).to have_key(:snippet)
expect(data[:snippet]).to eq(snippet.hook_attrs)
end
diff --git a/spec/lib/gitlab/reference_extractor_spec.rb b/spec/lib/gitlab/reference_extractor_spec.rb
index f921dd9cc09..088e34f050c 100644
--- a/spec/lib/gitlab/reference_extractor_spec.rb
+++ b/spec/lib/gitlab/reference_extractor_spec.rb
@@ -25,7 +25,7 @@ describe Gitlab::ReferenceExtractor do
project.team << [@u_bar, :guest]
subject.analyze(%Q{
- Inline code: `@foo`
+ Inline code: `@foo`
Code block:
@@ -33,7 +33,7 @@ describe Gitlab::ReferenceExtractor do
@bar
```
- Quote:
+ Quote:
> @offteam
})
@@ -49,8 +49,8 @@ describe Gitlab::ReferenceExtractor do
end
it 'accesses valid merge requests' do
- @m0 = create(:merge_request, source_project: project, target_project: project, source_branch: 'aaa')
- @m1 = create(:merge_request, source_project: project, target_project: project, source_branch: 'bbb')
+ @m0 = create(:merge_request, source_project: project, target_project: project, source_branch: 'markdown')
+ @m1 = create(:merge_request, source_project: project, target_project: project, source_branch: 'feature_conflict')
subject.analyze("!999, !#{@m1.iid}, and !#{@m0.iid}.")
expect(subject.merge_requests).to eq([@m1, @m0])
diff --git a/spec/lib/gitlab/satellite/action_spec.rb b/spec/lib/gitlab/satellite/action_spec.rb
deleted file mode 100644
index 0a93676edc3..00000000000
--- a/spec/lib/gitlab/satellite/action_spec.rb
+++ /dev/null
@@ -1,116 +0,0 @@
-require 'spec_helper'
-
-describe 'Gitlab::Satellite::Action' do
- let(:project) { create(:project) }
- let(:user) { create(:user) }
-
- describe '#prepare_satellite!' do
- it 'should be able to fetch timeout from conf' do
- expect(Gitlab::Satellite::Action::DEFAULT_OPTIONS[:git_timeout]).to eq(30.seconds)
- end
-
- it 'create a repository with a parking branch and one remote: origin' do
- repo = project.satellite.repo
-
- #now lets dirty it up
-
- starting_remote_count = repo.git.list_remotes.size
- expect(starting_remote_count).to be >= 1
- #kind of hookey way to add a second remote
- origin_uri = repo.git.remote({ v: true }).split(" ")[1]
-
- repo.git.remote({ raise: true }, 'add', 'another-remote', origin_uri)
- repo.git.branch({ raise: true }, 'a-new-branch')
-
- expect(repo.heads.size).to be > (starting_remote_count)
- expect(repo.git.remote().split(" ").size).to be > (starting_remote_count)
-
- repo.git.config({}, "user.name", "#{user.name} -- foo")
- repo.git.config({}, "user.email", "#{user.email} -- foo")
- expect(repo.config['user.name']).to eq("#{user.name} -- foo")
- expect(repo.config['user.email']).to eq("#{user.email} -- foo")
-
-
- #These must happen in the context of the satellite directory...
- satellite_action = Gitlab::Satellite::Action.new(user, project)
- project.satellite.lock do
- #Now clean it up, use send to get around prepare_satellite! being protected
- satellite_action.send(:prepare_satellite!, repo)
- end
-
- #verify it's clean
- heads = repo.heads.map(&:name)
- expect(heads.size).to eq(1)
- expect(heads.include?(Gitlab::Satellite::Satellite::PARKING_BRANCH)).to eq(true)
- remotes = repo.git.remote().split(' ')
- expect(remotes.size).to eq(1)
- expect(remotes.include?('origin')).to eq(true)
- expect(repo.config['user.name']).to eq(user.name)
- expect(repo.config['user.email']).to eq(user.email)
- end
- end
-
- describe '#in_locked_and_timed_satellite' do
-
- it 'should make use of a lockfile' do
- repo = project.satellite.repo
- called = false
-
- #set assumptions
- FileUtils.rm_f(project.satellite.lock_file)
-
- expect(File.exists?(project.satellite.lock_file)).to be_falsey
-
- satellite_action = Gitlab::Satellite::Action.new(user, project)
- satellite_action.send(:in_locked_and_timed_satellite) do |sat_repo|
- expect(repo).to eq(sat_repo)
- expect(File.exists? project.satellite.lock_file).to be_truthy
- called = true
- end
-
- expect(called).to be_truthy
-
- end
-
- it 'should be able to use the satellite after locking' do
- repo = project.satellite.repo
- called = false
-
- # Set base assumptions
- if File.exists? project.satellite.lock_file
- expect(FileLockStatusChecker.new(project.satellite.lock_file).flocked?).to be_falsey
- end
-
- satellite_action = Gitlab::Satellite::Action.new(user, project)
- satellite_action.send(:in_locked_and_timed_satellite) do |sat_repo|
- called = true
- expect(repo).to eq(sat_repo)
- expect(File.exists? project.satellite.lock_file).to be_truthy
- expect(FileLockStatusChecker.new(project.satellite.lock_file).flocked?).to be_truthy
- end
-
- expect(called).to be_truthy
- expect(FileLockStatusChecker.new(project.satellite.lock_file).flocked?).to be_falsey
-
- end
-
- class FileLockStatusChecker < File
- def flocked?(&block)
- status = flock LOCK_EX|LOCK_NB
- case status
- when false
- return true
- when 0
- begin
- block ? block.call : false
- ensure
- flock LOCK_UN
- end
- else
- raise SystemCallError, status
- end
- end
- end
-
- end
-end
diff --git a/spec/lib/gitlab/satellite/merge_action_spec.rb b/spec/lib/gitlab/satellite/merge_action_spec.rb
deleted file mode 100644
index 9b1c9a34e29..00000000000
--- a/spec/lib/gitlab/satellite/merge_action_spec.rb
+++ /dev/null
@@ -1,104 +0,0 @@
-require 'spec_helper'
-
-describe 'Gitlab::Satellite::MergeAction' do
- include RepoHelpers
-
- let(:project) { create(:project, namespace: create(:group)) }
- let(:fork_project) { create(:project, namespace: create(:group), forked_from_project: project) }
- let(:merge_request) { create(:merge_request, source_project: project, target_project: project) }
- let(:merge_request_fork) { create(:merge_request, source_project: fork_project, target_project: project) }
-
- let(:merge_request_with_conflict) { create(:merge_request, :conflict, source_project: project, target_project: project) }
- let(:merge_request_fork_with_conflict) { create(:merge_request, :conflict, source_project: project, target_project: project) }
-
- describe '#commits_between' do
- def verify_commits(commits, first_commit_sha, last_commit_sha)
- commits.each { |commit| expect(commit.class).to eq(Gitlab::Git::Commit) }
- expect(commits.first.id).to eq(first_commit_sha)
- expect(commits.last.id).to eq(last_commit_sha)
- end
-
- context 'on fork' do
- it 'should get proper commits between' do
- commits = Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request_fork).commits_between
- verify_commits(commits, sample_compare.commits.first, sample_compare.commits.last)
- end
- end
-
- context 'between branches' do
- it 'should raise exception -- not expected to be used by non forks' do
- expect { Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).commits_between }.to raise_error(RuntimeError)
- end
- end
- end
-
- describe '#format_patch' do
- def verify_content(patch)
- sample_compare.commits.each do |commit|
- expect(patch.include?(commit)).to be_truthy
- end
- end
-
- context 'on fork' do
- it 'should build a format patch' do
- patch = Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request_fork).format_patch
- verify_content(patch)
- end
- end
-
- context 'between branches' do
- it 'should build a format patch' do
- patch = Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request).format_patch
- verify_content(patch)
- end
- end
- end
-
- describe '#diffs_between_satellite tested against diff_in_satellite' do
- def is_a_matching_diff(diff, diffs)
- diff_count = diff.scan('diff --git').size
- expect(diff_count).to be >= 1
- expect(diffs.size).to eq(diff_count)
- diffs.each do |a_diff|
- expect(a_diff.class).to eq(Gitlab::Git::Diff)
- expect(diff.include? a_diff.diff).to be_truthy
- end
- end
-
- context 'on fork' do
- it 'should get proper diffs' do
- diffs = Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request_fork).diffs_between_satellite
- diff = Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request_fork).diff_in_satellite
- is_a_matching_diff(diff, diffs)
- end
- end
-
- context 'between branches' do
- it 'should get proper diffs' do
- expect{ Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).diffs_between_satellite }.to raise_error(RuntimeError)
- end
- end
- end
-
- describe '#can_be_merged?' do
- context 'on fork' do
- it do
- expect(Gitlab::Satellite::MergeAction.new(merge_request_fork.author, merge_request_fork).can_be_merged?).to be_truthy
- end
-
- it do
- expect(Gitlab::Satellite::MergeAction.new(merge_request_fork_with_conflict.author, merge_request_fork_with_conflict).can_be_merged?).to be_falsey
- end
- end
-
- context 'between branches' do
- it do
- expect(Gitlab::Satellite::MergeAction.new(merge_request.author, merge_request).can_be_merged?).to be_truthy
- end
-
- it do
- expect(Gitlab::Satellite::MergeAction.new(merge_request_with_conflict.author, merge_request_with_conflict).can_be_merged?).to be_falsey
- end
- end
- end
-end
diff --git a/spec/models/abuse_report_spec.rb b/spec/models/abuse_report_spec.rb
new file mode 100644
index 00000000000..d83004a8388
--- /dev/null
+++ b/spec/models/abuse_report_spec.rb
@@ -0,0 +1,7 @@
+require 'rails_helper'
+
+RSpec.describe AbuseReport, type: :model do
+ subject { create(:abuse_report) }
+
+ it { expect(subject).to be_valid }
+end
diff --git a/spec/models/hooks/system_hook_spec.rb b/spec/models/hooks/system_hook_spec.rb
index 4175f9dd88f..02d2cc2c77a 100644
--- a/spec/models/hooks/system_hook_spec.rb
+++ b/spec/models/hooks/system_hook_spec.rb
@@ -101,7 +101,7 @@ describe SystemHook do
it 'group member create hook' do
group = create(:group)
user = create(:user)
- group.add_user(user, Gitlab::Access::MASTER)
+ group.add_master(user)
expect(WebMock).to have_requested(:post, @system_hook.url).with(
body: /user_add_to_group/,
headers: { 'Content-Type'=>'application/json', 'X-Gitlab-Event'=>'System Hook' }
@@ -111,7 +111,7 @@ describe SystemHook do
it 'group member destroy hook' do
group = create(:group)
user = create(:user)
- group.add_user(user, Gitlab::Access::MASTER)
+ group.add_master(user)
group.group_members.destroy_all
expect(WebMock).to have_requested(:post, @system_hook.url).with(
body: /user_remove_from_group/,
diff --git a/spec/models/key_spec.rb b/spec/models/key_spec.rb
index 456bf221d62..2f819f60cbb 100644
--- a/spec/models/key_spec.rb
+++ b/spec/models/key_spec.rb
@@ -32,6 +32,13 @@ describe Key do
describe "Methods" do
it { is_expected.to respond_to :projects }
+ it { is_expected.to respond_to :publishable_key }
+
+ describe "#publishable_keys" do
+ it 'strips all personal information' do
+ expect(build(:key).publishable_key).not_to match(/dummy@gitlab/)
+ end
+ end
end
context "validation of uniqueness" do
diff --git a/spec/models/merge_request_spec.rb b/spec/models/merge_request_spec.rb
index 76f6d8c54c4..b91687bc09f 100644
--- a/spec/models/merge_request_spec.rb
+++ b/spec/models/merge_request_spec.rb
@@ -165,7 +165,7 @@ describe MergeRequest do
end
it_behaves_like 'an editable mentionable' do
- subject { create(:merge_request, source_project: project) }
+ subject { create(:merge_request) }
let(:backref_text) { "merge request #{subject.to_reference}" }
let(:set_mentionable_text) { ->(txt){ subject.description = txt } }
diff --git a/spec/models/note_spec.rb b/spec/models/note_spec.rb
index eba33dd510f..250d1e2da80 100644
--- a/spec/models/note_spec.rb
+++ b/spec/models/note_spec.rb
@@ -22,7 +22,7 @@ require 'spec_helper'
describe Note do
describe 'associations' do
it { is_expected.to belong_to(:project) }
- it { is_expected.to belong_to(:noteable).touch(true) }
+ it { is_expected.to belong_to(:noteable) }
it { is_expected.to belong_to(:author).class_name('User') }
end
diff --git a/spec/models/project_services/slack_service_spec.rb b/spec/models/project_services/slack_service_spec.rb
index 69466b11f09..97b60e19e40 100644
--- a/spec/models/project_services/slack_service_spec.rb
+++ b/spec/models/project_services/slack_service_spec.rb
@@ -67,7 +67,7 @@ describe SlackService do
opts = {
title: 'Awesome merge_request',
description: 'please fix',
- source_branch: 'stable',
+ source_branch: 'feature',
target_branch: 'master'
}
merge_service = MergeRequests::CreateService.new(project,
diff --git a/spec/models/project_spec.rb b/spec/models/project_spec.rb
index 5d40754d59d..2fcbd5ae108 100644
--- a/spec/models/project_spec.rb
+++ b/spec/models/project_spec.rb
@@ -91,7 +91,6 @@ describe Project do
describe 'Respond to' do
it { is_expected.to respond_to(:url_to_repo) }
it { is_expected.to respond_to(:repo_exists?) }
- it { is_expected.to respond_to(:satellite) }
it { is_expected.to respond_to(:update_merge_requests) }
it { is_expected.to respond_to(:execute_hooks) }
it { is_expected.to respond_to(:name_with_namespace) }
diff --git a/spec/models/project_team_spec.rb b/spec/models/project_team_spec.rb
index d125166e336..cc1138490a0 100644
--- a/spec/models/project_team_spec.rb
+++ b/spec/models/project_team_spec.rb
@@ -37,9 +37,9 @@ describe ProjectTeam do
let(:project) { create(:empty_project, group: group) }
before do
- group.add_user(master, Gitlab::Access::MASTER)
- group.add_user(reporter, Gitlab::Access::REPORTER)
- group.add_user(guest, Gitlab::Access::GUEST)
+ group.add_master(master)
+ group.add_reporter(reporter)
+ group.add_guest(guest)
# If user is a group and a project member - GitLab uses highest permission
# So we add group guest as master and add group master as guest
diff --git a/spec/models/repository_spec.rb b/spec/models/repository_spec.rb
index d25351b0f0e..d96244f23e0 100644
--- a/spec/models/repository_spec.rb
+++ b/spec/models/repository_spec.rb
@@ -36,13 +36,13 @@ describe Repository do
describe :can_be_merged? do
context 'mergeable branches' do
- subject { repository.can_be_merged?('feature', 'master') }
+ subject { repository.can_be_merged?('0b4bc9a49b562e85de7cc9e834518ea6828729b9', 'master') }
it { is_expected.to be_truthy }
end
context 'non-mergeable branches' do
- subject { repository.can_be_merged?('feature_conflict', 'feature') }
+ subject { repository.can_be_merged?('bb5206fee213d983da88c47f9cf4cc6caf9c66dc', 'feature') }
it { is_expected.to be_falsey }
end
diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb
index 922e9ebf844..876cfb1204a 100644
--- a/spec/models/user_spec.rb
+++ b/spec/models/user_spec.rb
@@ -184,6 +184,19 @@ describe User do
it { is_expected.to respond_to(:private_token) }
end
+ describe '#confirm' do
+ let(:user) { create(:user, confirmed_at: nil, unconfirmed_email: 'test@gitlab.com') }
+
+ it 'returns unconfirmed' do
+ expect(user.confirmed?).to be_falsey
+ end
+
+ it 'confirms a user' do
+ user.confirm!
+ expect(user.confirmed?).to be_truthy
+ end
+ end
+
describe '#to_reference' do
let(:user) { create(:user) }
diff --git a/spec/requests/api/files_spec.rb b/spec/requests/api/files_spec.rb
index 6c7860511e8..8cb8790c339 100644
--- a/spec/requests/api/files_spec.rb
+++ b/spec/requests/api/files_spec.rb
@@ -110,7 +110,7 @@ describe API::API, api: true do
expect(response.status).to eq(400)
end
- it "should return a 400 if satellite fails to create file" do
+ it "should return a 400 if fails to create file" do
allow_any_instance_of(Repository).to receive(:remove_file).and_return(false)
delete api("/projects/#{project.id}/repository/files", user), valid_params
diff --git a/spec/requests/api/groups_spec.rb b/spec/requests/api/groups_spec.rb
index c5a4ac7e4c4..1d5b4f6f36b 100644
--- a/spec/requests/api/groups_spec.rb
+++ b/spec/requests/api/groups_spec.rb
@@ -135,7 +135,7 @@ describe API::API, api: true do
it "should not remove a group if not an owner" do
user4 = create(:user)
- group1.add_user(user4, Gitlab::Access::MASTER)
+ group1.add_master(user4)
delete api("/groups/#{group1.id}", user3)
expect(response.status).to eq(403)
end
diff --git a/spec/requests/api/merge_requests_spec.rb b/spec/requests/api/merge_requests_spec.rb
index 29db035b2de..942768fa254 100644
--- a/spec/requests/api/merge_requests_spec.rb
+++ b/spec/requests/api/merge_requests_spec.rb
@@ -148,7 +148,7 @@ describe API::API, api: true do
it "should return merge_request" do
post api("/projects/#{project.id}/merge_requests", user),
title: 'Test merge_request',
- source_branch: 'stable',
+ source_branch: 'feature_conflict',
target_branch: 'master',
author: user,
labels: 'label, label2'
@@ -171,20 +171,20 @@ describe API::API, api: true do
it "should return 400 when target_branch is missing" do
post api("/projects/#{project.id}/merge_requests", user),
- title: "Test merge_request", source_branch: "stable", author: user
+ title: "Test merge_request", source_branch: "markdown", author: user
expect(response.status).to eq(400)
end
it "should return 400 when title is missing" do
post api("/projects/#{project.id}/merge_requests", user),
- target_branch: 'master', source_branch: 'stable'
+ target_branch: 'master', source_branch: 'markdown'
expect(response.status).to eq(400)
end
it 'should return 400 on invalid label names' do
post api("/projects/#{project.id}/merge_requests", user),
title: 'Test merge_request',
- source_branch: 'stable',
+ source_branch: 'markdown',
target_branch: 'master',
author: user,
labels: 'label, ?'
@@ -198,7 +198,7 @@ describe API::API, api: true do
before do
post api("/projects/#{project.id}/merge_requests", user),
title: 'Test merge_request',
- source_branch: 'stable',
+ source_branch: 'feature_conflict',
target_branch: 'master',
author: user
@mr = MergeRequest.all.last
@@ -208,7 +208,7 @@ describe API::API, api: true do
expect do
post api("/projects/#{project.id}/merge_requests", user),
title: 'New test merge_request',
- source_branch: 'stable',
+ source_branch: 'feature_conflict',
target_branch: 'master',
author: user
end.to change { MergeRequest.count }.by(0)
@@ -228,7 +228,8 @@ describe API::API, api: true do
it "should return merge_request" do
post api("/projects/#{fork_project.id}/merge_requests", user2),
- title: 'Test merge_request', source_branch: "stable", target_branch: "master", author: user2, target_project_id: project.id, description: 'Test description for Test merge_request'
+ title: 'Test merge_request', source_branch: "feature_conflict", target_branch: "master",
+ author: user2, target_project_id: project.id, description: 'Test description for Test merge_request'
expect(response.status).to eq(201)
expect(json_response['title']).to eq('Test merge_request')
expect(json_response['description']).to eq('Test description for Test merge_request')
@@ -258,7 +259,7 @@ describe API::API, api: true do
it "should return 400 when title is missing" do
post api("/projects/#{fork_project.id}/merge_requests", user2),
- target_branch: 'master', source_branch: 'stable', author: user2, target_project_id: project.id
+ target_branch: 'master', source_branch: 'markdown', author: user2, target_project_id: project.id
expect(response.status).to eq(400)
end
@@ -267,7 +268,7 @@ describe API::API, api: true do
post api("/projects/#{project.id}/merge_requests", user),
title: 'Test merge_request',
target_branch: 'master',
- source_branch: 'stable',
+ source_branch: 'markdown',
author: user,
target_project_id: fork_project.id
expect(response.status).to eq(422)
@@ -277,7 +278,7 @@ describe API::API, api: true do
post api("/projects/#{fork_project.id}/merge_requests", user2),
title: 'Test merge_request',
target_branch: 'master',
- source_branch: 'stable',
+ source_branch: 'markdown',
author: user2,
target_project_id: unrelated_project.id
expect(response.status).to eq(422)
@@ -286,7 +287,7 @@ describe API::API, api: true do
it "should return 201 when target_branch is specified and for the same project" do
post api("/projects/#{fork_project.id}/merge_requests", user2),
- title: 'Test merge_request', target_branch: 'master', source_branch: 'stable', author: user2, target_project_id: fork_project.id
+ title: 'Test merge_request', target_branch: 'master', source_branch: 'markdown', author: user2, target_project_id: fork_project.id
expect(response.status).to eq(201)
end
end
@@ -302,9 +303,6 @@ describe API::API, api: true do
describe "PUT /projects/:id/merge_request/:merge_request_id/merge" do
it "should return merge_request in case of success" do
- allow_any_instance_of(MergeRequest).
- to receive_messages(can_be_merged?: true, automerge!: true)
-
put api("/projects/#{project.id}/merge_request/#{merge_request.id}/merge", user)
expect(response.status).to eq(200)
diff --git a/spec/routing/project_routing_spec.rb b/spec/routing/project_routing_spec.rb
index 0040718d9be..82f62a8709c 100644
--- a/spec/routing/project_routing_spec.rb
+++ b/spec/routing/project_routing_spec.rb
@@ -210,8 +210,8 @@ end
# diffs_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/diffs(.:format) projects/merge_requests#diffs
# commits_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/commits(.:format) projects/merge_requests#commits
-# automerge_namespace_project_merge_request POST /:namespace_id/:project_id/merge_requests/:id/automerge(.:format) projects/merge_requests#automerge
-# automerge_check_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/automerge_check(.:format) projects/merge_requests#automerge_check
+# merge_namespace_project_merge_request POST /:namespace_id/:project_id/merge_requests/:id/merge(.:format) projects/merge_requests#merge
+# merge_check_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/merge_check(.:format) projects/merge_requests#merge_check
# ci_status_namespace_project_merge_request GET /:namespace_id/:project_id/merge_requests/:id/ci_status(.:format) projects/merge_requests#ci_status
# toggle_subscription_namespace_project_merge_request POST /:namespace_id/:project_id/merge_requests/:id/toggle_subscription(.:format) projects/merge_requests#toggle_subscription
# branch_from_namespace_project_merge_requests GET /:namespace_id/:project_id/merge_requests/branch_from(.:format) projects/merge_requests#branch_from
@@ -233,15 +233,15 @@ describe Projects::MergeRequestsController, 'routing' do
expect(get('/gitlab/gitlabhq/merge_requests/1/commits')).to route_to('projects/merge_requests#commits', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
end
- it 'to #automerge' do
- expect(post('/gitlab/gitlabhq/merge_requests/1/automerge')).to route_to(
- 'projects/merge_requests#automerge',
+ it 'to #merge' do
+ expect(post('/gitlab/gitlabhq/merge_requests/1/merge')).to route_to(
+ 'projects/merge_requests#merge',
namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1'
)
end
- it 'to #automerge_check' do
- expect(get('/gitlab/gitlabhq/merge_requests/1/automerge_check')).to route_to('projects/merge_requests#automerge_check', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
+ it 'to #merge_check' do
+ expect(get('/gitlab/gitlabhq/merge_requests/1/merge_check')).to route_to('projects/merge_requests#merge_check', namespace_id: 'gitlab', project_id: 'gitlabhq', id: '1')
end
it 'to #branch_from' do
diff --git a/spec/services/merge_requests/create_service_spec.rb b/spec/services/merge_requests/create_service_spec.rb
index d9bfdf64308..cc64d69361e 100644
--- a/spec/services/merge_requests/create_service_spec.rb
+++ b/spec/services/merge_requests/create_service_spec.rb
@@ -10,7 +10,7 @@ describe MergeRequests::CreateService do
{
title: 'Awesome merge_request',
description: 'please fix',
- source_branch: 'stable',
+ source_branch: 'feature',
target_branch: 'master'
}
end
diff --git a/spec/services/merge_requests/merge_service_spec.rb b/spec/services/merge_requests/merge_service_spec.rb
index 0a25fb12f4e..7b564d34d7b 100644
--- a/spec/services/merge_requests/merge_service_spec.rb
+++ b/spec/services/merge_requests/merge_service_spec.rb
@@ -24,11 +24,6 @@ describe MergeRequests::MergeService do
it { expect(merge_request).to be_valid }
it { expect(merge_request).to be_merged }
- it 'should execute hooks with merge action' do
- expect(service).to have_received(:execute_hooks).
- with(merge_request, 'merge')
- end
-
it 'should send email to user2 about merge of new merge_request' do
email = ActionMailer::Base.deliveries.last
expect(email.to.first).to eq(user2.email)
diff --git a/spec/services/notification_service_spec.rb b/spec/services/notification_service_spec.rb
index 253e5823499..9da6c9dc949 100644
--- a/spec/services/notification_service_spec.rb
+++ b/spec/services/notification_service_spec.rb
@@ -300,7 +300,7 @@ describe NotificationService do
describe 'Merge Requests' do
let(:project) { create(:project, :public) }
- let(:merge_request) { create :merge_request, source_project: project, assignee: create(:user) }
+ let(:merge_request) { create :merge_request, source_project: project, assignee: create(:user), description: 'cc @participant' }
before do
build_team(merge_request.target_project)
@@ -311,6 +311,7 @@ describe NotificationService do
it do
should_email(merge_request.assignee_id)
should_email(@u_watcher.id)
+ should_email(@u_participant_mentioned.id)
should_not_email(@u_participating.id)
should_not_email(@u_disabled.id)
notification.new_merge_request(merge_request, @u_disabled)
@@ -329,6 +330,7 @@ describe NotificationService do
it do
should_email(merge_request.assignee_id)
should_email(@u_watcher.id)
+ should_email(@u_participant_mentioned.id)
should_email(@subscriber.id)
should_not_email(@unsubscriber.id)
should_not_email(@u_participating.id)
@@ -349,6 +351,7 @@ describe NotificationService do
it do
should_email(merge_request.assignee_id)
should_email(@u_watcher.id)
+ should_email(@u_participant_mentioned.id)
should_email(@subscriber.id)
should_not_email(@unsubscriber.id)
should_not_email(@u_participating.id)
@@ -369,6 +372,7 @@ describe NotificationService do
it do
should_email(merge_request.assignee_id)
should_email(@u_watcher.id)
+ should_email(@u_participant_mentioned.id)
should_email(@subscriber.id)
should_not_email(@unsubscriber.id)
should_not_email(@u_participating.id)
@@ -389,6 +393,7 @@ describe NotificationService do
it do
should_email(merge_request.assignee_id)
should_email(@u_watcher.id)
+ should_email(@u_participant_mentioned.id)
should_email(@subscriber.id)
should_not_email(@unsubscriber.id)
should_not_email(@u_participating.id)
diff --git a/spec/support/markdown_feature.rb b/spec/support/markdown_feature.rb
index 2a868aed73b..c59df4e84d6 100644
--- a/spec/support/markdown_feature.rb
+++ b/spec/support/markdown_feature.rb
@@ -17,7 +17,7 @@ class MarkdownFeature
def group
unless @group
@group = create(:group)
- @group.add_user(user, Gitlab::Access::DEVELOPER)
+ @group.add_developer(user)
end
@group
diff --git a/spec/support/mentionable_shared_examples.rb b/spec/support/mentionable_shared_examples.rb
index f0717e61781..e3de0afb448 100644
--- a/spec/support/mentionable_shared_examples.rb
+++ b/spec/support/mentionable_shared_examples.rb
@@ -9,7 +9,7 @@ def common_mentionable_setup
let(:author) { subject.author }
let(:mentioned_issue) { create(:issue, project: project) }
- let(:mentioned_mr) { create(:merge_request, :simple, source_project: project) }
+ let!(:mentioned_mr) { create(:merge_request, :simple, source_project: project) }
let(:mentioned_commit) { project.commit }
let(:ext_proj) { create(:project, :public) }