@@ -893,3 +893,37 @@ def test_validity_ref_names(self):
893893
894894 # Valid reference name should not raise.
895895 check_ref ("valid/ref/name" )
896+
897+ def test_packed_refs_with_non_utf8_ref_name_does_not_raise (self ):
898+ # See: https://github.com/gitpython-developers/GitPython/issues/2064
899+ #
900+ # Tag (and other) ref names stored in .git/packed-refs are arbitrary byte
901+ # strings as far as Git is concerned - they are not guaranteed to be valid
902+ # UTF-8. Iterating packed refs must not raise UnicodeDecodeError just because
903+ # one of the packed ref names happens to contain non-UTF-8 bytes.
904+ with tempfile .TemporaryDirectory () as tmp_dir :
905+ base_dir = Path (tmp_dir )
906+ with self ._repo_with_initial_commit (base_dir ) as repo :
907+ sha = repo .head .commit .hexsha
908+
909+ # A normal, valid-UTF-8 tag, packed alongside the problematic one.
910+ good_tag_ref = b"refs/tags/good-tag"
911+ # A tag name containing a byte sequence that is not valid UTF-8
912+ # (0xE9 here is not a valid standalone/leading UTF-8 byte in this
913+ # position), similar to what `git pack-refs` can legitimately
914+ # produce for a non-UTF-8 ref name.
915+ bad_tag_ref = b"refs/tags/release-\xe9 tage"
916+
917+ packed_refs_path = Path (repo .common_dir ) / "packed-refs"
918+ with open (packed_refs_path , "wb" ) as f :
919+ f .write (b"# pack-refs with: peeled fully-peeled sorted\n " )
920+ f .write (sha .encode ("ascii" ) + b" " + good_tag_ref + b"\n " )
921+ f .write (sha .encode ("ascii" ) + b" " + bad_tag_ref + b"\n " )
922+
923+ # Must not raise UnicodeDecodeError.
924+ tags = repo .tags
925+
926+ tag_names = {t .name .encode ("utf-8" , "surrogateescape" ) for t in tags }
927+ assert b"good-tag" in tag_names
928+ assert b"release-\xe9 tage" in tag_names
929+ assert len (tags ) == 2
0 commit comments