Skip to content

Commit 09114f1

Browse files
authored
Merge pull request pre-commit#778 from pre-commit/pre_push_force_push
Fix force-push without fetch
2 parents 13c85f3 + c294be5 commit 09114f1

File tree

2 files changed

+28
-4
lines changed

2 files changed

+28
-4
lines changed

pre_commit/resources/hook-tmpl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,10 @@ def _exe():
105105
)
106106

107107

108+
def _rev_exists(rev):
109+
return not subprocess.call(('git', 'rev-list', '--quiet', rev))
110+
111+
108112
def _pre_push(stdin):
109113
remote = sys.argv[1]
110114

@@ -113,7 +117,7 @@ def _pre_push(stdin):
113117
_, local_sha, _, remote_sha = line.split()
114118
if local_sha == Z40:
115119
continue
116-
elif remote_sha != Z40:
120+
elif remote_sha != Z40 and _rev_exists(remote_sha):
117121
opts = ('--origin', local_sha, '--source', remote_sha)
118122
else:
119123
# First ancestor not found in remote

tests/commands/install_uninstall_test.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -495,13 +495,13 @@ def test_installed_from_venv(tempdir_factory, store):
495495
assert NORMAL_PRE_COMMIT_RUN.match(output)
496496

497497

498-
def _get_push_output(tempdir_factory):
498+
def _get_push_output(tempdir_factory, opts=()):
499499
return cmd_output_mocked_pre_commit_home(
500-
'git', 'push', 'origin', 'HEAD:new_branch',
500+
'git', 'push', 'origin', 'HEAD:new_branch', *opts,
501501
# git push puts pre-commit to stderr
502502
stderr=subprocess.STDOUT,
503503
tempdir_factory=tempdir_factory,
504-
retcode=None,
504+
retcode=None
505505
)[:2]
506506

507507

@@ -535,6 +535,26 @@ def test_pre_push_integration_accepted(tempdir_factory, store):
535535
assert 'Passed' in output
536536

537537

538+
def test_pre_push_force_push_without_fetch(tempdir_factory, store):
539+
upstream = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
540+
path1 = tempdir_factory.get()
541+
path2 = tempdir_factory.get()
542+
cmd_output('git', 'clone', upstream, path1)
543+
cmd_output('git', 'clone', upstream, path2)
544+
with cwd(path1):
545+
assert _get_commit_output(tempdir_factory)[0] == 0
546+
assert _get_push_output(tempdir_factory)[0] == 0
547+
548+
with cwd(path2):
549+
install(Runner(path2, C.CONFIG_FILE), store, hook_type='pre-push')
550+
assert _get_commit_output(tempdir_factory, commit_msg='force!')[0] == 0
551+
552+
retc, output = _get_push_output(tempdir_factory, opts=('--force',))
553+
assert retc == 0
554+
assert 'Bash hook' in output
555+
assert 'Passed' in output
556+
557+
538558
def test_pre_push_new_upstream(tempdir_factory, store):
539559
upstream = make_consuming_repo(tempdir_factory, 'script_hooks_repo')
540560
upstream2 = git_dir(tempdir_factory)

0 commit comments

Comments
 (0)