diff options
author | Douwe Maan <douwe@selenight.nl> | 2017-07-04 10:05:27 -0500 |
---|---|---|
committer | Douwe Maan <douwe@selenight.nl> | 2017-07-04 10:06:10 -0500 |
commit | 782e3e89985582471c41fdd7735bb3483e40f133 (patch) | |
tree | 7df3c889db7c362c033946a4ebc637aceb0032b3 | |
parent | 61b4000b0381f247a10391f1aafb30da7626f33e (diff) | |
download | gitlab-ce-dm-commit-diff-discussions-in-mr-context.tar.gz |
23 files changed, 166 insertions, 103 deletions
diff --git a/app/assets/javascripts/diff_notes/diff_notes_bundle.js b/app/assets/javascripts/diff_notes/diff_notes_bundle.js index a2d33b0936e..3170b96abff 100644 --- a/app/assets/javascripts/diff_notes/diff_notes_bundle.js +++ b/app/assets/javascripts/diff_notes/diff_notes_bundle.js @@ -16,7 +16,8 @@ import './components/diff_note_avatars'; import './components/new_issue_for_discussion'; $(() => { - const projectPath = document.querySelector('.merge-request').dataset.projectPath; + const projectPathHolder = document.querySelector('.merge-request') || document.querySelector('.commit-box') + const projectPath = projectPathHolder.dataset.projectPath; const COMPONENT_SELECTOR = 'resolve-btn, resolve-discussion-btn, jump-to-discussion, comment-and-resolve-btn, new-issue-for-discussion-btn'; window.gl = window.gl || {}; diff --git a/app/assets/javascripts/diff_notes/services/resolve.js b/app/assets/javascripts/diff_notes/services/resolve.js index 807ab11d292..9812db66142 100644 --- a/app/assets/javascripts/diff_notes/services/resolve.js +++ b/app/assets/javascripts/diff_notes/services/resolve.js @@ -45,7 +45,7 @@ class ResolveServiceClass { discussion.resolveAllNotes(resolved_by); } - gl.mrWidget.checkStatus(); + if (gl.mrWidget) gl.mrWidget.checkStatus(); discussion.updateHeadline(data); } else { throw new Error('An error occurred when trying to resolve discussion.'); diff --git a/app/controllers/projects/commit_controller.rb b/app/controllers/projects/commit_controller.rb index 7c3cce1c241..073481b756d 100644 --- a/app/controllers/projects/commit_controller.rb +++ b/app/controllers/projects/commit_controller.rb @@ -121,6 +121,23 @@ class Projects::CommitController < Projects::ApplicationController @grouped_diff_discussions = commit.grouped_diff_discussions @discussions = commit.discussions + if merge_request_iid = params[:merge_request_iid] + @merge_request = MergeRequestsFinder.new(current_user, project_id: @project.id).find_by(iid: merge_request_iid) + + if @merge_request + @new_diff_note_attrs.merge!( + noteable_type: 'MergeRequest', + noteable_id: @merge_request.id + ) + + merge_request_commit_notes = @merge_request.notes.where(commit_id: @commit.id).inc_relations_for_view + merge_request_commit_diff_discussions = merge_request_commit_notes.grouped_diff_discussions(@commit.diff_refs) + @grouped_diff_discussions.merge!(merge_request_commit_diff_discussions) do |line_code, left, right| + left + right + end + end + end + @notes = (@grouped_diff_discussions.values.flatten + @discussions).flat_map(&:notes) @notes = prepare_notes_for_rendering(@notes) end diff --git a/app/controllers/projects/merge_requests/diffs_controller.rb b/app/controllers/projects/merge_requests/diffs_controller.rb index 33b57b74847..77c59954f3b 100644 --- a/app/controllers/projects/merge_requests/diffs_controller.rb +++ b/app/controllers/projects/merge_requests/diffs_controller.rb @@ -20,33 +20,33 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic private def define_diff_vars - if params[:commit_sha].present? - handle_commit_sha_case + @merge_request_diffs = @merge_request.merge_request_diffs.viewable.select_without_diff + + if commit_id = params[:commit_id].presence + @commit = @merge_request.target_project.commit(commit_id) + @compare = @commit else - handle_diff_case + @compare = find_merge_request_diff_compare end - @diffs = @compare.diffs(diff_options) - end - def handle_commit_sha_case - project = @merge_request.target_project - @compare = project.commit(params[:commit_sha]) - @compare ||= @merge_request.merge_request_diff - end + return render_404 unless @compare - def handle_diff_case - @merge_request_diffs = @merge_request.merge_request_diffs.viewable.select_without_diff + @diffs = @compare.diffs(diff_options) + end - if diff_id = params[:diff_id] - @merge_request_diff = @merge_request.merge_request_diffs.viewable.find_by(id: diff_id) - end + def find_merge_request_diff_compare + @merge_request_diff = + if diff_id = params[:diff_id].presence + @merge_request.merge_request_diffs.viewable.find_by(id: diff_id) + else + @merge_request.merge_request_diff + end - @merge_request_diff ||= @merge_request.merge_request_diff + return unless @merge_request_diff @comparable_diffs = @merge_request_diffs.select { |diff| diff.id < @merge_request_diff.id } - if params[:start_sha].present? - @start_sha = params[:start_sha] + if @start_sha = params[:start_sha].presence @start_version = @comparable_diffs.find { |diff| diff.head_commit_sha == @start_sha } unless @start_version @@ -55,24 +55,20 @@ class Projects::MergeRequests::DiffsController < Projects::MergeRequests::Applic end end - @compare = - if @start_sha - @merge_request_diff.compare_with(@start_sha) - else - @merge_request_diff - end + if @start_sha + @merge_request_diff.compare_with(@start_sha) + else + @merge_request_diff + end end def define_diff_comment_vars @new_diff_note_attrs = { noteable_type: 'MergeRequest', - noteable_id: @merge_request.id + noteable_id: @merge_request.id, + commit_id: @commit&.id } - if @compare.is_a?(Commit) - @new_diff_note_attrs[:commit_id] = @compare.id - end - @diff_notes_disabled = false @use_legacy_diff_notes = !@merge_request.has_complete_diff_refs? diff --git a/app/helpers/commits_helper.rb b/app/helpers/commits_helper.rb index 0accd1f8d77..de25a42b340 100644 --- a/app/helpers/commits_helper.rb +++ b/app/helpers/commits_helper.rb @@ -213,4 +213,12 @@ module CommitsHelper [commits, 0] end end + + def commit_path(project, commit, merge_request: nil) + if merge_request&.persisted? + diffs_namespace_project_merge_request_path(project.namespace, project, merge_request, commit_id: commit.id) + else + namespace_project_commit_path(project.namespace, project, commit.id) + end + end end diff --git a/app/models/concerns/discussion_on_diff.rb b/app/models/concerns/discussion_on_diff.rb index f29ca22fef4..e3554116bf3 100644 --- a/app/models/concerns/discussion_on_diff.rb +++ b/app/models/concerns/discussion_on_diff.rb @@ -29,7 +29,7 @@ module DiscussionOnDiff end def on_merge_request_commit? - !commit_id.blank? + for_merge_request? && commit_id.present? end # Returns an array of at most 16 highlighted lines above a diff note diff --git a/app/models/diff_discussion.rb b/app/models/diff_discussion.rb index 07c4846e2ac..289406cb526 100644 --- a/app/models/diff_discussion.rb +++ b/app/models/diff_discussion.rb @@ -22,7 +22,11 @@ class DiffDiscussion < Discussion return unless for_merge_request? return {} if active? - noteable.version_params_for(position.diff_refs) + if on_merge_request_commit? + { commit_id: commit_id } + else + noteable.version_params_for(position.diff_refs) + end end def reply_attributes diff --git a/app/models/diff_note.rb b/app/models/diff_note.rb index 20ef1378500..485af258e5f 100644 --- a/app/models/diff_note.rb +++ b/app/models/diff_note.rb @@ -17,6 +17,7 @@ class DiffNote < Note validates :noteable_type, inclusion: { in: NOTEABLE_TYPES } validate :positions_complete validate :verify_supported + validate :diff_refs_match_commit, if: :for_commit? before_validation :set_original_position, :update_position, on: :create before_validation :set_line_code @@ -124,6 +125,12 @@ class DiffNote < Note errors.add(:position, "is invalid") end + def diff_refs_match_commit + return if self.original_position.diff_refs == self.commit.diff_refs + + errors.add(:commit_id, 'does not match the diff refs') + end + def keep_around_commits project.repository.keep_around(self.original_position.base_sha) project.repository.keep_around(self.original_position.start_sha) diff --git a/app/models/discussion.rb b/app/models/discussion.rb index d1cec7613af..3da5cb4f023 100644 --- a/app/models/discussion.rb +++ b/app/models/discussion.rb @@ -11,6 +11,7 @@ class Discussion :author, :noteable, + :commit_id, :for_commit?, :for_merge_request?, diff --git a/app/models/note.rb b/app/models/note.rb index ca6999427c0..7ae0b415c5d 100644 --- a/app/models/note.rb +++ b/app/models/note.rb @@ -187,10 +187,14 @@ class Note < ActiveRecord::Base for_personal_snippet? end + def commit + project.commit(commit_id) if commit_id.present? + end + # override to return commits, which are not active record def noteable if for_commit? - project.commit(commit_id) + commit else super end diff --git a/app/services/system_note_service.rb b/app/services/system_note_service.rb index 0837c07e6aa..9903f521fe2 100644 --- a/app/services/system_note_service.rb +++ b/app/services/system_note_service.rb @@ -23,7 +23,7 @@ module SystemNoteService body = "added #{commits_text}\n\n" body << existing_commit_summary(noteable, existing_commits, oldrev) - body << new_commit_summary(new_commits).join("\n") + body << new_commit_summary(noteable, new_commits).join("\n") body << "\n\n[Compare with previous version](#{diff_comparison_url(noteable, project, oldrev)})" create_note(NoteSummary.new(noteable, project, author, body, action: 'commit', commit_count: total_count)) @@ -504,9 +504,9 @@ module SystemNoteService # new_commits - Array of new Commit objects # # Returns an Array of Strings - def new_commit_summary(new_commits) + def new_commit_summary(merge_request, new_commits) new_commits.collect do |commit| - "* #{commit.short_id} - #{escape_html(commit.title)}" + "* [#{commit.short_id}](#{merge_request_commit_url(merge_request, commit)}) - #{escape_html(commit.title)}" end end @@ -638,4 +638,13 @@ module SystemNoteService start_sha: oldrev ) end + + def merge_request_commit_url(merge_request, commit) + url_helpers.diffs_namespace_project_merge_request_url( + project.namespace, + project, + merge_request.iid, + commit_id: commit.id + ) + end end diff --git a/app/views/discussions/_discussion.html.haml b/app/views/discussions/_discussion.html.haml index 7b10ddc62ff..8906eab3cf9 100644 --- a/app/views/discussions/_discussion.html.haml +++ b/app/views/discussions/_discussion.html.haml @@ -31,15 +31,14 @@ a deleted commit - elsif discussion.diff_discussion? on - - if discussion.on_merge_request_commit? - - if discussion.active? - the commit - - else - an outdated change in commit + = conditional_link_to url.present?, url do + - if discussion.on_merge_request_commit? + - unless discussion.active? + an outdated change in + commit - = link_to discussion.commit_id, url, class: 'monospace' - - else - = conditional_link_to url.present?, url do + %span.commit-sha= Commit.truncate_sha(discussion.commit_id) + - else - unless discussion.active? an old version of the diff diff --git a/app/views/projects/commit/_commit_box.html.haml b/app/views/projects/commit/_commit_box.html.haml index 7fe44816bae..2b870489c4f 100644 --- a/app/views/projects/commit/_commit_box.html.haml +++ b/app/views/projects/commit/_commit_box.html.haml @@ -46,7 +46,7 @@ %li= link_to s_("DownloadCommit|Email Patches"), namespace_project_commit_path(@project.namespace, @project, @commit, format: :patch) %li= link_to s_("DownloadCommit|Plain Diff"), namespace_project_commit_path(@project.namespace, @project, @commit, format: :diff) -.commit-box +.commit-box{ data: { project_path: project_path(@project) } } %h3.commit-title = markdown(@commit.title, pipeline: :single_line, author: @commit.author) - if @commit.description.present? @@ -79,5 +79,15 @@ in = time_interval_in_words last_pipeline.duration + - if @merge_request + .well-segment + = icon('info-circle fw') + + This commit is part of merge request + = succeed '.' do + = link_to @merge_request.to_reference, namespace_project_merge_request_path(@project.namespace, @project, @merge_request) + + Comments created here will be created in the context of that merge request. + :javascript $(".commit-info.branches").load("#{branches_namespace_project_commit_path(@project.namespace, @project, @commit.id)}"); diff --git a/app/views/projects/commit/show.html.haml b/app/views/projects/commit/show.html.haml index b778e8af121..3764b28fe44 100644 --- a/app/views/projects/commit/show.html.haml +++ b/app/views/projects/commit/show.html.haml @@ -3,6 +3,10 @@ - limited_container_width = fluid_layout ? '' : 'limit-container-width' - page_title "#{@commit.title} (#{@commit.short_id})", "Commits" - page_description @commit.description +- content_for :page_specific_javascripts do + = page_specific_javascript_bundle_tag('common_vue') + = page_specific_javascript_bundle_tag('diff_notes') + = render "projects/commits/head" .container-fluid{ class: [limited_container_width, container_class] } diff --git a/app/views/projects/commits/_commit.html.haml b/app/views/projects/commits/_commit.html.haml index 91dc4f6838b..e7fd5adbac4 100644 --- a/app/views/projects/commits/_commit.html.haml +++ b/app/views/projects/commits/_commit.html.haml @@ -1,10 +1,9 @@ -- ref = local_assigns.fetch(:ref) -- merge_request = local_assigns.fetch(:merge_request) -:ruby - link = (merge_request && !merge_request.new_record?) ? - diffs_namespace_project_merge_request_path(project.namespace, project, merge_request, commit_sha: commit.id) : - namespace_project_commit_path(project.namespace, project, commit.id) +- view_details = local_assigns.fetch(:view_details, false) +- merge_request = local_assigns.fetch(:merge_request, nil) +- project = local_assigns.fetch(:project) { merge_request&.project } +- ref = local_assigns.fetch(:ref) { merge_request&.source_branch } +- link = commit_path(project, commit, merge_request: merge_request) - if @note_counts - note_count = @note_counts.fetch(commit.id, 0) @@ -12,7 +11,7 @@ - notes = commit.notes - note_count = notes.user.count -- cache_key = [project.path_with_namespace, commit.id, current_application_settings, note_count, @path.presence, current_controller?(:commits)] +- cache_key = [project.path_with_namespace, commit.id, current_application_settings, note_count, @path.presence, current_controller?(:commits), merge_request] - cache_key.push(commit.status(ref)) if commit.status(ref) = cache(cache_key, expires_in: 1.day) do @@ -42,10 +41,12 @@ - commit_text = _('%{commit_author_link} committed %{commit_timeago}') % { commit_author_link: commit_author_link, commit_timeago: commit_timeago } #{ commit_text.html_safe } - .commit-actions.flex-row.hidden-xs - if commit.status(ref) = render_commit_status(commit, ref: ref) = link_to commit.short_id, link, class: "commit-sha btn btn-transparent" = clipboard_button(text: commit.id, title: _("Copy commit SHA to clipboard")) = link_to_browse_code(project, commit) + + - if view_details && merge_request + = link_to "View details", namespace_project_commit_path(project.namespace, project, commit.id, merge_request_iid: merge_request.iid), class: "btn btn-default" diff --git a/app/views/projects/commits/_commits.html.haml b/app/views/projects/commits/_commits.html.haml index 4b774b8a5f7..14d2802cb24 100644 --- a/app/views/projects/commits/_commits.html.haml +++ b/app/views/projects/commits/_commits.html.haml @@ -1,9 +1,6 @@ -- ref = local_assigns.fetch(:ref) -- merge_request = local_assigns.fetch(:merge_request) -- if merge_request - - ref = merge_request.source_branch - - project = merge_request.project - +- merge_request = local_assigns.fetch(:merge_request, nil) +- project = local_assigns.fetch(:project) { merge_request&.project } +- ref = local_assigns.fetch(:ref) { merge_request&.source_branch } - commits, hidden = limited_commits(@commits) diff --git a/app/views/projects/merge_requests/diffs/_commit_widget.html.haml b/app/views/projects/merge_requests/diffs/_commit_widget.html.haml new file mode 100644 index 00000000000..2e5594f8cbe --- /dev/null +++ b/app/views/projects/merge_requests/diffs/_commit_widget.html.haml @@ -0,0 +1,5 @@ +- if @commit + .info-well.hidden-xs.prepend-top-default + .well-segment + %ul.blob-commit-info + = render 'projects/commits/commit', commit: @commit, merge_request: @merge_request, view_details: true diff --git a/app/views/projects/merge_requests/diffs/_different_base.html.haml b/app/views/projects/merge_requests/diffs/_different_base.html.haml new file mode 100644 index 00000000000..aeeaa053c5f --- /dev/null +++ b/app/views/projects/merge_requests/diffs/_different_base.html.haml @@ -0,0 +1,11 @@ +- if @merge_request_diff && different_base?(@start_version, @merge_request_diff) + .mr-version-controls + .content-block + = icon('info-circle') + Selected versions have different base commits. + Changes will include + = link_to namespace_project_compare_path(@project.namespace, @project, from: @start_version.base_commit_sha, to: @merge_request_diff.base_commit_sha) do + new commits + from + = succeed '.' do + %code= @merge_request.target_branch diff --git a/app/views/projects/merge_requests/diffs/_diffs.html.haml b/app/views/projects/merge_requests/diffs/_diffs.html.haml index 06cc7f41b8a..dbbc61f9ddc 100644 --- a/app/views/projects/merge_requests/diffs/_diffs.html.haml +++ b/app/views/projects/merge_requests/diffs/_diffs.html.haml @@ -1,9 +1,12 @@ -- if @merge_request_diff - - if @merge_request_diff.collected? || @merge_request_diff.overflow? - = render 'projects/merge_requests/diffs/versions' - = render "projects/diffs/diffs", diffs: @diffs, environment: @environment - - elsif @merge_request_diff.empty? - .nothing-here-block Nothing to merge from #{@merge_request.source_branch} into #{@merge_request.target_branch} += render 'projects/merge_requests/diffs/version_controls' += render 'projects/merge_requests/diffs/different_base' += render 'projects/merge_requests/diffs/not_all_comments_displayed' += render 'projects/merge_requests/diffs/commit_widget' + +- if @merge_request_diff&.empty? + .nothing-here-block + No changes between #{@merge_request.source_branch} into #{@merge_request.target_branch}. - else - = render "projects/merge_requests/diffs/partial_comments_notice", commit: @compare, merge_request: @merge_request - = render "projects/diffs/diffs", diffs: @diffs, environment: @environment + - diff_viewable = @merge_request_diff ? @merge_request_diff.collected? || @merge_request_diff.overflow? : true + - if diff_viewable + = render "projects/diffs/diffs", diffs: @diffs, environment: @environment diff --git a/app/views/projects/merge_requests/diffs/_not_all_comments_displayed.html.haml b/app/views/projects/merge_requests/diffs/_not_all_comments_displayed.html.haml new file mode 100644 index 00000000000..26988d34917 --- /dev/null +++ b/app/views/projects/merge_requests/diffs/_not_all_comments_displayed.html.haml @@ -0,0 +1,19 @@ +- if @commit || @start_version || (@merge_request_diff && !@merge_request_diff.latest?) + .mr-version-controls + .content-block.comments-disabled-notif + = icon('info-circle') + Not all comments are displayed because you're + = succeed '.' do + - if @commit + viewing only the changes in commit + + = link_to @commit.short_id, diffs_namespace_project_merge_request_path(@project.namespace, @project, @merge_request, commit_id: @commit.id), class: "commit-sha" + - elsif @start_version + comparing two versions of the diff + - else + viewing an old version of the diff + + .pull-right + = link_to diffs_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), class: 'btn btn-sm' do + Show latest version + = "of the diff" if @commit diff --git a/app/views/projects/merge_requests/diffs/_partial_comments_notice.html.haml b/app/views/projects/merge_requests/diffs/_partial_comments_notice.html.haml deleted file mode 100644 index 568abe07d6f..00000000000 --- a/app/views/projects/merge_requests/diffs/_partial_comments_notice.html.haml +++ /dev/null @@ -1,9 +0,0 @@ -- project = merge_request.target_project -.mr-version-controls - .mr-version-menus-container.content-block - .comments-disabled-notif - = icon('info-circle') - Not all comments are displayed because you're viewing only the changes in commit - = succeed '.' do - = link_to commit.short_id, diffs_namespace_project_merge_request_path(project.namespace, project, merge_request, commit_sha: commit.id), class: "commit-sha btn btn-transparent" - = clipboard_button(text: commit.id, title: "Copy commit SHA to clipboard") diff --git a/app/views/projects/merge_requests/diffs/_versions.html.haml b/app/views/projects/merge_requests/diffs/_version_controls.html.haml index 0999b95c9c9..1c26f0405d2 100644 --- a/app/views/projects/merge_requests/diffs/_versions.html.haml +++ b/app/views/projects/merge_requests/diffs/_version_controls.html.haml @@ -1,4 +1,4 @@ -- if @merge_request_diffs.size > 1 +- if @merge_request_diff && @merge_request_diffs.size > 1 .mr-version-controls .mr-version-menus-container.content-block Changes between @@ -71,27 +71,3 @@ (base) %div %strong.commit-sha= short_sha(@merge_request_diff.base_commit_sha) - - - if different_base?(@start_version, @merge_request_diff) - .content-block - = icon('info-circle') - Selected versions have different base commits. - Changes will include - = link_to namespace_project_compare_path(@project.namespace, @project, from: @start_version.base_commit_sha, to: @merge_request_diff.base_commit_sha) do - new commits - from - = succeed '.' do - %code= @merge_request.target_branch - - - if @start_version || !@merge_request_diff.latest? - .comments-disabled-notif.content-block - = icon('info-circle') - Not all comments are displayed because you're - - if @start_version - comparing two versions - - else - viewing an old version - of the diff. - - .pull-right - = link_to 'Show latest version', diffs_namespace_project_merge_request_path(@project.namespace, @project, @merge_request), class: 'btn btn-sm' diff --git a/app/views/projects/merge_requests/show.html.haml b/app/views/projects/merge_requests/show.html.haml index dbbf1bde088..e485f9f6135 100644 --- a/app/views/projects/merge_requests/show.html.haml +++ b/app/views/projects/merge_requests/show.html.haml @@ -6,7 +6,7 @@ = page_specific_javascript_bundle_tag('common_vue') = page_specific_javascript_bundle_tag('diff_notes') -.merge-request{ 'data-url' => merge_request_path(@merge_request, format: :json), 'data-project-path' => project_path(@merge_request.project) } +.merge-request{ data: { url: merge_request_path(@merge_request, format: :json), project_path: project_path(@merge_request.project) } } = render "projects/merge_requests/mr_title" .merge-request-details.issuable-details{ data: { id: @merge_request.project.id } } |