diff --git a/git/repo/base.py b/git/repo/base.py index c39523344..a4161d620 100644 --- a/git/repo/base.py +++ b/git/repo/base.py @@ -26,6 +26,7 @@ from git.compat import defenc, safe_decode from git.config import GitConfigParser from git.db import GitCmdObjectDB +from git.diff import _unquote_path from git.exc import ( GitCommandError, InvalidGitRepositoryError, @@ -1158,7 +1159,7 @@ def ignored(self, *paths: PathLike) -> List[str]: Subset of those paths which are ignored """ try: - proc: str = self.git.check_ignore("--", *paths) + proc: bytes = self.git.check_ignore("--", *paths, stdout_as_string=False) except GitCommandError as err: if err.status == 1: # If return code is 1, this means none of the items in *paths are @@ -1168,7 +1169,12 @@ def ignored(self, *paths: PathLike) -> List[str]: # Raise the exception on all other return codes. raise - return proc.replace("\\\\", "\\").replace('"', "").split("\n") + # Git C-quotes a path containing special characters, including a line feed, + # so each path is on its own line. + return [ + safe_decode(_unquote_path(path[1:-1]) if path[:1] == path[-1:] == b'"' else path) + for path in proc.split(b"\n") + ] @property def active_branch(self) -> Head: diff --git a/test/test_repo.py b/test/test_repo.py index 47bf92b95..08cd4a1bf 100644 --- a/test/test_repo.py +++ b/test/test_repo.py @@ -1657,6 +1657,17 @@ def test_ignored_items_reported(self): ["included_file.txt", "ignored_file.txt", "included_dir/file.txt", "ignored_dir/file.txt"] ) == ["ignored_file.txt", "ignored_dir/file.txt"] + def test_ignored_items_reported_verbatim(self): + with tempfile.TemporaryDirectory() as tdir: + temp_repo = Repo.init(pathlib.Path(tdir) / "repo") + + with open(pathlib.Path(temp_repo.working_tree_dir) / ".gitignore", "w") as file: + file.write("*.env\n") + + # Git C-quotes each of these in its default output format. + paths = ["donn\u00e9es.env", 'q"uote.env', "tab\t.env", "nl\nx.env"] + assert temp_repo.ignored(["keep.txt", *paths]) == paths + @requires_symlinks def test_ignored_raises_error_w_symlink(self): with tempfile.TemporaryDirectory() as tdir: