Commit 1d0c7b74 authored by Paco Guzman's avatar Paco Guzman

Introduce Compare model in the codebase.

This object will manage Gitlab::Git::Compare instances
parent 8f359ea9
......@@ -21,7 +21,7 @@ class Projects::CompareController < Projects::ApplicationController
def diff_for_path
return render_404 unless @compare
render_diff_for_path(Compare.decorate(@compare, @project).diff_file_collection(diff_options: diff_options))
render_diff_for_path(@compare.diff_file_collection(diff_options: diff_options))
end
def create
......@@ -40,18 +40,12 @@ class Projects::CompareController < Projects::ApplicationController
@compare = CompareService.new.execute(@project, @head_ref, @project, @start_ref)
if @compare
@commits = Commit.decorate(@compare.commits, @project)
@commits = @compare.commits
@start_commit = @compare.start_commit
@commit = @compare.commit
@base_commit = @compare.base_commit
@start_commit = @project.commit(@start_ref)
@commit = @project.commit(@head_ref)
@base_commit = @project.merge_base_commit(@start_ref, @head_ref)
diff_refs = Gitlab::Diff::DiffRefs.new(
base_sha: @base_commit.try(:sha),
start_sha: @start_commit.try(:sha),
head_sha: @commit.try(:sha)
)
@diffs = Compare.decorate(@compare, @project).diff_file_collection(diff_options: diff_options, diff_refs: diff_refs)
@diffs = @compare.diff_file_collection(diff_options: diff_options)
@diff_notes_disabled = true
@grouped_diff_discussions = {}
......
......@@ -86,7 +86,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
respond_to do |format|
format.html { define_discussion_vars }
format.json do
@diffs = @merge_request.diff_file_collection(diff_options) if @merge_request_diff.collected?
@diffs = @merge_request.diff_file_collection(diff_options)
render json: { html: view_to_html_string("projects/merge_requests/show/_diffs") }
end
......@@ -157,10 +157,7 @@ class Projects::MergeRequestsController < Projects::ApplicationController
@commit = @merge_request.diff_head_commit
@base_commit = @merge_request.diff_base_commit
if @merge_request.compare
@diffs = Compare.decorate(@merge_request.compare, @project).diff_file_collection(
diff_options: diff_options,
diff_refs: @merge_request.diff_refs
)
@diffs = @merge_request.diff_file_collection(diff_options)
end
@diff_notes_disabled = true
......
......@@ -317,7 +317,7 @@ class Commit
nil
end
def diff_file_collection(diff_options)
def diff_file_collection(diff_options = nil)
Gitlab::Diff::FileCollection::Commit.new(self, diff_options: diff_options)
end
......
class Compare
delegate :commits, :same, :head, :base, to: :@compare
delegate :same, :head, :base, to: :@compare
def self.decorate(compare, project)
if compare.is_a?(Compare)
......@@ -14,10 +14,53 @@ class Compare
@project = project
end
def diff_file_collection(diff_options:, diff_refs: nil)
def commits
@commits ||= Commit.decorate(@compare.commits, @project)
end
def start_commit
return @start_commit if defined?(@start_commit)
commit = @compare.base
@start_commit = commit ? ::Commit.new(commit, @project) : nil
end
def commit
return @commit if defined?(@commit)
commit = @compare.head
@commit = commit ? ::Commit.new(commit, @project) : nil
end
alias_method :head_commit, :commit
# Used only on emails_on_push_worker.rb
def base_commit=(commit)
@base_commit = commit
end
def base_commit
return @base_commit if defined?(@base_commit)
@base_commit = if start_commit && commit
@project.merge_base_commit(start_commit.id, commit.id)
else
nil
end
end
# keyword args until we get ride of diff_refs as argument
def diff_file_collection(diff_options:, diff_refs: self.diff_refs)
Gitlab::Diff::FileCollection::Compare.new(@compare,
project: @project,
diff_options: diff_options,
diff_refs: diff_refs)
end
def diff_refs
@diff_refs ||= Gitlab::Diff::DiffRefs.new(
base_sha: base_commit.try(:sha),
start_sha: start_commit.try(:sha),
head_sha: commit.try(:sha)
)
end
end
......@@ -168,8 +168,12 @@ class MergeRequest < ActiveRecord::Base
merge_request_diff ? merge_request_diff.diffs(*args) : compare.diffs(*args)
end
def diff_file_collection(diff_options)
Gitlab::Diff::FileCollection::MergeRequest.new(self, diff_options: diff_options)
def diff_file_collection(diff_options = nil)
if self.compare
self.compare.diff_file_collection(diff_options: diff_options, diff_refs: diff_refs)
else
Gitlab::Diff::FileCollection::MergeRequest.new(self, diff_options: diff_options)
end
end
def diff_size
......
......@@ -20,10 +20,13 @@ class CompareService
)
end
Gitlab::Git::Compare.new(
raw_compare = Gitlab::Git::Compare.new(
target_project.repository.raw_repository,
target_branch,
source_sha,
source_sha
)
# REVIEW be sure if it's target_project or source_project
Compare.new(raw_compare, target_project)
end
end
......@@ -34,7 +34,7 @@ module MergeRequests
# At this point we decide if merge request can be created
# If we have at least one commit to merge -> creation allowed
if commits.present?
merge_request.compare_commits = Commit.decorate(commits, merge_request.source_project)
merge_request.compare_commits = commits
merge_request.can_be_created = true
merge_request.compare = compare
else
......
......@@ -2,7 +2,7 @@ module MergeRequests
class MergeRequestDiffCacheService
def execute(merge_request)
# Executing the iteration we cache all the highlighted diff information
merge_request.diff_file_collection(Gitlab::Diff::FileCollection.default_options).diff_files.to_a
merge_request.diff_file_collection.diff_files.to_a
end
end
end
......@@ -7,7 +7,7 @@
= render "ci_menu"
- else
%div.block-connector
= render "projects/diffs/diffs", diff_files: @diffs.diff_files, project: @diffs.project, diff_refs: @diffs.diff_refs
= render "projects/diffs/diffs", diffs: @diffs
= render "projects/notes/notes_with_form"
- if can_collaborate_with_project?
- %w(revert cherry-pick).each do |type|
......
......@@ -8,7 +8,7 @@
- if @commits.present?
= render "projects/commits/commit_list"
= render "projects/diffs/diffs", diff_files: @diffs.diff_files, project: @diffs.project, diff_refs: @diffs.diff_refs
= render "projects/diffs/diffs", diffs: @diffs
- else
.light-well
.center
......
- show_whitespace_toggle = local_assigns.fetch(:show_whitespace_toggle, true)
- diff_files = diffs.diff_files
- if diff_view == 'parallel'
- fluid_layout true
......@@ -26,7 +27,7 @@
- diff_commit = commit_for_diff(diff_file)
- blob = diff_file.blob(diff_commit)
- next unless blob
- blob.load_all_data!(project.repository) unless blob.only_display_raw?
- blob.load_all_data!(@project.repository) unless blob.only_display_raw?
= render 'projects/diffs/file', i: index, project: project,
diff_file: diff_file, diff_commit: diff_commit, blob: blob, diff_refs: diff_refs
= render 'projects/diffs/file', i: index, project: @project,
diff_file: diff_file, diff_commit: diff_commit, blob: blob, diff_refs: diffs.diff_refs
......@@ -42,7 +42,7 @@
%h4 This comparison includes more than #{MergeRequestDiff::COMMITS_SAFE_SIZE} commits.
%p To preserve performance the line changes are not shown.
- else
= render "projects/diffs/diffs", diff_files: @diffs.diff_files, project: @diffs.project, diff_refs: @merge_request.diff_refs, show_whitespace_toggle: false
= render "projects/diffs/diffs", diffs: @diffs, show_whitespace_toggle: false
- if @pipeline
#builds.builds.tab-pane
= render "projects/merge_requests/show/builds"
......
- if @merge_request_diff.collected?
= render "projects/diffs/diffs", diff_files: @diffs.diff_files,
= render "projects/diffs/diffs", diffs: @diffs,
diff_refs: @diffs.diff_refs, project: @diffs.project
- elsif @merge_request_diff.empty?
.nothing-here-block Nothing to merge from #{@merge_request.source_branch} into #{@merge_request.target_branch}
......
......@@ -33,25 +33,19 @@ class EmailsOnPushWorker
reverse_compare = false
if action == :push
merge_base_sha = project.merge_base_commit(before_sha, after_sha).try(:sha)
base_commit = project.merge_base_commit(before_sha, after_sha)
compare = Gitlab::Git::Compare.new(project.repository.raw_repository, before_sha, after_sha)
diff_refs = Gitlab::Diff::DiffRefs.new(
base_sha: merge_base_sha,
start_sha: before_sha,
head_sha: after_sha
)
compare = Compare.decorate(compare, project)
compare.base_commit = base_commit
diff_refs = compare.diff_refs
return false if compare.same
if compare.commits.empty?
compare = Gitlab::Git::Compare.new(project.repository.raw_repository, after_sha, before_sha)
diff_refs = Gitlab::Diff::DiffRefs.new(
base_sha: merge_base_sha,
start_sha: after_sha,
head_sha: before_sha
)
compare = Compare.decorate(compare, project)
compare.base_commit = base_commit
diff_refs = compare.diff_refs
reverse_compare = true
......
......@@ -7,7 +7,7 @@ module Gitlab
delegate :count, :size, :real_size, to: :diff_files
def initialize(diffs, project:, diff_options:, diff_refs: nil)
def initialize(diffs, project:, diff_options: nil, diff_refs: nil)
@diffs = diffs
@project = project
@diff_options = diff_options
......
......@@ -3,6 +3,9 @@ module Gitlab
module FileCollection
class Commit < Base
def initialize(commit, diff_options:)
# Not merge just set defaults
diff_options = diff_options || Gitlab::Diff::FileCollection.default_options
super(commit.diffs(diff_options),
project: commit.project,
diff_options: diff_options,
......
......@@ -3,6 +3,9 @@ module Gitlab
module FileCollection
class Compare < Base
def initialize(compare, project:, diff_options:, diff_refs: nil)
# Not merge just set defaults
diff_options = diff_options || Gitlab::Diff::FileCollection.default_options
super(compare.diffs(diff_options),
project: project,
diff_options: diff_options,
......
......@@ -4,6 +4,8 @@ module Gitlab
class MergeRequest < Base
def initialize(merge_request, diff_options:)
@merge_request = merge_request
# Not merge just set defaults
diff_options = diff_options || Gitlab::Diff::FileCollection.default_options
super(merge_request.diffs(diff_options),
project: merge_request.project,
......@@ -27,15 +29,10 @@ module Gitlab
if cacheable?
cache_highlight!(diff_file)
else
highlight_diff_file!(diff_file)
diff_file # Don't need to eager load highlighted diff lines
end
end
def highlight_diff_file!(diff_file)
diff_file.highlighted_diff_lines = Gitlab::Diff::Highlight.new(diff_file, repository: diff_file.repository).highlight
diff_file
end
def highlight_diff_file_from_cache!(diff_file, cache_diff_lines)
diff_file.highlighted_diff_lines = cache_diff_lines.map do |line|
Gitlab::Diff::Line.init_from_hash(line)
......@@ -56,7 +53,6 @@ module Gitlab
if highlight_cache[file_path]
highlight_diff_file_from_cache!(diff_file, highlight_cache[file_path])
else
highlight_diff_file!(diff_file)
highlight_cache[file_path] = diff_file.highlighted_diff_lines.map(&:to_hash)
end
......
......@@ -35,13 +35,13 @@ module Gitlab
def commits
return unless compare
@commits ||= Commit.decorate(compare.commits, project)
@commits ||= compare.commits
end
def diffs
return unless compare
@diffs ||= compare.diff_file_collection(diff_options: { max_files: 30 }, diff_refs: diff_refs).diff_files
@diffs ||= compare.diff_file_collection(diff_options: { max_files: 30 }).diff_files
end
def diffs_count
......@@ -49,9 +49,7 @@ module Gitlab
end
def compare
if @opts[:compare]
Compare.decorate(@opts[:compare], project)
end
@opts[:compare] if @opts[:compare]
end
def diff_refs
......@@ -99,16 +97,18 @@ module Gitlab
if commits.length > 1
namespace_project_compare_url(project_namespace,
project,
from: Commit.new(compare.base, project),
to: Commit.new(compare.head, project))
from: compare.start_commit,
to: compare.head_commit)
else
namespace_project_commit_url(project_namespace,
project, commits.first)
project,
commits.first)
end
else
unless @action == :delete
namespace_project_tree_url(project_namespace,
project, ref_name)
project,
ref_name)
end
end
end
......
......@@ -16,9 +16,12 @@ describe Gitlab::Email::Message::RepositoryPush do
{ author_id: author.id, ref: 'master', action: :push, compare: compare,
send_from_committer_email: true }
end
let(:compare) do
let(:raw_compare) do
Gitlab::Git::Compare.new(project.repository.raw_repository,
sample_image_commit.id, sample_commit.id)
sample_image_commit.id, sample_commit.id)
end
let(:compare) do
Compare.decorate(raw_compare, project)
end
describe '#project' do
......@@ -62,7 +65,7 @@ describe Gitlab::Email::Message::RepositoryPush do
describe '#diffs_count' do
subject { message.diffs_count }
it { is_expected.to eq compare.diffs.size }
it { is_expected.to eq raw_compare.diffs.size }
end
describe '#compare' do
......@@ -72,7 +75,7 @@ describe Gitlab::Email::Message::RepositoryPush do
describe '#compare_timeout' do
subject { message.compare_timeout }
it { is_expected.to eq compare.diffs.overflow? }
it { is_expected.to eq raw_compare.diffs.overflow? }
end
describe '#reverse_compare?' do
......
......@@ -944,8 +944,9 @@ describe Notify do
describe 'email on push with multiple commits' do
let(:example_site_path) { root_path }
let(:user) { create(:user) }
let(:compare) { Gitlab::Git::Compare.new(project.repository.raw_repository, sample_image_commit.id, sample_commit.id) }
let(:commits) { Commit.decorate(compare.commits, nil) }
let(:raw_compare) { Gitlab::Git::Compare.new(project.repository.raw_repository, sample_image_commit.id, sample_commit.id) }
let(:compare) { Compare.decorate(raw_compare, project) }
let(:commits) { compare.commits }
let(:diff_path) { namespace_project_compare_path(project.namespace, project, from: Commit.new(compare.base, project), to: Commit.new(compare.head, project)) }
let(:send_from_committer_email) { false }
let(:diff_refs) { Gitlab::Diff::DiffRefs.new(base_sha: project.merge_base_commit(sample_image_commit.id, sample_commit.id).id, head_sha: sample_commit.id) }
......@@ -1046,8 +1047,9 @@ describe Notify do
describe 'email on push with a single commit' do
let(:example_site_path) { root_path }
let(:user) { create(:user) }
let(:compare) { Gitlab::Git::Compare.new(project.repository.raw_repository, sample_commit.parent_id, sample_commit.id) }
let(:commits) { Commit.decorate(compare.commits, nil) }
let(:raw_compare) { Gitlab::Git::Compare.new(project.repository.raw_repository, sample_commit.parent_id, sample_commit.id) }
let(:compare) { Compare.decorate(raw_compare, project) }
let(:commits) { compare.commits }
let(:diff_path) { namespace_project_commit_path(project.namespace, project, commits.first) }
let(:diff_refs) { Gitlab::Diff::DiffRefs.new(base_sha: project.merge_base_commit(sample_image_commit.id, sample_commit.id).id, head_sha: sample_commit.id) }
......
......@@ -61,7 +61,7 @@ describe MergeRequests::BuildService, services: true do
end
context 'one commit in the diff' do
let(:commits) { [commit_1] }
let(:commits) { Commit.decorate([commit_1], project) }
it 'allows the merge request to be created' do
expect(merge_request.can_be_created).to eq(true)
......@@ -84,7 +84,7 @@ describe MergeRequests::BuildService, services: true do
end
context 'commit has no description' do
let(:commits) { [commit_2] }
let(:commits) { Commit.decorate([commit_2], project) }
it 'uses the title of the commit as the title of the merge request' do
expect(merge_request.title).to eq(commit_2.safe_message)
......@@ -111,7 +111,7 @@ describe MergeRequests::BuildService, services: true do
end
context 'commit has no description' do
let(:commits) { [commit_2] }
let(:commits) { Commit.decorate([commit_2], project) }
it 'sets the description to "Closes #$issue-iid"' do
expect(merge_request.description).to eq("Closes ##{issue.iid}")
......@@ -121,7 +121,7 @@ describe MergeRequests::BuildService, services: true do
end
context 'more than one commit in the diff' do
let(:commits) { [commit_1, commit_2] }
let(:commits) { Commit.decorate([commit_1, commit_2], project) }
it 'allows the merge request to be created' do
expect(merge_request.can_be_created).to eq(true)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment