Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'app/models/merge_request.rb')
-rw-r--r--app/models/merge_request.rb368
1 files changed, 0 insertions, 368 deletions
diff --git a/app/models/merge_request.rb b/app/models/merge_request.rb
deleted file mode 100644
index 9c9e2762507..00000000000
--- a/app/models/merge_request.rb
+++ /dev/null
@@ -1,368 +0,0 @@
-# == Schema Information
-#
-# Table name: merge_requests
-#
-# id :integer not null, primary key
-# target_branch :string(255) not null
-# source_branch :string(255) not null
-# source_project_id :integer not null
-# author_id :integer
-# assignee_id :integer
-# title :string(255)
-# created_at :datetime
-# updated_at :datetime
-# milestone_id :integer
-# state :string(255)
-# merge_status :string(255)
-# target_project_id :integer not null
-# iid :integer
-# description :text
-# position :integer default(0)
-# locked_at :datetime
-#
-
-require Rails.root.join("app/models/commit")
-require Rails.root.join("lib/static_model")
-
-class MergeRequest < ActiveRecord::Base
- include Issuable
- include Taskable
- include InternalId
- include Sortable
-
- belongs_to :target_project, foreign_key: :target_project_id, class_name: "Project"
- belongs_to :source_project, foreign_key: :source_project_id, class_name: "Project"
-
- has_one :merge_request_diff, dependent: :destroy
-
- after_create :create_merge_request_diff
- after_update :update_merge_request_diff
-
- delegate :commits, :diffs, :last_commit, :last_commit_short_sha, to: :merge_request_diff, prefix: nil
-
- attr_accessor :should_remove_source_branch
-
- # When this attribute is true some MR validation is ignored
- # It allows us to close or modify broken merge requests
- attr_accessor :allow_broken
-
- # Temporary fields to store compare vars
- # when creating new merge request
- attr_accessor :can_be_created, :compare_failed,
- :compare_commits, :compare_diffs
-
- state_machine :state, initial: :opened do
- event :close do
- transition [:reopened, :opened] => :closed
- end
-
- event :merge do
- transition [:reopened, :opened, :locked] => :merged
- end
-
- event :reopen do
- transition closed: :reopened
- end
-
- event :lock_mr do
- transition [:reopened, :opened] => :locked
- end
-
- event :unlock_mr do
- transition locked: :reopened
- end
-
- after_transition any => :locked do |merge_request, transition|
- merge_request.locked_at = Time.now
- merge_request.save
- end
-
- after_transition locked: (any - :locked) do |merge_request, transition|
- merge_request.locked_at = nil
- merge_request.save
- end
-
- state :opened
- state :reopened
- state :closed
- state :merged
- state :locked
- end
-
- state_machine :merge_status, initial: :unchecked do
- event :mark_as_unchecked do
- transition [:can_be_merged, :cannot_be_merged] => :unchecked
- end
-
- event :mark_as_mergeable do
- transition [:unchecked, :cannot_be_merged] => :can_be_merged
- end
-
- event :mark_as_unmergeable do
- transition [:unchecked, :can_be_merged] => :cannot_be_merged
- end
-
- state :unchecked
- state :can_be_merged
- state :cannot_be_merged
-
- around_transition do |merge_request, transition, block|
- merge_request.record_timestamps = false
- begin
- block.call
- ensure
- merge_request.record_timestamps = true
- end
- end
- end
-
- validates :source_project, presence: true, unless: :allow_broken
- validates :source_branch, presence: true
- validates :target_project, presence: true
- validates :target_branch, presence: true
- validate :validate_branches
- validate :validate_fork
-
- scope :of_group, ->(group) { where("source_project_id in (:group_project_ids) OR target_project_id in (:group_project_ids)", group_project_ids: group.project_ids) }
- scope :merged, -> { with_state(:merged) }
- 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) }
- # Closed scope for merge request should return
- # both merged and closed mr's
- scope :closed, -> { with_states(:closed, :merged) }
- scope :declined, -> { with_states(:closed) }
-
- def validate_branches
- if target_project == source_project && target_branch == source_branch
- errors.add :branch_conflict, "You can not use same project/branch for source and target"
- end
-
- if opened? || reopened?
- similar_mrs = self.target_project.merge_requests.where(source_branch: source_branch, target_branch: target_branch, source_project_id: source_project.id).opened
- similar_mrs = similar_mrs.where('id not in (?)', self.id) if self.id
- if similar_mrs.any?
- errors.add :validate_branches,
- "Cannot Create: This merge request already exists: #{
- similar_mrs.pluck(:title)
- }"
- end
- end
- end
-
- def validate_fork
- return true unless target_project && source_project
-
- if target_project == source_project
- true
- else
- # If source and target projects are different
- # we should check if source project is actually a fork of target project
- if source_project.forked_from?(target_project)
- true
- else
- errors.add :validate_fork,
- 'Source project is not a fork of target project'
- end
- end
- end
-
- def update_merge_request_diff
- if source_branch_changed? || target_branch_changed?
- reload_code
- mark_as_unchecked
- end
- end
-
- def reload_code
- if merge_request_diff && open?
- merge_request_diff.reload_content
- end
- end
-
- def check_if_can_be_merged
- if Gitlab::Satellite::MergeAction.new(self.author, self).can_be_merged?
- mark_as_mergeable
- else
- mark_as_unmergeable
- end
- end
-
- def merge_event
- self.target_project.events.where(target_id: self.id, target_type: "MergeRequest", action: Event::MERGED).last
- end
-
- def closed_event
- self.target_project.events.where(target_id: self.id, target_type: "MergeRequest", action: Event::CLOSED).last
- end
-
- def automerge!(current_user, commit_message = nil)
- MergeRequests::AutoMergeService.
- new(target_project, current_user).
- execute(self, commit_message)
- end
-
- def open?
- opened? || reopened?
- end
-
- def mr_and_commit_notes
- # Fetch comments only from last 100 commits
- commits_for_notes_limit = 100
- commit_ids = commits.last(commits_for_notes_limit).map(&:id)
-
- project.notes.where(
- "(noteable_type = 'MergeRequest' AND noteable_id = :mr_id) OR (noteable_type = 'Commit' AND commit_id IN (:commit_ids))",
- mr_id: id,
- commit_ids: commit_ids
- )
- end
-
- # Returns the raw diff for this merge request
- #
- # see "git diff"
- def to_diff(current_user)
- Gitlab::Satellite::MergeAction.new(current_user, self).diff_in_satellite
- end
-
- # Returns the commit as a series of email patches.
- #
- # see "git format-patch"
- def to_patch(current_user)
- Gitlab::Satellite::MergeAction.new(current_user, self).format_patch
- end
-
- def hook_attrs
- attrs = {
- source: source_project.hook_attrs,
- target: target_project.hook_attrs,
- last_commit: nil
- }
-
- unless last_commit.nil?
- attrs.merge!(last_commit: last_commit.hook_attrs(source_project))
- end
-
- attributes.merge!(attrs)
- end
-
- def for_fork?
- target_project != source_project
- end
-
- def project
- target_project
- end
-
- # Return the set of issues that will be closed if this merge request is accepted.
- def closes_issues(current_user = self.author)
- if target_branch == project.default_branch
- issues = commits.flat_map { |c| c.closes_issues(project, current_user) }
- issues.push(*Gitlab::ClosingIssueExtractor.new(project, current_user).
- closed_by_message(description))
- issues.uniq.sort_by(&:id)
- else
- []
- end
- end
-
- # Mentionable override.
- def gfm_reference
- "merge request !#{iid}"
- end
-
- def target_project_path
- if target_project
- target_project.path_with_namespace
- else
- "(removed)"
- end
- end
-
- def source_project_path
- if source_project
- source_project.path_with_namespace
- else
- "(removed)"
- end
- end
-
- def source_project_namespace
- if source_project && source_project.namespace
- source_project.namespace.path
- else
- "(removed)"
- end
- end
-
- def target_project_namespace
- if target_project && target_project.namespace
- target_project.namespace.path
- else
- "(removed)"
- end
- end
-
- def source_branch_exists?
- return false unless self.source_project
-
- self.source_project.repository.branch_names.include?(self.source_branch)
- end
-
- def target_branch_exists?
- return false unless self.target_project
-
- self.target_project.repository.branch_names.include?(self.target_branch)
- end
-
- # Reset merge request events cache
- #
- # Since we do cache @event we need to reset cache in special cases:
- # * when a merge request is updated
- # Events cache stored like events/23-20130109142513.
- # The cache key includes updated_at timestamp.
- # Thus it will automatically generate a new fragment
- # when the event is updated because the key changes.
- def reset_events_cache
- Event.reset_event_cache_for(self)
- end
-
- def merge_commit_message
- message = "Merge branch '#{source_branch}' into '#{target_branch}'"
- message << "\n\n"
- message << title.to_s
- message << "\n\n"
- message << description.to_s
- message << "\n\n"
- message << "See merge request !#{iid}"
- message
- end
-
- # Return array of possible target branches
- # depends on target project of MR
- def target_branches
- if target_project.nil?
- []
- else
- target_project.repository.branch_names
- end
- end
-
- # Return array of possible source branches
- # depends on source project of MR
- def source_branches
- if source_project.nil?
- []
- else
- source_project.repository.branch_names
- end
- end
-
- def locked_long_ago?
- return false unless locked?
-
- locked_at.nil? || locked_at < (Time.now - 1.day)
- end
-end