Git无法在Linux上使用LF检出以CRLF存储的文件

3
我正在Linux上检查第三方项目"libjpeg",该项目位于https://github.com/winlibs/libjpeg(这只是一个例子,实际上我在许多其他项目中也遇到了同样的问题)。我有以下Git行尾配置。
我只配置了全局设置(设置为使用LF行尾进行检出):
$ git config --system -l | grep core
core.eol=lf
core.autocrlf=false

$ git config --global -l | grep core
core.eol=lf
core.autocrlf=false

关于行尾的本地(repo)设置是不存在的。

我读了一篇有关Git行尾配置的文章:https://adaptivepatchwork.com/2012/03/01/mind-the-end-of-your-line,我认为我的配置应该在Linux上给我所有文本文件提供LF。然而它并不起作用。在我的工作区中,我得到的是CRLF。例如:

Original Answer翻译成"最初的回答"

~/gitclonetest/libjpeg$ file libjpeg.map
libjpeg.map: ASCII text, with CRLF line terminators
~/gitclonetest/libjpeg$ cat -v libjpeg.map
LIBJPEG_9.0 {^M
  global:^M
    *;^M
};^M

能有人帮我理解我错过了什么吗?我的目标是在Linux主机上克隆任何项目时,自动将所有文本文件转换为LF。

更新:目标是配置Git,在Linux主机上检出LF,即使文件在存储库中以CRLF存储。

最初的回答:


很可能,存储库中提交的文件已经具有CRLF行尾。如果是这种情况,并且您指示Git根本不干扰行尾(通常在Linux上),那么当将该文件提取到可用的、可编辑的Linux文件时,Git将保留存储库副本中存在的CRLF行尾。也就是说,如果您告诉Git:精确保留此二进制数据,Git会这样做。事实上,这个二进制数据是文本并不重要。 - torek
@torek,我已经更新了我的问题。如果我现在发布的标志是错误的,你能告诉我应该使用哪些标志来实现转换为LF吗?对我来说,似乎我尝试了所有可能的组合,但没有一个有效。 - Alexander Samoylov
1
我检查了(通过克隆存储库),确实提交的文件中有CRLF行尾。你可以告诉Git在转换过程中修改这些文件(因为文件从索引中提取到工作树中),但由于你使用的是“好”的操作系统(Linux),通常不应该这样做。编写此库的人希望您在Git内部保留具有CRLF行尾的提交文件。 - torek
@torek,那么针对我的情况解决方案是什么呢?是的,很明显该文件是使用CRLF提交的。但是我想在Linux上checkout时始终获得LF。我不在乎哪些行用于提交文件,我只想让Git按照我指定的行来checkout它。core.eol=lf难道不能实现这一点吗?如果不能,那么应该采用什么设置呢? - Alexander Samoylov
在这种情况下,您需要一个带有指令text eol=lf.gitattributes文件来处理那些特定的文件。但是影响会导致每次提交时,存储在仓库中的文件将只使用LF行结尾,这与以CRLF行结尾将文件放入仓库的人的愿望相悖。在这种情况下,没有任何必要让Git执行此操作:您可以提取所有文件,将它们全部转换一次并进行提交。实质上,您在声明先前的仓库维护者是错误的。[续] - torek
如果您打算这样做,即声明先前的存储库维护者错误,那么您只需说明某些文件为文本,其他文件为二进制,并让他们的Windows系统将仓库中保存的LF行结束符转换为CRLF行结束符,在Linux系统上不执行任何操作。在这种情况下,“eol=lf”将是不必要的,甚至可以说是错误的。请查看Git存储库(github.com/git/git)中的“.gitattributes”文件。 - torek
4个回答

3
问题在于您将core.autocrlf设置为true。文档中如下所述:
将此变量设置为“true”等同于在所有文件上设置文本属性为“auto”,并将core.eol设置为“crlf”。如果您希望在工作目录中具有CRLF行尾,并且存储库具有LF行尾,则应将其设置为true。
在Unix或Linux系统上,绝对不要将该变量设置为true;除非您在Windows系统上(即使是这样,也有更好的替代方案),它应该设置为false

也尝试了这个 - 仍然有同样的问题。 $ git config --system -l | grep core core.eol=lf core.autocrlf=false $ git config --global -l | grep core core.eol=lf core.autocrlf=false $ rm -rf libjpeg; git clone https://github.com/winlibs/libjpeg 2>/dev/null; file libjpeg/libjpeg.map libjpeg/libjpeg.map: ASCII text, with CRLF line terminators现在将更新问题以使其更清晰... - Alexander Samoylov

2

旧但仍然正确的答案 关于Git中的EOL头疼问题

简而言之:

core.autocrlf = false 
core.eol = native

会在任何操作系统上生成正确的行尾符。

懒惰的Badger,我尝试了你的设置,但它在https://github.com/winlibs/libjpeg上无法工作(你能在你的主机上重现吗?)。$ git config --system -l | grep core core.eol=native core.autocrlf=false $ git config --global -l | grep core core.eol=native core.autocrlf=false $ rm -rf libjpeg; git clone https://github.com/winlibs/libjpeg >& /dev/null; file libjpeg/libjpeg.map libjpeg/libjpeg.map:ASCII文本,带有CRLF行终止符 - Alexander Samoylov
@AlexanderSamoylov,好的,试试= input。我没有/使用Git(我在Mercurial战线上),现在也没有LF-OS。 - Lazy Badger

0

您很可能已经设置了一些标志,告诉git混淆EOL格式(这些标志非常混乱)。如果您不想让git干扰它们,可以通过将此内容添加到.gitattributes来实现:

* -text

那样,git在添加或检出文件时就不会弄乱它们。如果您需要其他类型的东西(例如真正的自动行尾转换),可以检查那里提供的可用选项。

https://git-scm.com/docs/gitattributes

无论如何,避免使用你在问题中使用的标记。它们很混乱。


1
请问您指的其他标志是哪些(在哪里可以查看)?我认为除了我上面描述的内容,我没有其他的了。另一个问题:您建议使用.gitattributes。首先,我无法将此文件添加到仓库中,因为它是外部仓库(不是由我开发)。其次,我提出问题的意义在于了解为什么默认配置如果我做得正确却不起作用。我还应该检查什么? - Alexander Samoylov
@AlexanderSamoylov 这些标志就是你在问题中描述的那些。它们真的很混乱。它们就像 git 上 EOL 处理的第一次迭代。然后创建了第二个版本(使用属性的版本)。只有将其添加到 .git/info/attributes 中,您才能在存储库中使用相同的东西。有关如何执行操作的良好信息,请参见链接:https://git-scm.com/docs/gitattributes - eftshift0
正如我之前告诉你的,我无法修改repo。然而,我阅读了你的链接并尝试了全局/etc/gitattributes文件。它没有起作用。第二个尝试是:在core.autocrlf的所有3个不同值(input、false、true)的组合中使用“git config --system core.eol lf”。这也没有起作用。关于我的标志中的“混乱”……实际上,我只在用户(--global)级别上设置了2个标志:core.eol和core.autocrlf。我发布了另一个问题来说明其他标志都未设置。 - Alexander Samoylov
你能否在你的主机上尝试克隆libjpeg并给我一组全局标志的组合,使其能够与LF一起克隆?我只是想知道是否有其他人可以做到这一点。 - Alexander Samoylov
@AlexanderSamoylov 我并不是说你设置的混乱。我是指你在git中使用的标志的实施是一团糟。而且.git/info/attributes可以在你的本地仓库上进行修改,而不会干扰原始仓库或分支。 - eftshift0

0

我在创建一个shell脚本来执行一些自动操作时遇到了这个问题,脚本无法对一些文件进行git addgit checkout操作,因为这些文件中有"LF to be replaced by CRLF"

要解决这个问题,你有两个选择:

git config --global core.autocrlf = false # Not recommended to deactivate this feature at all
git config --global core.safecrlf false # Just silent it instead (warning is ignored)

我的最终建议是在脚本(或手动操作)的开头使用第二种方法,然后在脚本结束时将其恢复为默认值:

git config --global core.safecrlf true # I'm assuming you didn't mess with autocrlf itself

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