为什么要在Git中使用core.autocrlf = true?


295

我有一个可以从Windows和OS X访问的Git存储库,而且我知道已经包含一些带有CRLF行尾的文件。据我所知,有两种解决方法:

  1. 设置core.autocrlffalse无处不在,

  2. 按照此处的说明(在GitHub帮助页面上显示)将存储库转换为仅包含LF行尾,然后在Windows和OS X上将其设置core.autocrlf为。这样做的问题是,如果存储库中有任何二进制文件那:trueinput

    1. 没有在gitattributes中正确标记为二进制,并且
    2. 碰巧同时包含CRLF和LF,

    他们将被破坏。我的存储库可能包含此类文件。

那么,为什么不关闭Git的行尾转换呢?网路上有很多模糊的警告,提示您core.autocrlf关闭电源会导致问题,但很少有具体的警告。到目前为止,我唯一发现的是kdiff3无法处理CRLF结尾(对我来说不是问题),并且某些文本编辑器存在行尾问题(对我来说也不是问题)。

该存储库是我公司内部的,因此我不必担心与具有不同autocrlf设置或行尾要求的人们共享它。

我不知道仅将行尾留为原样还有其他问题吗?


1
stackoverflow.com/questions/2333424/...帮助吗?我已经链接到留下autocrlf假的具体原因。
VonC 2010年

3
@VonC谢谢,但是我已经能够决定公司中的所有用户都将<code> autocrlf </ code>设置为false,并且目前认为这是最佳选择。但是我想知道是否有任何原因我不应该这样做,因为我发现有很多人(例如GitHub)说我应该设置autocrlf,但是没有为什么的实际细节。
Rich

3
@VonC,即我不是在寻找设置autocrlf为false的原因。我正在寻找将其设置为true的理由。
Rich

9
为什么不使用autocrlf = input:这似乎是两个极端之间的完美解决方案:您可以保持回购协议不受CRLF废话的影响,并且Windows本地开发人员可以使用他们想要的任何内容,而本地文件不会自动对其进行任何处理。(由于各种原因,他们可能会在本地希望使用LF,所以true我认为这很糟糕。)我看不到使用会有什么缺点autocrlf = input
iconoclast 2012年

7
@iconclast,我遇到的一个原因是,如果您构建包含Windows批处理文件和Unix Shell脚本的发行版。您想在每种情况下都使用正确的行尾,并且即使在您以一种或另一种方式显式设置它们之后,如果Git使周围的事物混乱,这将很难做到。
user1809090

Answers:


227

设置autocrlf为的唯一特定原因true是:

  • 避免git status将所有文件显示为modified因为将基于Unix的EOL Git存储库克隆到Windows时自动完成EOL转换(例如,参见问题83
  • 您的编码工具某种程度上取决于文件中存在的本机 EOL样式:
    • 例如,一个代码生成器经过硬编码以检测本机EOL
    • 其他带有regexp或代码集的外部批处理(在您的仓库外部),用于检测本机EOL
    • 我相信某些Eclipse插件可以在平台上生成带有CRLF的文件,这可能是个问题。
    • 您可以使用Notepad.exe进行编码(除非您使用Windows 10 2018.09+,其中Notepad尊重检测到的EOL字符)。

除非你能看到哪些具体的治疗必须应对本土停产,你最好留下autocrlffalsegit config --global core.autocrlf false)。

请注意,此配置将是本地配置(因为该配置未从存储库推送到存储库)

如果要为所有克隆该存储库的用户使用相同的配置,请使用文件中的属性,检查“ 使用git 的最佳CRLF处理策略是什么? ” 。text.gitattributes

例:

*.vcproj    text eol=crlf
*.sh        text eol=lf

注意:从git 2.8(2016年3月)开始,合并标记将不再在CRLF文件中引入混合行结尾(LF)。
请参阅“ 让Git在其“ <<<<<<<< HEAD”合并行上使用CRLF


5
@VonC谢谢!这使我对使用它安全无忧autocrlf=false。出于兴趣,您是否知道即使将autocrlf设置为false,为什么git仍会进行eol转换?
Rich

14
@VonC:我认为这个答案不正确。在Windows上使用core.autocrlf = true可以正常工作。仓库中的所有文件(在这种情况下应该具有LF行尾)在签出到Windows PC时都将转换为CRLF行尾。从Windows PC提交后,所有文件都会转换回LF行结尾。遇到麻烦的方法是,最初使用错误的core.autocrlf设置(这完全太容易了),以Windows PC签出。
Michael Maddox 2010年

3
@Michael因此,在这种情况下,不使用core.autocrlf=false场景的唯一原因就是我是否拥有一些会因行尾而感到困惑的工具/编辑器?
丰富,16:

49
我一定会使用false,我从来都不喜欢后台发生的自动或魔术事件。随处使用\nUTF-8就可以了。如果有些疯子不了解其中有约定和规则,而忘记使用UTF-8\n,那么有人会手动将其转换并拍打他的脸。
2012年

5
@ Pauld'Aoust我还是希望通过文件中的core.eol属性指定需要CRLF 的.gitattributes文件类型,而不是使用core.autocrlf不加选择地应用于所有文件的全局设置。
VonC

40

我是.NET开发人员,并且已经使用Git和Visual Studio多年了。我的强烈建议是将行结尾设置为true。并尽早在存储库的生命周期中执行此操作。

话虽这么说,我讨厌Git更改行尾。源代码控件应仅保存和检索我所做的工作,而不应对其进行修改。曾经 但是确实如此。

如果您没有将每个开发人员都设置为true,那将会发生什么,那就是一个开发人员最终将设置为true。这将开始在您的仓库中将所有文件的行尾更改为LF。并且当用户设置为false时,将其签出,Visual Studio会警告您,并要求您更改它们。您将很快发生两件事。第一,您将收到越来越多的警告,您的团队越大,您得到的越多。第二,更糟糕的是,它将显示每个修改文件的每一行都已更改(因为每一行的行尾都将由真正的家伙更改)。最终,您将无法再可靠地跟踪存储库中的更改。使每个人保持真实,而不是让每个人都虚假,要容易得多,也更清洁。事实证明,您信任的源代码控件正在做它不应该做的事情。曾经


我的公司规模很小,以至于我们可以很容易地要求在所有地方都使用false,我本以为较大的公司可以通过政策来做到这一点,但是我想这是使用“ true”的正当理由,因此我赞成无论如何。谢谢!
丰富

1
使用策略(强制执行文件)执行此操作的问题在于,在Windows计算机上,您可以具有本地,全局和隐藏的配置文件(ProgramData / Git / Confg)。您可以通过将本地签入存储库来强制执行本地操作,但是全局和隐藏文件优先。也可能使本地和全局(或隐藏)不同。如果是这样,它们将在SAME机器上相互冲突,从而导致行末错误(如果没有)。很难找到答案。:(
JGTaylor

7
正是我的想法。它不是源代码控制随意处理代码文件的工作。行尾应该只是编辑工具的关注点,仅此而已。
TuncayGöncüoğlu

6
如果您的项目是仅Windows,则没有问题。但是,如果您或您的同事在* nix平台上工作,那么您的“强烈建议”将引起问题。尝试运行以bash结尾的bash,perl或python脚本\r\n,您将看到。
phuclv

6
您所描述的情况不是GIT的问题,应按通常的设置将其设置为FALSE,这样就消失了。Instad,这是团队合作中的一个问题。“最终由一个开发人员设置true” 是什么意思?您为什么首先要允许他们这样做?当您设置它们以访问git repo时,就像您不允许使用不同的lang污染某些区域(以便从事此工作的任何人都可以读取它)一样,或者就像您沿选择的分支保留了分支/合并/ rebases / etc政策,他们应该得到一个明确的规则:设置正确的crlf。
quetzalcoatl

12

更新2

Xcode 9似乎具有“功能”,它将忽略文件的当前行尾,而是在将行插入文件时使用默认的行尾设置,从而导致文件的行尾混合。

我很确定Xcode 7中不存在该错误;不确定Xcode8。好消息是它似乎已在Xcode 10中修复。

就它存在的时间而言,此错误在我在问题中引用的代码库(今天使用autocrlf=false)中引起了少量的欢笑,并导致了许​​多“ EOL”提交消息,最终导致我编写了一个git pre-commithook来检查用于/防止引入混合行结尾。

更新

注:由于注意到VonC,从Git的2.8开始,合并标记不会推出Unix风格的行结束到Windows样式的文件

原件

我注意到此设置的一个小问题是,当发生合并冲突时,git添加以标记差异的行没有 Windows行尾,即使文件的其余部分也是如此,您最终可能带有混合行尾的文件,例如:

// Some code<CR><LF>
<<<<<<< Updated upstream<LF>
// Change A<CR><LF>
=======<LF>
// Change B<CR><LF>
>>>>>>> Stashed changes<LF>
// More code<CR><LF>

这不会给我们造成任何问题(我想像任何一种能够处理两种类型的行尾的工具也将处理混合的行尾-显然我们使用的所有行尾都可以),但这是需要注意的。

*我们发现的另一件事是,当git diff用于查看具有Windows行尾的文件的更改时,已添加的行将显示其回车符,因此:

    // Not changed

+   // New line added in^M
+^M
    // Not changed
    // Not changed

*它并不是真正值得称呼的问题:“问题”。


2
注意当Visual Studio遇到这样的文件时,它会为您提供标准化的行尾。选择Windows的行尾或选择不对行尾进行标准化都可以正常工作(因为VS仍正确显示了该行,一旦解决了冲突,就会删除有问题的行)。
2012年

2
不幸的是,公司版本控制纳粹不同意它(合并冲突标记上的LF)不是问题。
Ilia G

1
我同意关于合并冲突标记的LF应该不是问题。这些行无论如何都不应提交回购协议。
抢劫

1
注意:从git 2.8(2016年3月)开始,合并标记实际上将以CRLF行结尾。参见stackoverflow.com/a/35474954/6309
VonC
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.