将git仓库文件编码转换

31

我有一个包含使用 ISO-8859-1 编码的文件的大型 CVS 仓库,希望将其转换为 git。

当然,我可以配置 git 使用 ISO-8859-1 编码,但我希望使用 utf8 编码。

现在,像 iconvrecode 这样的工具可以转换我的工作树中文件的编码。我可以提交一条类似于 converted encoding 的消息。

我的问题是,是否有可能转换完整的历史记录?无论是从 cvs 转换到 git 还是之后。我的想法是编写一个脚本,读取 git 仓库中的每个提交,并将其转换为 utf8 并提交到新的 git 仓库中。

这可行吗(我对哈希代码以及如何遍历提交、分支和标签不确定)?还是有工具可以处理这样的问题?


3
是的,你可以重写历史记录,但最好不要这样做:你不应该重写已经推送到某个地方的仓库。我的意见是:使用iconv和普通提交是正确的方法。 - KingCrunch
1
好的,谢谢@KingCrunch。但是由于我新创建了git存储库,它被推送到了无处。而且我也愿意创建一个基于第一个存储库历史记录的“utf8”编码的第二个存储库。这基本上是相同的,只是我不会修改现有的存储库。 - Bertram Nudelbach
1个回答

24
你可以使用 git filter-branch 来实现这个功能。思路是需要在每个提交中更改文件的编码,随着提交的进行逐步重写每个提交。
首先,编写一个脚本来更改存储库中每个文件的编码。它可能看起来像这样:
#!/bin/sh

find . -type f -print | while read f; do
        mv -i "$f" "$f.recode.$$"
        iconv -f iso-8859-1 -t utf-8 < "$f.recode.$$" > "$f"
        rm -f "$f.recode.$$"
done

然后使用 git filter-branch 命令运行这个脚本,每次只针对一个提交进行操作:

git filter-branch --tree-filter /tmp/recode-all-files HEAD

其中/tmp/recode-all-files是上述脚本。

在从CVS刚刚升级的存储库中,您可能只有一个具有线性历史记录的git分支回到开始。如果您有几个分支,则可能需要增强git filter-branch命令以编辑所有提交。


很好!目前该命令正在测试git存储库上运行。实际上我有很多分支,我刚刚查看了文档,我只需要添加“--all”来过滤所有分支吗? - Bertram Nudelbach
对于其他的分支,命令git filter-branch --tree-filter /tmp/recode-all-files -- --all可以过滤所有分支。 - Bertram Nudelbach
1
我正在尝试使用您的答案,但是我收到了“recode-all-files: command not found”的错误提示。我正在使用Mac电脑,它似乎已经安装了iconv,但我不知道是否需要进行其他设置。 - marimaf
2
如果您在提交消息中也使用了ISO-8859-1字符,您也可以将它们转换为UTF-8:git filter-branch --msg-filter 'iconv -f iso-8859-1 -t utf-8' -- --all - hfs

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接