diff --git a/app/controllers/projects/merge_requests_controller.rb b/app/controllers/projects/merge_requests_controller.rb index 689c9627762..fda8a9ea2e3 100644 --- a/app/controllers/projects/merge_requests_controller.rb +++ b/app/controllers/projects/merge_requests_controller.rb @@ -135,33 +135,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController respond_to do |format| format.html { render 'show' } - format.json do - rugged = @merge_request.project.repository.rugged - their_commit = rugged.branches[@merge_request.target_branch].target - our_commit = rugged.lookup(@merge_request.diff_head_sha) - merge = rugged.merge_commits(our_commit, their_commit) - commit_message = "Merge branch '#{@merge_request.target_branch}' into '#{@merge_request.source_branch}'\n\n# Conflicts:" - - files = merge.conflicts.map do |conflict| - their_path = conflict[:theirs][:path] - our_path = conflict[:ours][:path] - - raise 'path mismatch!' unless their_path == our_path - - commit_message << "\n# #{our_path}" - merge_file = merge.merge_file(our_path) - - Gitlab::Conflict::File.new(merge_file, conflict, @merge_request.target_branch, @merge_request.source_branch, @merge_request.project.repository) - end - - render json: { - target_branch: @merge_request.target_branch, - source_branch: @merge_request.source_branch, - commit_sha: @merge_request.diff_head_sha, - commit_message: commit_message, - files: files - } - end + format.json { render json: Gitlab::Conflict::FileCollection.new(@merge_request) } end end diff --git a/lib/gitlab/conflict/file.rb b/lib/gitlab/conflict/file.rb index 84d3e6f4e03..7f81c72431d 100644 --- a/lib/gitlab/conflict/file.rb +++ b/lib/gitlab/conflict/file.rb @@ -3,20 +3,22 @@ module Gitlab class File CONTEXT_LINES = 3 - attr_reader :merge_file, :their_path, :their_ref, :our_path, :our_ref, :repository + attr_reader :merge_file_result, :their_path, :their_ref, :our_path, :our_ref, :repository - def initialize(merge_file, conflict, their_ref, our_ref, repository) - @merge_file = merge_file + def initialize(merge_file_result, conflict, diff_refs:, repository:) + @merge_file_result = merge_file_result @their_path = conflict[:theirs][:path] @our_path = conflict[:ours][:path] - @their_ref = their_ref - @our_ref = our_ref + @their_ref = diff_refs.start_sha + @our_ref = diff_refs.head_sha @repository = repository end # Array of Gitlab::Diff::Line objects def lines - @lines ||= Gitlab::Conflict::Parser.new.parse(merge_file[:data], their_path, our_path) + @lines ||= Gitlab::Conflict::Parser.new.parse(merge_file_result[:data], + our_path: our_path, + their_path: their_path) end def highlighted_lines @@ -28,9 +30,9 @@ module Gitlab @highlighted_lines = lines.map do |line| line = line.dup if line.type == 'old' - line.rich_text = their_highlight[line.old_line - 1].delete("\n") + line.rich_text = their_highlight[line.old_line - 1] else - line.rich_text = our_highlight[line.new_line - 1].delete("\n") + line.rich_text = our_highlight[line.new_line - 1] end line end diff --git a/lib/gitlab/conflict/file_collection.rb b/lib/gitlab/conflict/file_collection.rb new file mode 100644 index 00000000000..a3035a5c3e6 --- /dev/null +++ b/lib/gitlab/conflict/file_collection.rb @@ -0,0 +1,59 @@ +module Gitlab + module Conflict + class FileCollection + attr_reader :merge_request, :our_commit, :their_commit + + def initialize(merge_request) + @merge_request = merge_request + @our_commit = merge_request.diff_head_commit.raw.raw_commit + @their_commit = merge_request.target_branch_head.raw.raw_commit + end + + def repository + merge_request.project.repository + end + + def merge_index + @merge_index ||= repository.rugged.merge_commits(our_commit, their_commit) + end + + def files + @files ||= merge_index.conflicts.map do |conflict| + their_path = conflict[:theirs][:path] + our_path = conflict[:ours][:path] + + # TODO remove this + raise 'path mismatch!' unless their_path == our_path + + Gitlab::Conflict::File.new(merge_index.merge_file(our_path), + conflict, + diff_refs: merge_request.diff_refs, + repository: repository) + end + end + + def as_json(opts = nil) + { + target_branch: merge_request.target_branch, + source_branch: merge_request.source_branch, + commit_sha: merge_request.diff_head_sha, + commit_message: default_commit_message, + files: files + } + end + + def default_commit_message + conflict_filenames = merge_index.conflicts.map do |conflict| + "# #{conflict[:ours][:path]}" + end + + <