【发布时间】:2022-01-19 16:34:23
【问题描述】:
我在 Windows 上,通过 git bash CLI 使用 git。我有一个使用UTF-8 编码的.java 文件,我从旧的svn 服务器导入到git。我的同事也在 Windows 上,但使用 Eclipse IDE 中的 git 客户端,经常抱怨这个特定文件在结帐时有空格更改(即没有任何手动修改)。我相信问题与git 将文件视为二进制文件有关,但我不确定。 ls-files --eol 的输出为:
$ git ls-files --eol -- src/Props.java
i/-text w/-text attr/text=auto eol=crlf src/Props.java
以上似乎表明git 认为文件的存储版本是二进制的(i/-text w/-text 位),但也识别存储库中的属性设置(attr/text=auto eol=crlf 位)。这怎么可能?有没有办法修复它,以便存储在索引/工作树中的是crlf?我是否正在寻找正确的地方来解决这个问题?
【问题讨论】:
-
text=auto告诉 Git 猜测。您看到的输出表明 Git 确实猜到了,它的猜测是“这些是二进制文件”。猜测是不可配置的,但您可以强制 Git 相信文件是文本(或不是文本),text或-text在.gitattributes中。但是,如果 Git 猜测该文件是二进制文件,则它可能不是文本(例如,它可能存储为 UTF16,对于 Git 来说不是文本,如果将其视为文本并进行 EOL 转换,它可能会损坏 Git )。 -
很难判断文件是否已被某些错误的 Windows 软件从 UTF-8 转换为 UTF-16-LE,因为检查文件的其他软件会发现它是 UTF-16 -LE,将其转换为 UTF-8,然后检查它并自豪地宣布该文件现在是 UTF-8。当你的工具对你撒谎时——许多现代工具都会撒谎——事情就会变得困难。
-
好的,假设我真的想告诉
git将此文件视为text并以crlf行结尾。我需要某种方法来确定编码是什么,然后用某种方法替换那些欺骗git相信它是二进制的字符,对吧?关于如何做这两件事的想法?我完全控制了这个文件,它不需要是 UTF-16(或任何其他特殊编码),所以手动修改文件不是问题。 (FWIW,Notepad++认为它是 UTF-8 而file -i Props.java给出了text/x-java; charset=us-ascii) -
如果文件真的是文本,奇怪的是 Git 会猜错,但只需将
.gitattributes中的text=auto更改为text就会告诉 Git 文件是文本。 (更改或添加的内容取决于.gitattributes文件中已有的内容:如果您有* text=auto,您可以在其下方添加*.java text以覆盖.java文件,例如。添加eol=crlf以制作Git 在从存储库到工作树的途中将 \n 转为 \r\n,并且仅在从工作树到存储库的途中将 \r\n 转为 \n,如果这是你想要的。) -
请注意,不同的
eol=设置指导Git在退出时是否做\n => \r\n,以及是否做\r\n => \n方式。设置是:两者都做,或者只做输入到存储库端(\r\n => \n)的转换。这些是唯一可用的转换选项:例如,在进入存储库选项的过程中没有 \n 到 \r\n。-text(或binary)表示放手,text表示放手,eol=设置转换。