summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorkaren Carias <karen@gitlab.com>2015-08-10 16:03:10 -0700
committerkaren Carias <karen@gitlab.com>2015-08-10 16:03:10 -0700
commit8344c7950838a4f83307a208865dad4b28ee3b96 (patch)
treeef601e40cea332ad952b73723d7da76cdf9719d6
parent082467e8e65f8f6f4dd3f0e11c43c5cc9d13316c (diff)
parent151d9fb35fd66a161cf0e1f95d7b0f0448ca8034 (diff)
downloadgitlab-ce-8344c7950838a4f83307a208865dad4b28ee3b96.tar.gz
fixed conflict and comment
-rw-r--r--CHANGELOG13
-rw-r--r--Gemfile.lock4
-rw-r--r--app/assets/images/msapplication-tile.pngbin6102 -> 5798 bytes
-rw-r--r--app/assets/javascripts/dropzone_input.js.coffee9
-rw-r--r--app/assets/stylesheets/generic/markdown_area.scss9
-rw-r--r--app/assets/stylesheets/pages/merge_requests.scss11
-rw-r--r--app/assets/stylesheets/pages/tree.scss6
-rw-r--r--app/services/notification_service.rb49
-rw-r--r--app/services/post_commit_service.rb67
-rw-r--r--app/views/abuse_reports/new.html.haml2
-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/layouts/_head.html.haml4
-rw-r--r--app/views/layouts/_user_styles.html.haml24
-rw-r--r--app/views/profiles/show.html.haml4
-rw-r--r--app/views/projects/merge_requests/show/_how_to_merge.html.haml55
-rw-r--r--app/views/projects/merge_requests/widget/_closed.html.haml5
-rw-r--r--app/views/projects/merge_requests/widget/_heading.html.haml10
-rw-r--r--app/views/projects/merge_requests/widget/_locked.html.haml5
-rw-r--r--app/views/projects/merge_requests/widget/_merged.html.haml24
-rw-r--r--app/views/projects/merge_requests/widget/_open.html.haml2
-rw-r--r--app/views/projects/merge_requests/widget/open/_accept.html.haml6
-rw-r--r--app/views/projects/merge_requests/widget/open/_archived.html.haml4
-rw-r--r--app/views/projects/merge_requests/widget/open/_check.html.haml4
-rw-r--r--app/views/projects/merge_requests/widget/open/_conflicts.html.haml17
-rw-r--r--app/views/projects/merge_requests/widget/open/_missing_branch.html.haml32
-rw-r--r--app/views/projects/merge_requests/widget/open/_not_allowed.html.haml6
-rw-r--r--app/views/projects/merge_requests/widget/open/_nothing.html.haml14
-rw-r--r--app/views/projects/merge_requests/widget/open/_reload.html.haml7
-rw-r--r--app/views/projects/merge_requests/widget/open/_wip.html.haml16
-rw-r--r--app/views/projects/tree/_tree_commit_column.html.haml5
-rw-r--r--app/views/shared/issuable/_form.html.haml4
-rw-r--r--app/workers/post_receive.rb2
-rw-r--r--config/initializers/1_settings.rb10
-rw-r--r--doc/update/patch_versions.md1
-rw-r--r--doc/workflow/notifications.md35
-rw-r--r--features/profile/profile.feature2
-rw-r--r--features/steps/profile/profile.rb4
-rw-r--r--lib/gitlab/markdown/commit_range_reference_filter.rb3
-rw-r--r--lib/gitlab/markdown/commit_reference_filter.rb3
-rw-r--r--lib/gitlab/markdown/issue_reference_filter.rb3
-rw-r--r--lib/gitlab/markdown/label_reference_filter.rb3
-rw-r--r--lib/gitlab/markdown/merge_request_reference_filter.rb3
-rw-r--r--lib/gitlab/markdown/reference_filter.rb16
-rw-r--r--lib/gitlab/markdown/snippet_reference_filter.rb3
-rw-r--r--lib/gitlab/markdown/user_reference_filter.rb6
-rw-r--r--spec/lib/gitlab/markdown/commit_range_reference_filter_spec.rb8
-rw-r--r--spec/lib/gitlab/markdown/commit_reference_filter_spec.rb8
-rw-r--r--spec/lib/gitlab/markdown/issue_reference_filter_spec.rb8
-rw-r--r--spec/lib/gitlab/markdown/label_reference_filter_spec.rb8
-rw-r--r--spec/lib/gitlab/markdown/merge_request_reference_filter_spec.rb8
-rw-r--r--spec/lib/gitlab/markdown/snippet_reference_filter_spec.rb8
-rw-r--r--spec/lib/gitlab/markdown/user_reference_filter_spec.rb16
-rw-r--r--spec/services/notification_service_spec.rb7
55 files changed, 423 insertions, 185 deletions
diff --git a/CHANGELOG b/CHANGELOG
index b7a173e8267..d228ef616d4 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -22,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.
@@ -31,16 +32,21 @@ v 7.14.0 (unreleased)
- 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 satellites
- Remove comments and email addresses when publicly exposing ssh keys (Zeger-Jan van de Weg)
+ - Improve MR merge widget text and UI consistency.
+ - Improve text in MR "How To Merge" modal.
+ - Cache all events
v 7.13.3
- Fix bug causing Bitbucket importer to crash when OAuth application had been removed.
@@ -69,9 +75,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)
-
-v 7.13.0 (unreleased)
- 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)
@@ -119,12 +122,12 @@ v 7.13.0 (unreleased)
- 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
diff --git a/Gemfile.lock b/Gemfile.lock
index e72b7fe4927..643c513161f 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -154,7 +154,7 @@ GEM
doorkeeper (2.1.3)
railties (>= 3.2)
dotenv (0.9.0)
- dropzonejs-rails (0.4.14)
+ dropzonejs-rails (0.7.1)
rails (> 3.1)
email_spec (1.6.0)
launchy (~> 2.1)
@@ -373,7 +373,7 @@ GEM
mini_portile (0.6.2)
minitest (5.3.5)
mousetrap-rails (1.4.6)
- multi_json (1.11.1)
+ multi_json (1.11.2)
multi_xml (0.5.5)
multipart-post (1.2.0)
mysql2 (0.3.16)
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/dropzone_input.js.coffee b/app/assets/javascripts/dropzone_input.js.coffee
index a4f511301c1..a0dcaa8c27a 100644
--- a/app/assets/javascripts/dropzone_input.js.coffee
+++ b/app/assets/javascripts/dropzone_input.js.coffee
@@ -8,6 +8,7 @@ class @DropzoneInput
divAlert = "<div class=\"" + alertClass + "\"></div>"
iconPaperclip = "<i class=\"fa fa-paperclip div-dropzone-icon\"></i>"
iconSpinner = "<i class=\"fa fa-spinner fa-spin div-dropzone-icon\"></i>"
+ uploadProgress = $("<div class=\"div-dropzone-progress\"></div>")
btnAlert = "<button type=\"button\"" + alertAttr + ">&times;</button>"
project_uploads_path = window.project_uploads_path or null
markdown_preview_path = window.markdown_preview_path or null
@@ -28,6 +29,7 @@ class @DropzoneInput
form_dropzone.find(".div-dropzone-hover").append iconPaperclip
form_dropzone.append divSpinner
form_dropzone.find(".div-dropzone-spinner").append iconSpinner
+ form_dropzone.find(".div-dropzone-spinner").append uploadProgress
form_dropzone.find(".div-dropzone-spinner").css
"opacity": 0
"display": "none"
@@ -112,13 +114,18 @@ class @DropzoneInput
$(".div-dropzone-alert").append btnAlert + errorMessage
return
+ totaluploadprogress: (totalUploadProgress) ->
+ uploadProgress.text Math.round(totalUploadProgress) + "%"
+ return
+
sending: ->
form_dropzone.find(".div-dropzone-spinner").css
"opacity": 0.7
"display": "inherit"
return
- complete: ->
+ queuecomplete: ->
+ uploadProgress.text ""
$(".dz-preview").remove()
$(".markdown-area").trigger "input"
$(".div-dropzone-spinner").css
diff --git a/app/assets/stylesheets/generic/markdown_area.scss b/app/assets/stylesheets/generic/markdown_area.scss
index f94677d1925..a4fc82e90bf 100644
--- a/app/assets/stylesheets/generic/markdown_area.scss
+++ b/app/assets/stylesheets/generic/markdown_area.scss
@@ -40,6 +40,15 @@
font-size: inherit;
}
+ .div-dropzone-progress {
+ position: absolute;
+ top: 7px;
+ left: -40px;
+ width: 35px;
+ font-size: 13px;
+ text-align: right;
+ }
+
.dz-preview {
display: none;
}
diff --git a/app/assets/stylesheets/pages/merge_requests.scss b/app/assets/stylesheets/pages/merge_requests.scss
index 9af8227a52f..30bbec7b795 100644
--- a/app/assets/stylesheets/pages/merge_requests.scss
+++ b/app/assets/stylesheets/pages/merge_requests.scss
@@ -91,8 +91,6 @@
@media(min-width: $screen-sm-max) {
.merge-request .merge-request-tabs{
- margin: 20px 0;
-
li {
a {
padding: 15px 40px;
@@ -102,6 +100,11 @@
}
}
+.merge-request .merge-request-tabs{
+ margin-top: 30px;
+ margin-bottom: 20px;
+}
+
.mr_source_commit,
.mr_target_commit {
.commit {
@@ -179,3 +182,7 @@
.merge-request-form .select2-container {
width: 250px !important;
}
+
+#modal_merge_info .modal-dialog {
+ width: 600px;
+}
diff --git a/app/assets/stylesheets/pages/tree.scss b/app/assets/stylesheets/pages/tree.scss
index 642bcd943aa..34ee4d7b31e 100644
--- a/app/assets/stylesheets/pages/tree.scss
+++ b/app/assets/stylesheets/pages/tree.scss
@@ -60,7 +60,11 @@
}
.tree_author {
- padding-left: 8px;
+ padding-right: 8px;
+
+ .commit-author-name {
+ color: gray;
+ }
}
.tree_commit {
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
index 7d7e5fbc32e..8592c8d238b 100644
--- a/app/services/post_commit_service.rb
+++ b/app/services/post_commit_service.rb
@@ -1,8 +1,71 @@
class PostCommitService < BaseService
+ include Gitlab::Popen
+
+ attr_reader :changes, :repo_path
+
def execute(sha, branch)
commit = repository.commit(sha)
- full_ref = 'refs/heads/' + branch
+ 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)
+ @changes = "#{old_sha} #{sha} #{full_ref}"
+ @repo_path = repository.path_to_repo
+
+ post_receive
+ end
+
+ private
+
+ def post_receive
+ hook = hook_file('post-receive', repo_path)
+ return true if hook.nil?
+ call_receive_hook(hook)
+ end
+
+ def call_receive_hook(hook)
+ # function will return true if succesful
+ exit_status = false
+
+ vars = {
+ 'GL_ID' => Gitlab::ShellEnv.gl_id(current_user),
+ 'PWD' => repo_path
+ }
+
+ options = {
+ chdir: repo_path
+ }
+
+ # we combine both stdout and stderr as we don't know what stream
+ # will be used by the custom hook
+ Open3.popen2e(vars, hook, options) do |stdin, stdout_stderr, wait_thr|
+ exit_status = true
+ stdin.sync = true
+
+ # in git, pre- and post- receive hooks may just exit without
+ # reading stdin. We catch the exception to avoid a broken pipe
+ # warning
+ begin
+ # inject all the changes as stdin to the hook
+ changes.lines do |line|
+ stdin.puts line
+ end
+ rescue Errno::EPIPE
+ end
+
+ # need to close stdin before reading stdout
+ stdin.close
+
+ # only output stdut_stderr if scripts doesn't return 0
+ unless wait_thr.value == 0
+ exit_status = false
+ end
+ end
+
+ exit_status
+ end
+
+ def hook_file(hook_type, repo_path)
+ hook_path = File.join(repo_path.strip, 'hooks')
+ hook_file = "#{hook_path}/#{hook_type}"
+ hook_file if File.exist?(hook_file)
end
end
diff --git a/app/views/abuse_reports/new.html.haml b/app/views/abuse_reports/new.html.haml
index a3b34345a3c..cffd7684008 100644
--- a/app/views/abuse_reports/new.html.haml
+++ b/app/views/abuse_reports/new.html.haml
@@ -1,6 +1,6 @@
- page_title "Report abuse"
%h3.page-title Report abuse
-%p Please use this form to report users who create spam issues or comments or who otherwise behave inappropriately.
+%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
diff --git a/app/views/events/_event.html.haml b/app/views/events/_event.html.haml
index 5ab5ffc238c..0faab4458e9 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/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/profiles/show.html.haml b/app/views/profiles/show.html.haml
index 37a3952635e..9fdeddfcc7a 100644
--- a/app/views/profiles/show.html.haml
+++ b/app/views/profiles/show.html.haml
@@ -82,12 +82,12 @@
You can change your avatar here
- if Gitlab.config.gravatar.enabled
%br
- or remove the current avatar to revert to #{link_to "gravatar.com", "http://gravatar.com"}
+ or remove the current avatar to revert to #{link_to Gitlab.config.gravatar.host, "http://" + Gitlab.config.gravatar.host}
- else
You can upload an avatar here
- if Gitlab.config.gravatar.enabled
%br
- or change it at #{link_to "gravatar.com", "http://gravatar.com"}
+ or change it at #{link_to Gitlab.config.gravatar.host, "http://" + Gitlab.config.gravatar.host}
%hr
%a.choose-btn.btn.btn-sm.js-choose-user-avatar-button
%i.fa.fa-paperclip
diff --git a/app/views/projects/merge_requests/show/_how_to_merge.html.haml b/app/views/projects/merge_requests/show/_how_to_merge.html.haml
index 22f601ac99e..db1575f899a 100644
--- a/app/views/projects/merge_requests/show/_how_to_merge.html.haml
+++ b/app/views/projects/merge_requests/show/_how_to_merge.html.haml
@@ -3,42 +3,45 @@
.modal-content
.modal-header
%a.close{href: "#", "data-dismiss" => "modal"} Ɨ
- %h3 How to merge
+ %h3 Check out, review and merge locally
.modal-body
- - if @merge_request.for_fork?
- - source_remote = @merge_request.source_project.namespace.nil? ? "source" :@merge_request.source_project.namespace.path
- - target_remote = @merge_request.target_project.namespace.nil? ? "target" :@merge_request.target_project.namespace.path
- %p
- %strong Step 1.
- Fetch the code and create a new branch pointing to it
- %pre.dark
+ %p
+ %strong Step 1.
+ Fetch and check out the branch for this merge request
+ %pre.dark
+ - if @merge_request.for_fork?
:preserve
git fetch #{@merge_request.source_project.http_url_to_repo} #{@merge_request.source_branch}
git checkout -b #{@merge_request.source_project_path}-#{@merge_request.source_branch} FETCH_HEAD
- %p
- %strong Step 2.
- Merge the branch and push the changes to GitLab
- %pre.dark
- :preserve
- git checkout #{@merge_request.target_branch}
- git merge --no-ff #{@merge_request.source_project_path}-#{@merge_request.source_branch}
- git push origin #{@merge_request.target_branch}
- - else
- %p
- %strong Step 1.
- Update the repo and checkout the branch we are going to merge
- %pre.dark
+ - else
:preserve
git fetch origin
git checkout -b #{@merge_request.source_branch} origin/#{@merge_request.source_branch}
- %p
- %strong Step 2.
- Merge the branch and push the changes to GitLab
- %pre.dark
+ %p
+ %strong Step 2.
+ Review the changes locally
+
+ %p
+ %strong Step 3.
+ Merge the branch and fix any conflicts that come up
+ %pre.dark
+ - if @merge_request.for_fork?
+ :preserve
+ git checkout #{@merge_request.target_branch}
+ git merge --no-ff #{@merge_request.source_project_path}-#{@merge_request.source_branch}
+ - else
:preserve
git checkout #{@merge_request.target_branch}
git merge --no-ff #{@merge_request.source_branch}
- git push origin #{@merge_request.target_branch}
+ %p
+ %strong Step 4.
+ Push the result of the merge to GitLab
+ %pre.dark
+ :preserve
+ git push origin #{@merge_request.target_branch}
+ - unless @merge_request.can_be_merged_by?(current_user)
+ %p
+ Note that pushing to GitLab requires write access to this repository.
:javascript
$(function(){
diff --git a/app/views/projects/merge_requests/widget/_closed.html.haml b/app/views/projects/merge_requests/widget/_closed.html.haml
index b5704c502c8..f3cc0e7e8a1 100644
--- a/app/views/projects/merge_requests/widget/_closed.html.haml
+++ b/app/views/projects/merge_requests/widget/_closed.html.haml
@@ -6,4 +6,7 @@
- if @merge_request.closed_event
by #{link_to_member(@project, @merge_request.closed_event.author, avatar: true)}
#{time_ago_with_tooltip(@merge_request.closed_event.created_at)}
- %p Changes were not merged into target branch
+ %p
+ = succeed '.' do
+ The changes were not merged into
+ %span.label-branch= @merge_request.target_branch
diff --git a/app/views/projects/merge_requests/widget/_heading.html.haml b/app/views/projects/merge_requests/widget/_heading.html.haml
index 17d529766e6..4d4e2f68f61 100644
--- a/app/views/projects/merge_requests/widget/_heading.html.haml
+++ b/app/views/projects/merge_requests/widget/_heading.html.haml
@@ -3,26 +3,26 @@
- [:success, :skipped, :canceled, :failed, :running, :pending].each do |status|
.ci_widget{class: "ci-#{status}", style: "display:none"}
- if status == :success
+ - status = "passed"
= 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"
+ = link_to "View build details", ci_build_details_path(@merge_request), :"data-no-turbolink" => "data-no-turbolink"
.ci_widget
= icon("spinner spin")
- Checking for CI status for #{@merge_request.last_commit_short_sha}
+ Checking CI status for #{@merge_request.last_commit_short_sha}&hellip;
.ci_widget.ci-not_found{style: "display:none"}
= icon("times-circle")
- %span Can not find commit in the CI server
- for #{@merge_request.last_commit_short_sha}.
+ Could not find CI status for #{@merge_request.last_commit_short_sha}.
.ci_widget.ci-error{style: "display:none"}
= icon("times-circle")
- %span Cannot connect to the CI server. Please check your settings and try again.
+ Could not connect to the CI server. Please check your settings and try again.
:coffeescript
$ ->
diff --git a/app/views/projects/merge_requests/widget/_locked.html.haml b/app/views/projects/merge_requests/widget/_locked.html.haml
index 13ec278847b..78d0783cba0 100644
--- a/app/views/projects/merge_requests/widget/_locked.html.haml
+++ b/app/views/projects/merge_requests/widget/_locked.html.haml
@@ -2,7 +2,8 @@
= render 'projects/merge_requests/widget/heading'
.mr-widget-body
%h4
- Merge in progress...
+ = icon("spinner spin")
+ Merge in progress&hellip;
%p
- Merging is in progress. While merging this request is locked and cannot be closed.
+ This merge request is in the process of being merged, during which time it is locked and cannot be closed.
diff --git a/app/views/projects/merge_requests/widget/_merged.html.haml b/app/views/projects/merge_requests/widget/_merged.html.haml
index a3b13140810..d22dfa085b8 100644
--- a/app/views/projects/merge_requests/widget/_merged.html.haml
+++ b/app/views/projects/merge_requests/widget/_merged.html.haml
@@ -7,23 +7,31 @@
by #{link_to_member(@project, @merge_request.merge_event.author, avatar: true)}
#{time_ago_with_tooltip(@merge_request.merge_event.created_at)}
%div
- - if @source_branch.blank?
- Source branch has been removed
+ - if !@merge_request.source_branch_exists?
+ = succeed '.' do
+ The changes were merged into
+ %span.label-branch= @merge_request.target_branch
+ The source branch has been removed.
- - elsif can_remove_branch?(@merge_request.source_project, @merge_request.source_branch) && @merge_request.merged?
+ - elsif can_remove_branch?(@merge_request.source_project, @merge_request.source_branch)
.remove_source_branch_widget
- %p Changes merged into #{@merge_request.target_branch}. You can remove source branch now
+ %p
+ = succeed '.' do
+ The changes were merged into
+ %span.label-branch= @merge_request.target_branch
+ You can remove the source branch now.
= link_to namespace_project_branch_path(@merge_request.source_project.namespace, @merge_request.source_project, @source_branch), remote: true, method: :delete, class: "btn btn-primary btn-sm remove_source_branch" do
%i.fa.fa-times
Remove Source Branch
.remove_source_branch_widget.failed.hide
- Failed to remove source branch '#{@merge_request.source_branch}'
+ %p
+ Failed to remove source branch '#{@merge_request.source_branch}'.
.remove_source_branch_in_progress.hide
- %i.fa.fa-spinner.fa-spin
- &nbsp;
- Removing source branch '#{@merge_request.source_branch}'. Please wait. Page will be automatically reloaded. &nbsp;
+ %p
+ = icon('spinner spin')
+ Removing source branch '#{@merge_request.source_branch}'. Please wait. This page will be automatically reload.
:coffeescript
$('.remove_source_branch').on 'click', ->
diff --git a/app/views/projects/merge_requests/widget/_open.html.haml b/app/views/projects/merge_requests/widget/_open.html.haml
index f420cdcab49..0aad9bb3e88 100644
--- a/app/views/projects/merge_requests/widget/_open.html.haml
+++ b/app/views/projects/merge_requests/widget/_open.html.haml
@@ -22,6 +22,6 @@
.mr-widget-footer
%span
%i.fa.fa-check
- Accepting this merge request will close #{@closes_issues.size == 1 ? 'issue' : 'issues'}
+ Accepting this merge request will close #{"issue".pluralize(@closes_issues.size)}
= succeed '.' do
!= gfm(issues_sentence(@closes_issues))
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 1be98cbe8de..e1525f6aeb7 100644
--- a/app/views/projects/merge_requests/widget/open/_accept.html.haml
+++ b/app/views/projects/merge_requests/widget/open/_accept.html.haml
@@ -8,10 +8,10 @@
.accept-control.checkbox
= label_tag :should_remove_source_branch, class: "remove_source_checkbox" do
= check_box_tag :should_remove_source_branch
- Remove source-branch
+ Remove source branch
.accept-control
- = link_to "#", class: "modify-merge-commit-link js-toggle-button", title: "Modify merge commit message" do
- %i.fa.fa-edit
+ = link_to "#", class: "modify-merge-commit-link js-toggle-button" do
+ = icon('edit')
Modify commit message
.js-toggle-content.hide.prepend-top-20
= render 'shared/commit_message_container', params: params,
diff --git a/app/views/projects/merge_requests/widget/open/_archived.html.haml b/app/views/projects/merge_requests/widget/open/_archived.html.haml
index eaf113ee568..ab30fa6b243 100644
--- a/app/views/projects/merge_requests/widget/open/_archived.html.haml
+++ b/app/views/projects/merge_requests/widget/open/_archived.html.haml
@@ -1,2 +1,4 @@
+%h4
+ Project is archived
%p
- %strong Archived projects do not provide commit access.
+ This merge request cannot be merged because archived projects cannot be written to.
diff --git a/app/views/projects/merge_requests/widget/open/_check.html.haml b/app/views/projects/merge_requests/widget/open/_check.html.haml
index e775447cb75..b6b8974297e 100644
--- a/app/views/projects/merge_requests/widget/open/_check.html.haml
+++ b/app/views/projects/merge_requests/widget/open/_check.html.haml
@@ -1,6 +1,6 @@
%strong
- %i.fa.fa-spinner.fa-spin
- Checking automatic merge…
+ = icon("spinner spin")
+ Checking ability to merge automatically&hellip;
:coffeescript
$ ->
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 440a7aa1c61..e6c089fefb2 100644
--- a/app/views/projects/merge_requests/widget/open/_conflicts.html.haml
+++ b/app/views/projects/merge_requests/widget/open/_conflicts.html.haml
@@ -1,11 +1,10 @@
%h4
- This merge request contains merge conflicts that must be resolved.
+ = icon("exclamation-triangle")
+ This merge request contains merge conflicts
-- if @merge_request.can_be_merged_by?(current_user)
- %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
- %p
- Only those with write access to this repository can merge merge requests.
+%p
+ Please resolve these conflicts or
+ - if @merge_request.can_be_merged_by?(current_user)
+ #{link_to "merge this request manually", "#modal_merge_info", class: "how_to_merge_link vlink", "data-toggle" => "modal"}.
+ - else
+ ask someone with write access to this repository to merge this request manually.
diff --git a/app/views/projects/merge_requests/widget/open/_missing_branch.html.haml b/app/views/projects/merge_requests/widget/open/_missing_branch.html.haml
index 1c565bae80a..c9f07629493 100644
--- a/app/views/projects/merge_requests/widget/open/_missing_branch.html.haml
+++ b/app/views/projects/merge_requests/widget/open/_missing_branch.html.haml
@@ -1,16 +1,16 @@
-%h4
- Can't be merged
-%p
- This merge request can not be accepted because branch
- - unless @merge_request.source_branch_exists?
- %span.label.label-inverse= @merge_request.source_branch
- does not exist in
- %span.label.label-info= @merge_request.source_project_path
- %br
- %strong Please close this merge request and open a new merge request to change source branches.
- - else
- %span.label.label-inverse= @merge_request.target_branch
- does not exist in
- %span.label.label-info= @merge_request.target_project_path
- %br
- %strong Please close this merge request or change to another target branch.
+- unless @merge_request.source_branch_exists?
+ %h4
+ = icon("exclamation-triangle")
+ Source branch
+ %span.label-branch= source_branch_with_namespace(@merge_request)
+ does not exist
+ %p
+ Please restore the source branch or close this merge request and open a new merge request with a different source branch.
+- else
+ %h4
+ = icon("exclamation-triangle")
+ Target branch
+ %span.label-branch= @merge_request.target_branch
+ does not exist
+ %p
+ Please restore the target branch or use a different target branch.
diff --git a/app/views/projects/merge_requests/widget/open/_not_allowed.html.haml b/app/views/projects/merge_requests/widget/open/_not_allowed.html.haml
index 82f6ffd8fcb..a8145558ca8 100644
--- a/app/views/projects/merge_requests/widget/open/_not_allowed.html.haml
+++ b/app/views/projects/merge_requests/widget/open/_not_allowed.html.haml
@@ -1,2 +1,4 @@
-%strong This request can be merged automatically.
-Only those with write access to this repository can merge merge requests.
+%h4
+ Ready to be merged automatically
+%p
+ Ask someone with write access to this repository to merge this request.
diff --git a/app/views/projects/merge_requests/widget/open/_nothing.html.haml b/app/views/projects/merge_requests/widget/open/_nothing.html.haml
index 4d526576bc2..35626b624b7 100644
--- a/app/views/projects/merge_requests/widget/open/_nothing.html.haml
+++ b/app/views/projects/merge_requests/widget/open/_nothing.html.haml
@@ -1,8 +1,8 @@
-%h4 Nothing to merge
-%p
+%h4
+ = icon("exclamation-triangle")
Nothing to merge from
- %span.label-branch #{@merge_request.source_branch}
- to
- %span.label-branch #{@merge_request.target_branch}
- %br
- Try to use different branches or push new code.
+ %span.label-branch= source_branch_with_namespace(@merge_request)
+ into
+ %span.label-branch= @merge_request.target_branch
+%p
+ Please push new commits to the source branch or use a different target branch.
diff --git a/app/views/projects/merge_requests/widget/open/_reload.html.haml b/app/views/projects/merge_requests/widget/open/_reload.html.haml
index 5787f6efea4..acfc31725eb 100644
--- a/app/views/projects/merge_requests/widget/open/_reload.html.haml
+++ b/app/views/projects/merge_requests/widget/open/_reload.html.haml
@@ -1 +1,6 @@
-This merge request cannot be merged. Try to reload the page.
+%h4
+ = icon("exclamation-triangle")
+ This merge request failed to be merged automatically
+
+%p
+ Please reload the page to find out the reason.
diff --git a/app/views/projects/merge_requests/widget/open/_wip.html.haml b/app/views/projects/merge_requests/widget/open/_wip.html.haml
index 4ce3ab31278..0cf16542cc1 100644
--- a/app/views/projects/merge_requests/widget/open/_wip.html.haml
+++ b/app/views/projects/merge_requests/widget/open/_wip.html.haml
@@ -1,13 +1,5 @@
-- if @merge_request.can_be_merged_by?(current_user)
- %h4
- This merge request cannot be accepted because it is marked as Work In Progress.
+%h4
+ This merge request is currently a Work In Progress
- %p
- %button.btn.disabled{:type => 'button'}
- %i.fa.fa-warning
- Accept Merge Request
- &nbsp;
- When the merge request is ready, remove the "WIP" prefix from the title to allow it to be accepted.
-- else
- %strong This merge request is marked as Work In Progress.
- Only those with write access to this repository can merge merge requests.
+%p
+ When this merge request is ready, remove the "WIP" prefix from the title to allow it to be merged.
diff --git a/app/views/projects/tree/_tree_commit_column.html.haml b/app/views/projects/tree/_tree_commit_column.html.haml
index 86a80703072..50521264a61 100644
--- a/app/views/projects/tree/_tree_commit_column.html.haml
+++ b/app/views/projects/tree/_tree_commit_column.html.haml
@@ -1,6 +1,3 @@
%span.str-truncated
+ %span.tree_author= commit_author_link(commit, avatar: true, size: 16)
= link_to_gfm commit.title, namespace_project_commit_path(@project.namespace, @project, commit.id), class: "tree-commit-link"
- %span.tree_author
- [
- commit_author_link(commit, avatar: false)
- ]
diff --git a/app/views/shared/issuable/_form.html.haml b/app/views/shared/issuable/_form.html.haml
index ac8c1936c9e..3489bf3f191 100644
--- a/app/views/shared/issuable/_form.html.haml
+++ b/app/views/shared/issuable/_form.html.haml
@@ -16,10 +16,10 @@
%p.help-block
- if issuable.work_in_progress?
Remove the <code>WIP</code> prefix from the title to allow this
- <strong>Work In Progress</strong> merge request to be accepted when it's ready.
+ <strong>Work In Progress</strong> merge request to be merged when it's ready.
- else
Start the title with <code>[WIP]</code> or <code>WIP:</code> to prevent a
- <strong>Work In Progress</strong> merge request from being accepted before it's ready.
+ <strong>Work In Progress</strong> merge request from being merged before it's ready.
.form-group.issuable-description
= f.label :description, 'Description', class: 'control-label'
.col-sm-10
diff --git a/app/workers/post_receive.rb b/app/workers/post_receive.rb
index 33d8cc8861b..994b8e8ed38 100644
--- a/app/workers/post_receive.rb
+++ b/app/workers/post_receive.rb
@@ -45,7 +45,7 @@ class PostReceive
def utf8_encode_changes(changes)
changes = changes.dup
-
+
changes.force_encoding("UTF-8")
return changes if changes.valid_encoding?
diff --git a/config/initializers/1_settings.rb b/config/initializers/1_settings.rb
index bd76c918485..026c1a5792c 100644
--- a/config/initializers/1_settings.rb
+++ b/config/initializers/1_settings.rb
@@ -8,6 +8,15 @@ class Settings < Settingslogic
def gitlab_on_standard_port?
gitlab.port.to_i == (gitlab.https ? 443 : 80)
end
+
+ # get host without www, thanks to http://stackoverflow.com/a/6674363/1233435
+ def get_host_without_www(url)
+ url = URI.encode(url)
+ uri = URI.parse(url)
+ uri = URI.parse("http://#{url}") if uri.scheme.nil?
+ host = uri.host.downcase
+ host.start_with?('www.') ? host[4..-1] : host
+ end
private
@@ -147,6 +156,7 @@ Settings['gravatar'] ||= Settingslogic.new({})
Settings.gravatar['enabled'] = true if Settings.gravatar['enabled'].nil?
Settings.gravatar['plain_url'] ||= 'http://www.gravatar.com/avatar/%{hash}?s=%{size}&d=identicon'
Settings.gravatar['ssl_url'] ||= 'https://secure.gravatar.com/avatar/%{hash}?s=%{size}&d=identicon'
+Settings.gravatar['host'] = Settings.get_host_without_www(Settings.gravatar['plain_url'])
#
# GitLab Shell
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/notifications.md b/doc/workflow/notifications.md
index a079a5ddf66..32b515ca238 100644
--- a/doc/workflow/notifications.md
+++ b/doc/workflow/notifications.md
@@ -52,11 +52,9 @@ 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 |
@@ -67,5 +65,36 @@ Below is the table of events users can be notified of:
| 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 |
-You won't receive notifications for Issues, Merge Requests or Milestones created by yourself. You will only receive automatic notifications when somebody else creates one and they mention you. Also, when somebody comments or adds changes to the ones that you've created.
+### 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 |
+
+You won't receive notifications for Issues, Merge Requests or Milestones
+created by yourself. You will only receive automatic notifications when
+somebody else comments or adds changes to the ones that you've created or
+mentions you.
diff --git a/features/profile/profile.feature b/features/profile/profile.feature
index 7a1345f2b37..27c0bde364e 100644
--- a/features/profile/profile.feature
+++ b/features/profile/profile.feature
@@ -35,6 +35,7 @@ Feature: Profile
Then I change my avatar
And I should see new avatar
And I should see the "Remove avatar" button
+ And I should see the gravatar host link
Scenario: I remove my avatar
Given I visit profile page
@@ -42,6 +43,7 @@ Feature: Profile
When I remove my avatar
Then I should see my gravatar
And I should not see the "Remove avatar" button
+ And I should see the gravatar host link
Scenario: My password is expired
Given my password is expired
diff --git a/features/steps/profile/profile.rb b/features/steps/profile/profile.rb
index 2b6b8b167f6..8cf24705a5e 100644
--- a/features/steps/profile/profile.rb
+++ b/features/steps/profile/profile.rb
@@ -59,6 +59,10 @@ class Spinach::Features::Profile < Spinach::FeatureSteps
step 'I should not see the "Remove avatar" button' do
expect(page).not_to have_link("Remove avatar")
end
+
+ step 'I should see the gravatar host link' do
+ expect(page).to have_link("gravatar.com")
+ end
step 'I try change my password w/o old one' do
page.within '.update-password' do
diff --git a/lib/gitlab/markdown/commit_range_reference_filter.rb b/lib/gitlab/markdown/commit_range_reference_filter.rb
index 61591a9914b..a9f1ee9c161 100644
--- a/lib/gitlab/markdown/commit_range_reference_filter.rb
+++ b/lib/gitlab/markdown/commit_range_reference_filter.rb
@@ -57,10 +57,11 @@ module Gitlab
title = range.reference_title
klass = reference_class(:commit_range)
+ data = data_attribute(project.id)
project_ref += '@' if project_ref
- %(<a href="#{url}"
+ %(<a href="#{url}" #{data}
title="#{title}"
class="#{klass}">#{project_ref}#{range}</a>)
else
diff --git a/lib/gitlab/markdown/commit_reference_filter.rb b/lib/gitlab/markdown/commit_reference_filter.rb
index f6932e76e70..eacdf8a6d37 100644
--- a/lib/gitlab/markdown/commit_reference_filter.rb
+++ b/lib/gitlab/markdown/commit_reference_filter.rb
@@ -47,10 +47,11 @@ module Gitlab
title = escape_once(commit.link_title)
klass = reference_class(:commit)
+ data = data_attribute(project.id)
project_ref += '@' if project_ref
- %(<a href="#{url}"
+ %(<a href="#{url}" #{data}
title="#{title}"
class="#{klass}">#{project_ref}#{commit.short_id}</a>)
else
diff --git a/lib/gitlab/markdown/issue_reference_filter.rb b/lib/gitlab/markdown/issue_reference_filter.rb
index dea04761ead..ab6f6bc1cf7 100644
--- a/lib/gitlab/markdown/issue_reference_filter.rb
+++ b/lib/gitlab/markdown/issue_reference_filter.rb
@@ -49,8 +49,9 @@ module Gitlab
title = escape_once("Issue: #{issue.title}")
klass = reference_class(:issue)
+ data = data_attribute(project.id)
- %(<a href="#{url}"
+ %(<a href="#{url}" #{data}
title="#{title}"
class="#{klass}">#{match}</a>)
else
diff --git a/lib/gitlab/markdown/label_reference_filter.rb b/lib/gitlab/markdown/label_reference_filter.rb
index e022ca69c91..2186f36f854 100644
--- a/lib/gitlab/markdown/label_reference_filter.rb
+++ b/lib/gitlab/markdown/label_reference_filter.rb
@@ -43,8 +43,9 @@ module Gitlab
url = url_for_label(project, label)
klass = reference_class(:label)
+ data = data_attribute(project.id)
- %(<a href="#{url}"
+ %(<a href="#{url}" #{data}
class="#{klass}">#{render_colored_label(label)}</a>)
else
match
diff --git a/lib/gitlab/markdown/merge_request_reference_filter.rb b/lib/gitlab/markdown/merge_request_reference_filter.rb
index 80779819485..884f60f9d53 100644
--- a/lib/gitlab/markdown/merge_request_reference_filter.rb
+++ b/lib/gitlab/markdown/merge_request_reference_filter.rb
@@ -47,10 +47,11 @@ module Gitlab
title = escape_once("Merge Request: #{merge_request.title}")
klass = reference_class(:merge_request)
+ data = data_attribute(project.id)
url = url_for_merge_request(merge_request, project)
- %(<a href="#{url}"
+ %(<a href="#{url}" #{data}
title="#{title}"
class="#{klass}">#{match}</a>)
else
diff --git a/lib/gitlab/markdown/reference_filter.rb b/lib/gitlab/markdown/reference_filter.rb
index a84bacd3d4f..47ee1d99da3 100644
--- a/lib/gitlab/markdown/reference_filter.rb
+++ b/lib/gitlab/markdown/reference_filter.rb
@@ -21,6 +21,22 @@ module Gitlab
result[:references] = Hash.new { |hash, type| hash[type] = [] }
end
+ # Returns a data attribute String to attach to a reference link
+ #
+ # id - Object ID
+ # type - Object type (default: :project)
+ #
+ # Examples:
+ #
+ # data_attribute(1) # => "data-project-id=\"1\""
+ # data_attribute(2, :user) # => "data-user-id=\"2\""
+ # data_attribute(3, :group) # => "data-group-id=\"3\""
+ #
+ # Returns a String
+ def data_attribute(id, type = :project)
+ %Q(data-#{type}-id="#{id}")
+ end
+
def escape_once(html)
ERB::Util.html_escape_once(html)
end
diff --git a/lib/gitlab/markdown/snippet_reference_filter.rb b/lib/gitlab/markdown/snippet_reference_filter.rb
index 174ba58af6c..92979a356dc 100644
--- a/lib/gitlab/markdown/snippet_reference_filter.rb
+++ b/lib/gitlab/markdown/snippet_reference_filter.rb
@@ -47,10 +47,11 @@ module Gitlab
title = escape_once("Snippet: #{snippet.title}")
klass = reference_class(:snippet)
+ data = data_attribute(project.id)
url = url_for_snippet(snippet, project)
- %(<a href="#{url}"
+ %(<a href="#{url}" #{data}
title="#{title}"
class="#{klass}">#{match}</a>)
else
diff --git a/lib/gitlab/markdown/user_reference_filter.rb b/lib/gitlab/markdown/user_reference_filter.rb
index c9972957182..a4aec7a05d1 100644
--- a/lib/gitlab/markdown/user_reference_filter.rb
+++ b/lib/gitlab/markdown/user_reference_filter.rb
@@ -83,18 +83,20 @@ module Gitlab
push_result(:user, *namespace.users)
url = urls.group_url(group, only_path: context[:only_path])
+ data = data_attribute(namespace.id, :group)
text = Group.reference_prefix + group
- %(<a href="#{url}" class="#{link_class}">#{text}</a>)
+ %(<a href="#{url}" #{data} class="#{link_class}">#{text}</a>)
end
def link_to_user(user, namespace)
push_result(:user, namespace.owner)
url = urls.user_url(user, only_path: context[:only_path])
+ data = data_attribute(namespace.owner_id, :user)
text = User.reference_prefix + user
- %(<a href="#{url}" class="#{link_class}">#{text}</a>)
+ %(<a href="#{url}" #{data} class="#{link_class}">#{text}</a>)
end
def user_can_reference_group?(group)
diff --git a/spec/lib/gitlab/markdown/commit_range_reference_filter_spec.rb b/spec/lib/gitlab/markdown/commit_range_reference_filter_spec.rb
index e8391cc7aca..58155284486 100644
--- a/spec/lib/gitlab/markdown/commit_range_reference_filter_spec.rb
+++ b/spec/lib/gitlab/markdown/commit_range_reference_filter_spec.rb
@@ -80,6 +80,14 @@ module Gitlab::Markdown
expect(doc.css('a').first.attr('class')).to include 'custom'
end
+ it 'includes a data-project-id attribute' do
+ doc = filter("See #{reference}")
+ link = doc.css('a').first
+
+ expect(link).to have_attribute('data-project-id')
+ expect(link.attr('data-project-id')).to eq project.id.to_s
+ end
+
it 'supports an :only_path option' do
doc = filter("See #{reference}", only_path: true)
link = doc.css('a').first.attr('href')
diff --git a/spec/lib/gitlab/markdown/commit_reference_filter_spec.rb b/spec/lib/gitlab/markdown/commit_reference_filter_spec.rb
index a10d43c9a02..05a02de4669 100644
--- a/spec/lib/gitlab/markdown/commit_reference_filter_spec.rb
+++ b/spec/lib/gitlab/markdown/commit_reference_filter_spec.rb
@@ -76,6 +76,14 @@ module Gitlab::Markdown
expect(doc.css('a').first.attr('class')).to include 'custom'
end
+ it 'includes a data-project-id attribute' do
+ doc = filter("See #{reference}")
+ link = doc.css('a').first
+
+ expect(link).to have_attribute('data-project-id')
+ expect(link.attr('data-project-id')).to eq project.id.to_s
+ end
+
it 'supports an :only_path context' do
doc = filter("See #{reference}", only_path: true)
link = doc.css('a').first.attr('href')
diff --git a/spec/lib/gitlab/markdown/issue_reference_filter_spec.rb b/spec/lib/gitlab/markdown/issue_reference_filter_spec.rb
index fa43d33794d..35b1ba5f132 100644
--- a/spec/lib/gitlab/markdown/issue_reference_filter_spec.rb
+++ b/spec/lib/gitlab/markdown/issue_reference_filter_spec.rb
@@ -73,6 +73,14 @@ module Gitlab::Markdown
expect(doc.css('a').first.attr('class')).to include 'custom'
end
+ it 'includes a data-project-id attribute' do
+ doc = filter("Issue #{reference}")
+ link = doc.css('a').first
+
+ expect(link).to have_attribute('data-project-id')
+ expect(link.attr('data-project-id')).to eq project.id.to_s
+ end
+
it 'supports an :only_path context' do
doc = filter("Issue #{reference}", only_path: true)
link = doc.css('a').first.attr('href')
diff --git a/spec/lib/gitlab/markdown/label_reference_filter_spec.rb b/spec/lib/gitlab/markdown/label_reference_filter_spec.rb
index e9f8ed277a5..fabe0411e46 100644
--- a/spec/lib/gitlab/markdown/label_reference_filter_spec.rb
+++ b/spec/lib/gitlab/markdown/label_reference_filter_spec.rb
@@ -30,6 +30,14 @@ module Gitlab::Markdown
expect(doc.css('a').first.attr('class')).to include 'custom'
end
+ it 'includes a data-project-id attribute' do
+ doc = filter("Label #{reference}")
+ link = doc.css('a').first
+
+ expect(link).to have_attribute('data-project-id')
+ expect(link.attr('data-project-id')).to eq project.id.to_s
+ end
+
it 'supports an :only_path context' do
doc = filter("Label #{reference}", only_path: true)
link = doc.css('a').first.attr('href')
diff --git a/spec/lib/gitlab/markdown/merge_request_reference_filter_spec.rb b/spec/lib/gitlab/markdown/merge_request_reference_filter_spec.rb
index 5945302a2da..5cef52b1916 100644
--- a/spec/lib/gitlab/markdown/merge_request_reference_filter_spec.rb
+++ b/spec/lib/gitlab/markdown/merge_request_reference_filter_spec.rb
@@ -61,6 +61,14 @@ module Gitlab::Markdown
expect(doc.css('a').first.attr('class')).to include 'custom'
end
+ it 'includes a data-project-id attribute' do
+ doc = filter("Merge #{reference}")
+ link = doc.css('a').first
+
+ expect(link).to have_attribute('data-project-id')
+ expect(link.attr('data-project-id')).to eq project.id.to_s
+ end
+
it 'supports an :only_path context' do
doc = filter("Merge #{reference}", only_path: true)
link = doc.css('a').first.attr('href')
diff --git a/spec/lib/gitlab/markdown/snippet_reference_filter_spec.rb b/spec/lib/gitlab/markdown/snippet_reference_filter_spec.rb
index 38619a3c07f..678b171e99e 100644
--- a/spec/lib/gitlab/markdown/snippet_reference_filter_spec.rb
+++ b/spec/lib/gitlab/markdown/snippet_reference_filter_spec.rb
@@ -60,6 +60,14 @@ module Gitlab::Markdown
expect(doc.css('a').first.attr('class')).to include 'custom'
end
+ it 'includes a data-project-id attribute' do
+ doc = filter("Snippet #{reference}")
+ link = doc.css('a').first
+
+ expect(link).to have_attribute('data-project-id')
+ expect(link.attr('data-project-id')).to eq project.id.to_s
+ end
+
it 'supports an :only_path context' do
doc = filter("Snippet #{reference}", only_path: true)
link = doc.css('a').first.attr('href')
diff --git a/spec/lib/gitlab/markdown/user_reference_filter_spec.rb b/spec/lib/gitlab/markdown/user_reference_filter_spec.rb
index 9c55b4ff38f..a5405e14a73 100644
--- a/spec/lib/gitlab/markdown/user_reference_filter_spec.rb
+++ b/spec/lib/gitlab/markdown/user_reference_filter_spec.rb
@@ -64,6 +64,14 @@ module Gitlab::Markdown
expect(doc.css('a').length).to eq 1
end
+ it 'includes a data-user-id attribute' do
+ doc = filter("Hey #{reference}")
+ link = doc.css('a').first
+
+ expect(link).to have_attribute('data-user-id')
+ expect(link.attr('data-user-id')).to eq user.namespace.owner_id.to_s
+ end
+
it 'adds to the results hash' do
result = pipeline_result("Hey #{reference}")
expect(result[:references][:user]).to eq [user]
@@ -85,6 +93,14 @@ module Gitlab::Markdown
expect(doc.css('a').first.attr('href')).to eq urls.group_url(group)
end
+ it 'includes a data-group-id attribute' do
+ doc = filter("Hey #{reference}", current_user: user)
+ link = doc.css('a').first
+
+ expect(link).to have_attribute('data-group-id')
+ expect(link.attr('data-group-id')).to eq group.id.to_s
+ end
+
it 'adds to the results hash' do
result = pipeline_result("Hey #{reference}", current_user: user)
expect(result[:references][:user]).to eq group.users
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)