diff --git a/pre_commit/git.py b/pre_commit/git.py index ec1928f37..1161be575 100644 --- a/pre_commit/git.py +++ b/pre_commit/git.py @@ -152,7 +152,8 @@ def intent_to_add_files() -> list[str]: def get_all_files() -> list[str]: - return zsplit(cmd_output('git', 'ls-files', '-z')[1]) + # git ls-files lists unmerged paths once per stage -- deduplicate (#3706) + return list(dict.fromkeys(zsplit(cmd_output('git', 'ls-files', '-z')[1]))) def get_changed_files(old: str, new: str) -> list[str]: diff --git a/tests/git_test.py b/tests/git_test.py index 02b6ce3ae..6658c4e4f 100644 --- a/tests/git_test.py +++ b/tests/git_test.py @@ -225,6 +225,14 @@ def test_all_files_non_ascii(non_ascii_repo): assert ret == ['интервью'] +def test_all_files_deduplicates_in_merge_conflict(in_merge_conflict): + # git ls-files lists each unmerged path once per stage; #3706 + ret = git.get_all_files() + # The fixture contains multiple tracked files; the bug is duplication + assert ret.count('conflict_file') == 1 + assert len(ret) == len(set(ret)) + + def test_staged_files_non_ascii(non_ascii_repo): non_ascii_repo.join('интервью').write('hi') cmd_output('git', 'add', '.')