diff --git a/CHANGELOG b/CHANGELOG index 5b91ee1159c5ac6ca20013cb5e6e3e01925c7dc8..6a7c314f9f8e1a0b4637d0703434bd49f3de5121 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -34,6 +34,7 @@ v 8.10.0 (unreleased) - Add basic system information like memory and disk usage to the admin panel - Don't garbage collect commits that have related DB records like comments - More descriptive message for git hooks and file locks + - Handle custom Git hook result in GitLab UI v 8.9.5 (unreleased) - Improve the request / withdraw access button. !4860 diff --git a/app/services/merge_requests/merge_service.rb b/app/services/merge_requests/merge_service.rb index 9aaf5a5e561804560d5e962afc62905a57b21b6a..3bec66cea88555b7fd4b18187c3312daa1d2a0d5 100644 --- a/app/services/merge_requests/merge_service.rb +++ b/app/services/merge_requests/merge_service.rb @@ -36,10 +36,13 @@ module MergeRequests commit_id = repository.merge(current_user, merge_request.source_sha, merge_request.target_branch, options) merge_request.update(merge_commit_sha: commit_id) + 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) - return false + false end def after_merge diff --git a/lib/gitlab/git/hook.rb b/lib/gitlab/git/hook.rb index 5415f4844d3d848c41403fdca6ac51306c190eab..420c6883c45a0913da78ebdb87738cdb1812319f 100644 --- a/lib/gitlab/git/hook.rb +++ b/lib/gitlab/git/hook.rb @@ -41,7 +41,7 @@ module Gitlab chdir: repo_path } - Open3.popen3(vars, path, options) do |stdin, _, stderr, wait_thr| + Open3.popen3(vars, path, options) do |stdin, stdout, stderr, wait_thr| exit_status = true stdin.sync = true @@ -60,7 +60,7 @@ module Gitlab unless wait_thr.value == 0 exit_status = false - exit_message = stderr.gets + exit_message = retrieve_error_message(stderr, stdout) end end @@ -76,6 +76,11 @@ module Gitlab [status, nil] end + + def retrieve_error_message(stderr, stdout) + err_message = stderr.gets + err_message.blank? ? stdout.gets : err_message + end end end end diff --git a/spec/services/merge_requests/merge_service_spec.rb b/spec/services/merge_requests/merge_service_spec.rb index 1b0396eb6865c97fca3bfeb4b104d6792c1ceb7a..2f72cd600715689686dc4ad10b81d5c19d4afcaa 100644 --- a/spec/services/merge_requests/merge_service_spec.rb +++ b/spec/services/merge_requests/merge_service_spec.rb @@ -65,6 +65,16 @@ describe MergeRequests::MergeService, services: true do expect(merge_request.merge_error).to eq("Something went wrong during merge") end + + it 'saves error if there is an PreReceiveError exception' do + allow(service).to receive(:repository).and_raise(GitHooksService::PreReceiveError, "error") + + allow(service).to receive(:execute_hooks) + + service.execute(merge_request) + + expect(merge_request.merge_error).to eq("error") + end end end end