gitlab-org--gitlab-foss/app/services/merge_requests/merge_service.rb
Stan Hu 60529e0216 Properly abort a merge when merge conflicts occur
If somehow a user attempted to accept a merge request that had
conflicts (e.g. the "Accept Merge Request" button or the MR itself was
not updated), `MergeService` did not properly detect that a conflict
occurred. It would assume that the MR went through without any issues
and close the MR as though everything was fine. This could cause
data loss if the source branch were removed.

Closes #20425
2016-07-29 11:21:21 -07:00

69 lines
1.9 KiB
Ruby

module MergeRequests
# MergeService class
#
# Do git merge and in case of success
# mark merge request as merged and execute all hooks and notifications
# Executed when you do merge via GitLab UI
#
class MergeService < MergeRequests::BaseService
attr_reader :merge_request
def execute(merge_request)
@merge_request = merge_request
return error('Merge request is not mergeable') unless @merge_request.mergeable?
merge_request.in_locked_state do
if commit
after_merge
success
else
error('Can not merge changes')
end
end
end
private
def commit
committer = repository.user_to_committer(current_user)
options = {
message: params[:commit_message] || merge_request.merge_commit_message,
author: committer,
committer: committer
}
commit_id = repository.merge(current_user, merge_request, options)
if commit_id
merge_request.update(merge_commit_sha: commit_id)
else
merge_request.update(merge_error: 'Conflicts detected during merge')
false
end
rescue GitHooksService::PreReceiveError => e
merge_request.update(merge_error: e.message)
false
rescue StandardError => e
merge_request.update(merge_error: "Something went wrong during merge")
Rails.logger.error(e.message)
false
ensure
merge_request.update(in_progress_merge_commit_sha: nil)
end
def after_merge
MergeRequests::PostMergeService.new(project, current_user).execute(merge_request)
if params[:should_remove_source_branch].present? || @merge_request.force_remove_source_branch?
DeleteBranchService.new(@merge_request.source_project, branch_deletion_user).
execute(merge_request.source_branch)
end
end
def branch_deletion_user
@merge_request.force_remove_source_branch? ? @merge_request.author : current_user
end
end
end