From c294be513d0f00f6a2a0dcab15bb191984a88c40 Mon Sep 17 00:00:00 2001 From: Anthony Sottile Date: Mon, 2 Jul 2018 09:59:23 -0700 Subject: [PATCH] Fix force-push without fetch --- pre_commit/resources/hook-tmpl | 6 +++++- tests/commands/install_uninstall_test.py | 26 +++++++++++++++++++++--- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/pre_commit/resources/hook-tmpl b/pre_commit/resources/hook-tmpl index 2a9657ed..d3575857 100755 --- a/pre_commit/resources/hook-tmpl +++ b/pre_commit/resources/hook-tmpl @@ -105,6 +105,10 @@ def _exe(): ) +def _rev_exists(rev): + return not subprocess.call(('git', 'rev-list', '--quiet', rev)) + + def _pre_push(stdin): remote = sys.argv[1] @@ -113,7 +117,7 @@ def _pre_push(stdin): _, local_sha, _, remote_sha = line.split() if local_sha == Z40: continue - elif remote_sha != Z40: + elif remote_sha != Z40 and _rev_exists(remote_sha): opts = ('--origin', local_sha, '--source', remote_sha) else: # First ancestor not found in remote diff --git a/tests/commands/install_uninstall_test.py b/tests/commands/install_uninstall_test.py index 9f805691..6aa9c7fa 100644 --- a/tests/commands/install_uninstall_test.py +++ b/tests/commands/install_uninstall_test.py @@ -495,13 +495,13 @@ def test_installed_from_venv(tempdir_factory, store): assert NORMAL_PRE_COMMIT_RUN.match(output) -def _get_push_output(tempdir_factory): +def _get_push_output(tempdir_factory, opts=()): return cmd_output_mocked_pre_commit_home( - 'git', 'push', 'origin', 'HEAD:new_branch', + 'git', 'push', 'origin', 'HEAD:new_branch', *opts, # git push puts pre-commit to stderr stderr=subprocess.STDOUT, tempdir_factory=tempdir_factory, - retcode=None, + retcode=None )[:2] @@ -535,6 +535,26 @@ def test_pre_push_integration_accepted(tempdir_factory, store): assert 'Passed' in output +def test_pre_push_force_push_without_fetch(tempdir_factory, store): + upstream = make_consuming_repo(tempdir_factory, 'script_hooks_repo') + path1 = tempdir_factory.get() + path2 = tempdir_factory.get() + cmd_output('git', 'clone', upstream, path1) + cmd_output('git', 'clone', upstream, path2) + with cwd(path1): + assert _get_commit_output(tempdir_factory)[0] == 0 + assert _get_push_output(tempdir_factory)[0] == 0 + + with cwd(path2): + install(Runner(path2, C.CONFIG_FILE), store, hook_type='pre-push') + assert _get_commit_output(tempdir_factory, commit_msg='force!')[0] == 0 + + retc, output = _get_push_output(tempdir_factory, opts=('--force',)) + assert retc == 0 + assert 'Bash hook' in output + assert 'Passed' in output + + def test_pre_push_new_upstream(tempdir_factory, store): upstream = make_consuming_repo(tempdir_factory, 'script_hooks_repo') upstream2 = git_dir(tempdir_factory)