diff --git a/pre_commit/commands/try_repo.py b/pre_commit/commands/try_repo.py index c9849ea4..3e256ad8 100644 --- a/pre_commit/commands/try_repo.py +++ b/pre_commit/commands/try_repo.py @@ -15,6 +15,7 @@ from pre_commit.commands.run import run from pre_commit.store import Store from pre_commit.util import cmd_output from pre_commit.util import tmpdir +from pre_commit.xargs import xargs logger = logging.getLogger(__name__) @@ -32,9 +33,15 @@ def _repo_ref(tmpdir, repo, ref): shadow = os.path.join(tmpdir, 'shadow-repo') cmd_output('git', 'clone', repo, shadow) cmd_output('git', 'checkout', ref, '-b', '_pc_tmp', cwd=shadow) + idx = git.git_path('index', repo=shadow) objs = git.git_path('objects', repo=shadow) env = dict(os.environ, GIT_INDEX_FILE=idx, GIT_OBJECT_DIRECTORY=objs) + + staged_files = git.get_staged_files(cwd=repo) + if staged_files: + xargs(('git', 'add', '--'), staged_files, cwd=repo, env=env) + cmd_output('git', 'add', '-u', cwd=repo, env=env) git.commit(repo=shadow) diff --git a/pre_commit/git.py b/pre_commit/git.py index c24ca86e..3b97bfd9 100644 --- a/pre_commit/git.py +++ b/pre_commit/git.py @@ -91,11 +91,12 @@ def get_conflicted_files(): return set(merge_conflict_filenames) | set(merge_diff_filenames) -def get_staged_files(): +def get_staged_files(cwd=None): return zsplit(cmd_output( 'git', 'diff', '--staged', '--name-only', '--no-ext-diff', '-z', # Everything except for D '--diff-filter=ACMRTUXB', + cwd=cwd, )[1]) diff --git a/pre_commit/xargs.py b/pre_commit/xargs.py index a382759c..f32cb32c 100644 --- a/pre_commit/xargs.py +++ b/pre_commit/xargs.py @@ -109,6 +109,7 @@ def xargs(cmd, varargs, **kwargs): """ negate = kwargs.pop('negate', False) target_concurrency = kwargs.pop('target_concurrency', 1) + max_length = kwargs.pop('_max_length', _get_platform_max_length()) retcode = 0 stdout = b'' stderr = b'' @@ -118,10 +119,10 @@ def xargs(cmd, varargs, **kwargs): except parse_shebang.ExecutableNotFoundError as e: return e.to_output() - partitions = partition(cmd, varargs, target_concurrency, **kwargs) + partitions = partition(cmd, varargs, target_concurrency, max_length) def run_cmd_partition(run_cmd): - return cmd_output(*run_cmd, encoding=None, retcode=None) + return cmd_output(*run_cmd, encoding=None, retcode=None, **kwargs) threads = min(len(partitions), target_concurrency) with _thread_mapper(threads) as thread_map: diff --git a/tests/commands/try_repo_test.py b/tests/commands/try_repo_test.py index 5b50f420..d9a0401a 100644 --- a/tests/commands/try_repo_test.py +++ b/tests/commands/try_repo_test.py @@ -123,3 +123,15 @@ def test_try_repo_uncommitted_changes(cap_out, tempdir_factory): config, ) assert rest == 'modified name!...........................................................Passed\n' # noqa: E501 + + +def test_try_repo_staged_changes(tempdir_factory): + repo = make_repo(tempdir_factory, 'modified_file_returns_zero_repo') + + with cwd(repo): + open('staged-file', 'a').close() + open('second-staged-file', 'a').close() + cmd_output('git', 'add', '.') + + with cwd(git_dir(tempdir_factory)): + assert not try_repo(try_repo_opts(repo, hook='bash_hook')) diff --git a/tests/xargs_test.py b/tests/xargs_test.py index a6cffd72..71f5454c 100644 --- a/tests/xargs_test.py +++ b/tests/xargs_test.py @@ -208,3 +208,13 @@ def test_thread_mapper_concurrency_uses_threadpoolexecutor_map(): def test_thread_mapper_concurrency_uses_regular_map(): with xargs._thread_mapper(1) as thread_map: assert thread_map is map + + +def test_xargs_propagate_kwargs_to_cmd(): + env = {'PRE_COMMIT_TEST_VAR': 'Pre commit is awesome'} + cmd = ('bash', '-c', 'echo $PRE_COMMIT_TEST_VAR', '--') + cmd = parse_shebang.normalize_cmd(cmd) + + ret, stdout, _ = xargs.xargs(cmd, ('1',), env=env) + assert ret == 0 + assert b'Pre commit is awesome' in stdout