summaryrefslogtreecommitdiff
path: root/app/models/merge_request.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/merge_request.rb')
-rw-r--r--app/models/merge_request.rb40
1 files changed, 34 insertions, 6 deletions
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
index 8271dc83116..a015a9ef394 100644
--- a/app/models/merge_request.rb
+++ b/app/models/merge_request.rb
@@ -135,11 +135,8 @@ class MergeRequest < ActiveRecord::Base
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) }
scope :by_milestone, ->(milestone) { where(milestone_id: milestone) }
- scope :in_projects, ->(project_ids) { where("source_project_id in (:project_ids) OR target_project_id in (:project_ids)", project_ids: project_ids) }
scope :of_projects, ->(ids) { where(target_project_id: ids) }
- scope :opened, -> { with_states(:opened, :reopened) }
scope :merged, -> { with_state(:merged) }
- scope :closed, -> { with_state(:closed) }
scope :closed_and_merged, -> { with_states(:closed, :merged) }
scope :join_project, -> { joins(:target_project) }
@@ -163,6 +160,24 @@ class MergeRequest < ActiveRecord::Base
super("merge_requests", /(?<merge_request>\d+)/)
end
+ # Returns all the merge requests from an ActiveRecord:Relation.
+ #
+ # This method uses a UNION as it usually operates on the result of
+ # ProjectsFinder#execute. PostgreSQL in particular doesn't always like queries
+ # using multiple sub-queries especially when combined with an OR statement.
+ # UNIONs on the other hand perform much better in these cases.
+ #
+ # relation - An ActiveRecord::Relation that returns a list of Projects.
+ #
+ # Returns an ActiveRecord::Relation.
+ def self.in_projects(relation)
+ source = where(source_project_id: relation).select(:id)
+ target = where(target_project_id: relation).select(:id)
+ union = Gitlab::SQL::Union.new([source, target])
+
+ where("merge_requests.id IN (#{union.to_sql})")
+ end
+
def to_reference(from_project = nil)
reference = "#{self.class.reference_prefix}#{iid}"
@@ -262,8 +277,14 @@ class MergeRequest < ActiveRecord::Base
self.target_project.events.where(target_id: self.id, target_type: "MergeRequest", action: Event::CLOSED).last
end
+ WIP_REGEX = /\A\s*(\[WIP\]\s*|WIP:\s*|WIP\s+)+\s*/i.freeze
+
def work_in_progress?
- !!(title =~ /\A\[?WIP(\]|:| )/i)
+ title =~ WIP_REGEX
+ end
+
+ def wipless_title
+ self.title.sub(WIP_REGEX, "")
end
def mergeable?
@@ -501,11 +522,15 @@ class MergeRequest < ActiveRecord::Base
end
def target_sha
- @target_sha ||= target_project.repository.commit(target_branch).sha
+ @target_sha ||= target_project.repository.commit(target_branch).try(:sha)
end
def source_sha
- last_commit.try(:sha)
+ last_commit.try(:sha) || source_tip.try(:sha)
+ end
+
+ def source_tip
+ source_branch && source_project.repository.commit(source_branch)
end
def fetch_ref
@@ -553,8 +578,11 @@ class MergeRequest < ActiveRecord::Base
end
def compute_diverged_commits_count
+ return 0 unless source_sha && target_sha
+
Gitlab::Git::Commit.between(target_project.repository.raw_repository, source_sha, target_sha).size
end
+ private :compute_diverged_commits_count
def diverged_from_target_branch?
diverged_commits_count > 0