module Commits class ChangeService < ::BaseService ValidationError = Class.new(StandardError) ChangeError = Class.new(StandardError) def execute @start_project = params[:start_project] || @project @start_branch = params[:start_branch] @target_branch = params[:target_branch] @commit = params[:commit] check_push_permissions commit rescue Repository::CommitError, Gitlab::Git::Repository::InvalidBlobName, GitHooksService::PreReceiveError, ValidationError, ChangeError => ex error(ex.message) end private def commit raise NotImplementedError end def commit_change(action) raise NotImplementedError unless repository.respond_to?(action) validate_target_branch if different_branch? repository.public_send( action, current_user, @commit, @target_branch, start_project: @start_project, start_branch_name: @start_branch) success rescue Repository::CreateTreeError error_msg = "Sorry, we cannot #{action.to_s.dasherize} this #{@commit.change_type_title(current_user)} automatically. A #{action.to_s.dasherize} may have already been performed with this #{@commit.change_type_title(current_user)}, or a more recent commit may have updated some of its content." raise ChangeError, error_msg end def check_push_permissions allowed = ::Gitlab::UserAccess.new(current_user, project: project).can_push_to_branch?(@target_branch) unless allowed raise ValidationError.new('You are not allowed to push into this branch') end true end def validate_target_branch result = ValidateNewBranchService.new(@project, current_user) .execute(@target_branch) if result[:status] == :error raise ChangeError, "There was an error creating the source branch: #{result[:message]}" end end def different_branch? @start_branch != @target_branch || @start_project != @project end end end