summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/models/merge_request.rb15
-rw-r--r--app/models/merge_request_diff.rb54
-rw-r--r--app/services/merge_requests/create_service.rb1
3 files changed, 37 insertions, 33 deletions
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 85048f928dc..6f2216ab5db 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -11,11 +11,13 @@ class MergeRequest < ActiveRecord::Base
belongs_to :merge_user, class_name: "User"
has_many :merge_request_diffs, dependent: :destroy
+ has_one :merge_request_diff
has_many :events, as: :target, dependent: :destroy
serialize :merge_params, Hash
- after_update :update_merge_request_diff
+ after_create :ensure_merge_request_diff, unless: :importing?
+ after_update :reload_diff_if_branch_changed
delegate :commits, :real_size, to: :merge_request_diff, prefix: nil
@@ -94,7 +96,6 @@ class MergeRequest < ActiveRecord::Base
validates :merge_user, presence: true, if: :merge_when_build_succeeds?
validate :validate_branches, unless: [:allow_broken, :importing?]
validate :validate_fork
- validates_associated :merge_request_diff, on: :create, unless: [:allow_broken, :importing?]
scope :by_branch, ->(branch_name) { where("(source_branch LIKE :branch) OR (target_branch LIKE :branch)", branch: branch_name) }
scope :cared, ->(user) { where('assignee_id = :user OR author_id = :user', user: user.id) }
@@ -282,11 +283,11 @@ class MergeRequest < ActiveRecord::Base
end
end
- def create_merge_request_diff
- merge_request_diffs.create
+ def ensure_merge_request_diff
+ merge_request_diff || create_merge_request_diff
end
- def update_merge_request_diff
+ def reload_diff_if_branch_changed
if source_branch_changed? || target_branch_changed?
reload_diff
end
@@ -689,8 +690,4 @@ class MergeRequest < ActiveRecord::Base
def keep_around_commit
project.repository.keep_around(self.merge_commit_sha)
end
-
- def merge_request_diff
- merge_request_diffs.first
- end
end
diff --git a/app/models/merge_request_diff.rb b/app/models/merge_request_diff.rb
index b668b62cdac..074d8f5d40a 100644
--- a/app/models/merge_request_diff.rb
+++ b/app/models/merge_request_diff.rb
@@ -22,28 +22,28 @@ class MergeRequestDiff < ActiveRecord::Base
serialize :st_commits
serialize :st_diffs
- validates :start_commit_sha, presence: true, unless: :importing?
- validates :head_commit_sha, presence: true, unless: :importing?
+ # For compatibility with old MergeRequestDiff which
+ # does not store those variables in database
+ after_initialize :ensure_commits_sha, if: :persisted?
- after_initialize :initialize_commits_sha, unless: :importing?
+ # All diff information is collected from repository after object is created.
+ # It allows you to override variables like head_commit_sha before getting diff.
after_create :save_git_content, unless: :importing?
- after_save :keep_around_commits, unless: :importing?
-
- # Those variables are used for collecting commits and diff from git repository.
- # After object is created those sha are stored in the database.
- # However some old MergeRequestDiff records don't
- # have those variables in the database so we try to initialize it
- def initialize_commits_sha
- self.start_commit_sha ||= merge_request.target_branch_sha
- self.head_commit_sha ||= persisted? ? last_commit.sha : merge_request.source_branch_sha
- self.base_commit_sha ||= find_base_sha
- end
# Collect information about commits and diff from repository
# and save it to the database as serialized data
def save_git_content
+ ensure_commits_sha
save_commits
+ reload_commits
save_diffs
+ keep_around_commits
+ end
+
+ def ensure_commits_sha
+ self.start_commit_sha ||= merge_request.target_branch_sha
+ self.head_commit_sha ||= last_commit.try(:sha) || merge_request.source_branch_sha
+ self.base_commit_sha ||= find_base_sha
end
def size
@@ -52,14 +52,15 @@ class MergeRequestDiff < ActiveRecord::Base
def diffs(options={})
if options[:ignore_whitespace_change]
- @diffs_no_whitespace ||= begin
- compare = Gitlab::Git::Compare.new(
- repository.raw_repository,
- start_commit_sha,
- head_commit_sha
- )
- compare.diffs(options)
- end
+ @diffs_no_whitespace ||=
+ begin
+ compare = Gitlab::Git::Compare.new(
+ repository.raw_repository,
+ start_commit_sha,
+ head_commit_sha
+ )
+ compare.diffs(options)
+ end
else
@diffs ||= {}
@diffs[options] ||= load_diffs(st_diffs, options)
@@ -70,6 +71,11 @@ class MergeRequestDiff < ActiveRecord::Base
@commits ||= load_commits(st_commits || [])
end
+ def reload_commits
+ @commits = nil
+ commits
+ end
+
def last_commit
commits.first
end
@@ -192,7 +198,6 @@ class MergeRequestDiff < ActiveRecord::Base
new_attributes[:st_diffs] = new_diffs
update_columns_serialized(new_attributes)
- keep_around_commits
end
def project
@@ -207,6 +212,9 @@ class MergeRequestDiff < ActiveRecord::Base
return unless head_commit_sha && start_commit_sha
project.merge_base_commit(head_commit_sha, start_commit_sha).try(:sha)
+ rescue Rugged::OdbError
+ # In case head or start commit does not exist in the repository any more
+ nil
end
def utf8_st_diffs
diff --git a/app/services/merge_requests/create_service.rb b/app/services/merge_requests/create_service.rb
index 553d7443c86..96a25330af1 100644
--- a/app/services/merge_requests/create_service.rb
+++ b/app/services/merge_requests/create_service.rb
@@ -16,7 +16,6 @@ module MergeRequests
merge_request.target_project ||= source_project
merge_request.author = current_user
merge_request.merge_params['force_remove_source_branch'] = force_remove_source_branch
- merge_request.merge_request_diffs.build
if merge_request.save
merge_request.update_attributes(label_ids: label_params)