From c97a92b3e9affb13e68561096cf31525a1239e0f Mon Sep 17 00:00:00 2001 From: Jonathan Griffe Date: Mon, 28 Oct 2024 11:10:46 +0100 Subject: [PATCH] fix(precommit): handle filenames with spaces in Commit.from_merge --- ...recommit_git_merge_filename_with_spaces.md | 3 ++ ggshield/core/scan/commit_utils.py | 4 +- tests/unit/core/scan/test_commit.py | 38 +++++++++++++++++++ 3 files changed, 43 insertions(+), 2 deletions(-) create mode 100644 changelog.d/20241028_113440_jonathan.griffe_fix_precommit_git_merge_filename_with_spaces.md diff --git a/changelog.d/20241028_113440_jonathan.griffe_fix_precommit_git_merge_filename_with_spaces.md b/changelog.d/20241028_113440_jonathan.griffe_fix_precommit_git_merge_filename_with_spaces.md new file mode 100644 index 0000000000..75dda92d39 --- /dev/null +++ b/changelog.d/20241028_113440_jonathan.griffe_fix_precommit_git_merge_filename_with_spaces.md @@ -0,0 +1,3 @@ +### Fixed + +- The ggshield pre-commit hook no longer crashes when merging files with spaces in their names (#991). diff --git a/ggshield/core/scan/commit_utils.py b/ggshield/core/scan/commit_utils.py index 39568ad0f0..75b627ed1b 100644 --- a/ggshield/core/scan/commit_utils.py +++ b/ggshield/core/scan/commit_utils.py @@ -369,7 +369,7 @@ def get_file_sha_in_ref( """ output = git(["ls-tree", "-z", ref] + files, cwd=cwd) for line in output.split("\0")[:-1]: - _, _, sha, path = line.split() + _, _, sha, path = line.split(maxsplit=3) yield (path, sha) @@ -381,7 +381,7 @@ def get_file_sha_stage( """ output = git(["ls-files", "--stage", "-z"] + files, cwd=cwd) for line in output.split("\0")[:-1]: - _, sha, _, path = line.split() + _, sha, _, path = line.split(maxsplit=3) yield (path, sha) diff --git a/tests/unit/core/scan/test_commit.py b/tests/unit/core/scan/test_commit.py index ca24aa6119..c1a4b08204 100644 --- a/tests/unit/core/scan/test_commit.py +++ b/tests/unit/core/scan/test_commit.py @@ -504,3 +504,41 @@ def test_from_merge(tmp_path): (Path("conflict.md"), Filemode.MODIFY), (Path("new.md"), Filemode.NEW), ] + + +def test_from_merge_filename_with_spaces(tmp_path): + """ + GIVEN two commits on different branches with a conflict + involving a filename with spaces + WHEN Commit.from_merge() is called + THEN it returns successfully + AND get_files returns the correct filename + """ + repo = Repository.create(tmp_path, initial_branch="master") + + Path(tmp_path / "inital.md").write_text("Initial") + repo.add(".") + repo.create_commit("Initial commit on master") + + repo.create_branch("feature_branch") + repo.checkout("master") + conflict_file = tmp_path / "file with spaces.md" + conflict_file.write_text("Hello") + repo.add(".") + repo.create_commit("Commit on master") + + repo.checkout("feature_branch") + conflict_file.write_text("World") + repo.add(".") + repo.create_commit("Commit on feature_branch") + + # Create merge commit with conflict + with pytest.raises(subprocess.CalledProcessError): + repo.git("merge", "master") + + conflict_file.write_text("Hello World !") + repo.add(".") + commit = Commit.from_merge(cwd=tmp_path) + files = list(commit.get_files()) + assert len(files) == 1 + assert files[0].path == Path("file with spaces.md")