60529e0216
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
69 lines
1.9 KiB
Ruby
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
|