使用GitPython按版本获取二进制文件:Unicode转字节失败
解决GitPython获取二进制文件内容时的Unicode编码错误问题
你遇到的问题根源在于 repo.git.show 默认会把 Git 命令的输出当成文本内容解析为 Unicode 字符串,但二进制文件(比如图片)的字节流并不符合 Unicode 编码规则,这就导致字符串中混入了无效的 Unicode 字符,后续尝试转码时自然会触发 UnicodeEncodeError。
下面给你两种可靠的解决方案:
方案一:使用 GitPython 原生 API 直接读取二进制内容(推荐)
GitPython 提供了更底层的仓库对象操作方法,可以直接获取文件的原始字节流,完全绕开编码问题:
from io import BytesIO import git # 初始化仓库 repo = git.Repo('.') # 获取指定提交的对象 target_commit = repo.commit('4cb2a02') # 从提交的树结构中找到目标文件(blob 对象) image_blob = target_commit.tree / 'example.jpg' # 读取二进制内容并写入 BytesIO b = BytesIO(image_blob.data_stream.read())
这种方法直接操作 Git 的 blob 对象,是最规范的方式,不会有编码相关的隐患。
方案二:调整 repo.git.show 的编码参数,获取原始字节
如果你坚持要用 repo.git.show,可以通过设置 encoding=None 让它返回原始的 bytes 对象,而不是自动解码为 Unicode 字符串:
from io import BytesIO import git repo = git.Repo('.') # 设置 encoding=None,让命令输出直接返回 bytes raw_bytes = repo.git.show("4cb2a02:example.jpg", encoding=None) # 直接用 bytes 创建 BytesIO b = BytesIO(raw_bytes)
这样就能拿到文件的原始二进制内容,不需要再做 encode 操作,自然不会触发编码错误。
为什么你的原代码会报错?
repo.git.show 默认会将 Git 命令的输出按系统默认编码解码为 Unicode 字符串,但二进制文件的字节流中存在大量不符合 Unicode 规则的字节,这些字节被错误地解码后会变成无效的 Unicode 代理字符或非法序列,当你尝试用 encode('utf-8') 转换时,Python 无法处理这些无效字符,就会抛出 UnicodeEncodeError。
内容的提问来源于stack exchange,提问作者redimp
相关产品推荐
相关产品推荐

