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