pep*_*pak 6 git encoding repository utf-8 windows-1252
我有一个现有的存储库,其中包含混合编码的文件 - 有些文件采用 UTF-8,有些文件采用 ANSI(例如 Windows-1252)。大多数情况下一切都工作正常,除了我厌倦了在 ANSI 文件上执行 diff 时看到“无效字符”,而且我特别恼火的是我无法使用我的 GUI 工具来暂存或取消暂存这些字符的块。我正在寻找一种方法来说服 Git 某个文件使用非 UTF-8 编码,以便 Git 会先执行转换,然后再对其施展魔法。
据我所知,有两种方法可以实现这一结果:
[diff "win1252"]
textconv = "iconv -f windows-1252 -t utf-8"
Run Code Online (Sandbox Code Playgroud)
.gitattributes,将文件标记为二进制并请求使用此过滤器将其转换为文本: *.txt diff=win1252
Run Code Online (Sandbox Code Playgroud)
这种方法似乎在孤立的情况下工作得很好git diff,但我遇到了几个我不知道如何解决的问题:
core.autocrlf = true,此方法也不会对转换命令的输出执行 CRLF 转换,因此我的 diff 将显示更改行中的行尾差异。我可以创建一个脚本,该脚本将运行 iconv 来执行编码转换,然后将输出传递给 dos2unix,后者将执行 EOL 转换,但这似乎相当严厉。git add -p显示垃圾(甚至比“未知字符”更糟糕),并且 SourceTree 停止暂存并显示一条错误消息,指出它无法找到原始文本。虽然我可能能够学会忍受#1和#2,但#3是一个阻塞问题,因为我主要需要完成这种转换,以方便上演带有“未知字符”的帅哥。我当前的工作流程(在git add -p没有任何转换的情况下使用)可能会显示“未知字符”,但至少它可以工作。
对 GUI 的更改是不切实际的:我尝试过的所有其他 GUI 都有比这更严重的问题。
.gitattributes,将文件标记为具有自定义编码的文本文件: *.txt text working-tree-encoding=windows-1252
Run Code Online (Sandbox Code Playgroud)
据我所知,这种方法涵盖了上面列出的所有抱怨,并且在命令行和 GUI 中都可以正常工作。不幸的是,有一个重要的警告:它仅适用于设置此属性后创建的文件。对于在添加此属性之前创建的文件,Git 将为包含这些未编码字符的每个文件显示更改(从“未知字符”到 windows-1252)。此外,克隆存储库后,它会抱怨“无法将 'a.txt' 从 UTF-8 编码为 windows-1252”。看起来该文件实际上已正确克隆(与原始文件逐字节匹配),但它仍然显示出差异。基本上,我必须提交每个带有“未知字符”的文件,以便在存储库中将其重新编码为 UTF-8,这会破坏我的历史记录,并且几乎使 Blame 无法使用。
似乎一个现实的方法可能是使用类似的东西git filter-branch,但是对于整个存储库(有类似的东西吗?)将所有现有文件转换为 UTF-8并将属性添加到第一次提交,但我担心做这么大规模的事情。另外,我预计我会丢失之前的提交 ID,这将是不幸的(我用提交 ID 标记我的可执行文件,以便轻松找到构建它们的版本)。
是否有任何方法可以克服所描述方法的缺点,或者是否有其他方法不易受到这些缺点的影响?
通过使用 ,您走上了正确的道路working-tree-encoding,但您还需要执行一个步骤。
在创建.gitattributes文件的同一提交中,运行git add --renormalize .,这将获取所有工作树文件并根据指定的编码对其进行过滤。然后您需要提交所有更改的文件和.gitattributes在同一提交中提交所有已更改的文件和文件,此后它们将以 UTF-8 形式存储在存储库中,但在工作树中以 Windows-1252 形式存储。
这确实有一个缺点,那就是git blame必须跳回到该提交之外,但您可以指定--ignore-revor --ignore-revs-file(或配置选项blame.ignoreRevsFile)来忽略该修订,并且一切都会起作用。
| 归档时间: |
|
| 查看次数: |
4570 次 |
| 最近记录: |