diff --git a/git/refs/symbolic.py b/git/refs/symbolic.py index 020de5e13..3642ce671 100644 --- a/git/refs/symbolic.py +++ b/git/refs/symbolic.py @@ -149,7 +149,7 @@ def _iter_packed_refs(cls, repo: "Repo") -> Iterator[Tuple[str, str]]: The packed refs file will be kept open as long as we iterate. """ try: - with open(cls._get_packed_refs_path(repo), "rt", encoding="UTF-8") as fp: + with open(cls._get_packed_refs_path(repo), "rt", encoding="UTF-8", errors="surrogateescape") as fp: for line in fp: line = line.strip() if not line: diff --git a/test/test_refs.py b/test/test_refs.py index d77b34eba..43e50a905 100644 --- a/test/test_refs.py +++ b/test/test_refs.py @@ -77,6 +77,19 @@ def test_from_pathlike(self): # Check remoteness assert Reference(self.rorepo, PathLikeMock("refs/remotes/origin")).is_remote() + def test_iter_packed_refs_with_non_utf8_name(self): + with tempfile.TemporaryDirectory() as tdir: + with self._repo_with_initial_commit(Path(tdir)) as repo: + packed_refs_path = Path(Reference._get_packed_refs_path(repo)) + hexsha = repo.head.commit.hexsha + packed_refs_path.write_bytes( + b"# pack-refs with: peeled\n" + hexsha.encode("ascii") + b" refs/tags/non-utf8-\xe9\n" + ) + + tag_data = [(tag.commit.hexsha, tag.path) for tag in repo.tags] + + self.assertEqual(tag_data, [(hexsha, "refs/tags/non-utf8-\udce9")]) + def test_tag_base(self): tag_object_refs = [] for tag in self.rorepo.tags: