Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit fdc2a88

Browse files
committed
1 parent cdf726b commit fdc2a88

3 files changed

Lines changed: 86 additions & 0 deletions

File tree

pre_commit/commands/run.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,18 @@ def _has_unmerged_paths(runner):
139139
return bool(stdout.strip())
140140

141141

142+
def _has_unstaged_config(runner):
143+
retcode, stdout, stderr = runner.cmd_runner.run(
144+
[
145+
'git', 'diff', '--exit-code', runner.config_file_path
146+
],
147+
retcode=None,
148+
encoding=None,
149+
)
150+
# be explicit, other git errors don't mean it has an unstaged config.
151+
return retcode == 1
152+
153+
142154
def run(runner, args, write=sys_stdout_write_wrapper, environ=os.environ):
143155
# Set up our logging handler
144156
logger.addHandler(LoggingHandler(args.color, write=write))
@@ -151,6 +163,16 @@ def run(runner, args, write=sys_stdout_write_wrapper, environ=os.environ):
151163
if bool(args.source) != bool(args.origin):
152164
logger.error('Specify both --origin and --source.')
153165
return 1
166+
if _has_unstaged_config(runner) and not args.no_stash:
167+
if args.allow_unstaged_config:
168+
logger.warn('You have an unstaged config file and have '
169+
'specified the --allow-unstaged-config option.\n'
170+
'Note that your config will be stashed before the '
171+
'config is parsed unless --no-stash is specified.')
172+
else:
173+
logger.error('You have an unstaged config file and have not '
174+
'specified the --allow-unstaged-config option.\n')
175+
return 1
154176

155177
# Don't stash if specified or files are specified
156178
if args.no_stash or args.all_files or args.files:

pre_commit/main.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,11 @@ def main(argv=None):
9494
'--source', '-s',
9595
help='The remote branch"s commit_id when using `git push`',
9696
)
97+
run_parser.add_argument(
98+
'--allow-unstaged-config', default=False, action='store_true',
99+
help='Allow an unstaged config to be present. Note that this will'
100+
'be stashed before parsing unless --no-stash is specified'
101+
)
97102
run_mutex_group = run_parser.add_mutually_exclusive_group(required=False)
98103
run_mutex_group.add_argument(
99104
'--all-files', '-a', action='store_true', default=False,

tests/commands/run_test.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ def _get_opts(
5353
no_stash=False,
5454
origin='',
5555
source='',
56+
allow_unstaged_config=False,
5657
):
5758
# These are mutually exclusive
5859
assert not (all_files and files)
@@ -65,6 +66,7 @@ def _get_opts(
6566
no_stash=no_stash,
6667
origin=origin,
6768
source=source,
69+
allow_unstaged_config=allow_unstaged_config,
6870
)
6971

7072

@@ -334,3 +336,60 @@ def test_lots_of_files(mock_out_store_directory, tmpdir_factory):
334336
stderr=subprocess.STDOUT,
335337
env=env,
336338
)
339+
340+
341+
def test_allow_unstaged_config_option(repo_with_passing_hook,
342+
mock_out_store_directory):
343+
344+
with cwd(repo_with_passing_hook):
345+
with io.open(
346+
'.pre-commit-config.yaml', 'a+',
347+
) as config_file:
348+
# writing a newline should be relatively harmless to get a change
349+
config_file.write('\n')
350+
351+
args = _get_opts(allow_unstaged_config=True)
352+
ret, printed = _do_run(repo_with_passing_hook, args)
353+
common_msg = 'You have an unstaged config file'
354+
warning_msg = 'have specified the --allow-unstaged-config option.'
355+
356+
assert common_msg in printed
357+
assert warning_msg in printed
358+
assert ret == 0
359+
360+
361+
def test_no_allow_unstaged_config_option(repo_with_passing_hook,
362+
mock_out_store_directory):
363+
364+
with cwd(repo_with_passing_hook):
365+
with io.open(
366+
'.pre-commit-config.yaml', 'a+',
367+
) as config_file:
368+
# writing a newline should be relatively harmless to get a change
369+
config_file.write('\n')
370+
371+
args = _get_opts(allow_unstaged_config=False)
372+
ret, printed = _do_run(repo_with_passing_hook, args)
373+
common_msg = 'You have an unstaged config file'
374+
error_msg = 'have not specified the --allow-unstaged-config option.\n'
375+
376+
assert common_msg in printed
377+
assert error_msg in printed
378+
assert ret == 1
379+
380+
381+
def test_no_stash_suppresses_allow_unstaged_config_option(
382+
repo_with_passing_hook, mock_out_store_directory):
383+
384+
with cwd(repo_with_passing_hook):
385+
with io.open(
386+
'.pre-commit-config.yaml', 'a+',
387+
) as config_file:
388+
# writing a newline should be relatively harmless to get a change
389+
config_file.write('\n')
390+
391+
args = _get_opts(allow_unstaged_config=False, no_stash=True)
392+
ret, printed = _do_run(repo_with_passing_hook, args)
393+
common_msg = 'You have an unstaged config file'
394+
395+
assert common_msg not in printed

0 commit comments

Comments
 (0)