diff options
Diffstat (limited to 'app')
-rw-r--r-- | app/models/merge_request.rb | 15 | ||||
-rw-r--r-- | app/models/merge_request_diff.rb | 54 | ||||
-rw-r--r-- | app/services/merge_requests/create_service.rb | 1 |
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) |