Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion pre_commit/commands/run.py
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,10 @@ def run(
environ.get('_PRE_COMMIT_SKIP_POST_CHECKOUT')
):
return 0

# prevent pushing staged files not committed (#2486)
if args.hook_stage == 'pre-push' and git.get_staged_files():
logger.error('Staged files found. Please commit before pushing')
return 1
# Expose prepare_commit_message_source / commit_object_name
# as environment variables for the hooks
if args.prepare_commit_message_source:
Expand Down
40 changes: 36 additions & 4 deletions tests/commands/run_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,7 +362,7 @@ def test_show_diff_on_failure(
{'hook': 'nope', 'hook_stage': 'pre-push'},
(b'No hook with id `nope` in stage `pre-push`',),
1,
True,
False,
),
(
{'all_files': True, 'verbose': True},
Expand Down Expand Up @@ -828,7 +828,7 @@ def test_stages(cap_out, store, repo_with_passing_hook):
'language': 'pygrep',
'stages': [stage],
}
for i, stage in enumerate(('pre-commit', 'pre-push', 'manual'), 1)
for i, stage in enumerate(('pre-commit', 'manual'), 1)
],
}
add_config_to_repo(repo_with_passing_hook, config)
Expand All @@ -844,8 +844,7 @@ def _run_for_stage(stage):
return printed

assert _run_for_stage('pre-commit').startswith(b'hook 1...')
assert _run_for_stage('pre-push').startswith(b'hook 2...')
assert _run_for_stage('manual').startswith(b'hook 3...')
assert _run_for_stage('manual').startswith(b'hook 2...')


def test_commit_msg_hook(cap_out, store, commit_msg_repo):
Expand Down Expand Up @@ -1246,3 +1245,36 @@ def test_pre_commit_env_variable_set(cap_out, store, repo_with_passing_hook):
cap_out, store, repo_with_passing_hook, args, environ,
)
assert environ['PRE_COMMIT'] == '1'


def test_pre_push_fails_if_staged_files(
cap_out, store, repo_with_passing_hook,
):
Comment on lines +1250 to +1252
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this test is probably sufficient -- then you don't need the additional one above

config = {
'repo': 'local',
'hooks': [{
'id': 'no-todo',
'name': 'No TODO',
'entry': 'sh -c "! grep -iI todo $@" --',
'language': 'system',
'stage': 'pre-push',
}],
}
add_config_to_repo(repo_with_passing_hook, config)

with open('placeholder.py', 'w') as staged_file:
staged_file.write('"""TODO: something"""\n')
cmd_output('git', 'add', 'placeholder.py')
git_commit()
with open('placeholder.py', 'w') as staged_file:
staged_file.write('"""Ok"""\n')

cmd_output('git', 'add', 'placeholder.py')

args = run_opts(hook_stage='pre-push')
ret, printed = _do_run(cap_out, store, repo_with_passing_hook, args)
assert ret == 1
assert printed == (
b'[ERROR] Staged files found.'
b' Please commit before pushing\n'
)
Loading