如何让Git将.strings文件视为文本文件而不是二进制文件

25
每当我们从不同的分支对.strings文件(用于iOS本地化)进行更改时,就会出现冲突。
原因似乎是git将.strings视为二进制文件而非文本文件。有时这有点烦人,因为git无法自动帮助合并更改,因为它们被视为二进制格式。
是否有任何git设置可以强制将文件视为文本文件。
我注意到SourceTree和GitLab都无法识别它是文本文件。但是XCode本身将能够显示差异。不确定这是否相关。

enter image description here

9个回答

28

2
@slawomir-jaranowski 建议使用 text,而您建议使用 diff;这两者有什么区别? - Sukima
使用 diff 将会导致该类型的文件使用您的默认差异工具进行比较。 - Jonathan.Brink
1
如果您想将此设置作为用户的全局设置添加(而不是提交到项目中),则可以运行 git config --global core.attributesfile <path>,其中路径可以是类似于 ~/.gitattributes 的内容。 - Luiz Dias

24

对于我来说,没有任何解决方案可行,所以我进行了更深入的研究,在这个链接上我找到了以下内容:

  • in your project main directory, create or edit a .gitattributes file adding this line:

    *.strings diff=localizablestrings
    
  • in the .gitconfig file in your home directory, add these lines:

    [diff "localizablestrings"]
    textconv = "iconv -f utf-16 -t utf-8"
    
这很管用。

我认为这应该被标记为正确答案。这是唯一一个使git diff工作并清晰地显示更改为可读文本的解决方案。至少对我来说是这样。请注意,.gitconfig位于您的主目录中,而.gitattributes是您添加到项目目录中的内容。这篇优秀的文章也是这么说的,但很容易忽略(好吧,我第一次就是这样!) - Andy Weinstein

13

在尝试Jonathan或Slawomir的解决方案后,我仍然无法正确地查看差异。它们仍被视为二进制文件。

我最终发现我们的localizable.strings文件不是使用UTF-8编码而是UTF-16编码。将编码更改回UTF-8后,它可以正常工作。

更改编码是否可行?是的,可以。实际上,苹果公司推荐使用UTF-8。

注意:建议您使用UTF-8编码保存字符串文件,这是标准字符串文件的默认编码。当将它们复制到产品中时,Xcode会自动将字符串文件从UTF-8转换为UTF-16。

[参考资料]

如何知道该文件使用哪种编码?请参见此处的命令行和此处的Xcode:

file -I vol34.tex 

请查看下面的评论,您可能需要手动更改文件的编码:

iconv -f UTF-16 -t UTF8 file.strings

1
我尝试使用Xcode 9.2来更改文件编码,但实际上并没有更改。它只是更改了.xcproj文件认为的文件编码。通过iconv -f UTF-16 -t UTF8 file.strings进行修复。 - Greg
1
@EdwardThomson 哈哈,谢谢!但我想我现在会把已接受的答案保留原样。我记得当时Jonathan的回答确实帮了我。如果这个答案以后获得更多的投票,我会改变绿色勾选标志的 ;) - Yuchen
对我来说,转换为UTF-8也解决了问题。然而,我正在使用genstrings,它会生成UTF-16LE格式的文件,因此我需要每次运行时将其转换回UTF-8。此外,使用iconv和Xcode将文件转换为UTF-8对我来说都没有起作用,最终我使用了VS Code。 - Ric Santos

1
这是我在Mac上使用的脚本变体。我需要将所有的 .strings 文件转换为 utf-8 编码,包括其中一些已经是 utf-8 的情况。请从您的 *.lproj 目录所在的文件夹运行它。
STRING_FILES=$(find . -type f -name '*.strings')
for f in $STRING_FILES; do 
  ENCODING=$(file -I $f)
  if [[ $ENCODING == *"utf-16le"* ]]; then
    iconv -f UTF-16 -t UTF8 $f > $f.1; 
    mv -f $f.1 $f
  fi
done

这个想法是从钟雨辰的回答中得到的。


1
我注意到SourceTree无法仅对英语本地化文件进行差异比较,其他文件都可以。因此,看起来只有该文件存在问题。
我用其他随机的Localized.strings文件替换了英语文件,其中SourceTree可以正确进行差异比较,复制了英语翻译,提交后,任何新更改都会被SourceTree正确显示。
请记住,您必须提交并查看它是否正常工作,因为您必须将修复后的文件与修复后的文件进行比较。

谢谢@Viktor Kucera,那个可行。我也试了其他的,但都没用。 - Mr. G

1
请在您的项目根目录下添加文件.gitattributes,其中包含以下内容:
*.strings  text

现在,git将会把你的文件.strings识别为文本文件。

2
@jonathan-brink建议使用diff,而您建议使用text;这两者有什么区别? - Sukima
从手册中:在路径上设置文本属性可以启用行尾规范化,并将该路径标记为文本文件。行尾转换将在不猜测内容类型的情况下进行。 - Slawomir Jaranowski
1
而:当设置差异属性的路径被视为文本时,即使它们包含在文本文件中通常不会出现的字节值,如NUL。 - Slawomir Jaranowski

0

在我的情况下,不需要 .gitattributes 和 .gitconfig 文件!

您需要执行以下简单步骤:

  1. 打开当前可用的 .strings 文件并复制其所有内容
  2. 打开终端,键入 nano <path/to/your/file/Localizable.strings> - 您可以在键入 nano 后将文件拖放到终端中 - 但不要按回车键
  3. 将文件移到垃圾桶中(以防失败时保存它)
  4. 返回终端并按回车键
  5. 将剪贴板内容粘贴到终端中
  6. 按下 control+xy 以保存文件
  7. 对项目中的 .strings 文件重复此操作
  8. 享受您的 .strings 文件差异!

0

0
我发现最好的方法是使用iconv将其转换为UTF8,其他方法在github中查看差异时无法正常工作。
iconv -f utf-16 -t utf-8 path/to/localization/en.lproj/Localizable.strings > temp.strings
mv temp.strings path/to/localization/en.lproj/Localizable.strings > temp.strings

然后提交并合并您的更改。随后的差异将被正确显示。


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