【问题标题】:Why should I use core.autocrlf=true in Git?为什么我应该在 Git 中使用 core.autocrlf=true?
【发布时间】:2011-02-19 00:08:11
【问题描述】:

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

  1. 在任何地方将core.autocrlf 设置为false

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

    1. 在 gitattributes 中未正确标记为二进制,并且
    2. 恰好同时包含 CRLF 和 LF,

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

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

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

我不知道只保留行尾是否还有其他问题?

【问题讨论】:

  • stackoverflow.com/questions/2333424/… 有帮助吗?我有将autocrlf 设为假的具体原因的链接。
  • @VonC 谢谢,但我已经能够规定公司中的所有用户都将 autocrlf 设置为 false,并且目前认为这是最好的选择。但我想知道我是否有任何理由不应该这样做,因为我发现有很多人(例如 GitHub)说我 autocrlf 应该设置,但没有具体的原因。
  • @VonC 即我不是在寻找将 autocrlf 设置为 false 的理由。我正在寻找将其设置为 true 的理由。
  • 为什么不使用autocrlf = input:这似乎是两个极端之间的完美解决方案:您可以让您的 repo 免受 CRLF 垃圾的影响,并且本地 Windows 开发人员可以使用他们想要的任何东西,而无需本地文件任何魔法都会自动对他们进行。 (他们可能出于各种原因想要在本地使用 LF,所以在我看来,true 很糟糕。)我看不出使用 autocrlf = input 有任何缺点。
  • @iconclast,我遇到的一个原因是,如果您构建的发行版同时包含 Windows 批处理文件和 Unix shell 脚本。您希望在每种情况下都使用正确的行结尾,如果即使您明确地将它们设置为一种或另一种方式,Git 仍然在四处乱窜,这将更难做到。

标签: git line-endings


【解决方案1】:

在我们的项目中,我们声明了将 autocrlf 设置为 input 值的必要性。这就是您可能对此感兴趣的原因:

  • 您的项目在 Linux/Unix 环境中运行,开发人员正在 Windows 中编写代码。在推送过程中,CRLF 会自动转换为 LF,因此您只需在 Unix 服务器上签出 Git repo,一切都会很好。
  • 有时开发人员使用 WinSCP 手动将配置从 Windows 机器上传到服务器。这会导致 Unix 机器上的 CRLF 行结束和应用程序启动失败。 “输入”值部分消除了此类情况的数量

我们不久前面临的问题:

  • 如果在 DEV 的机器上将行尾设置为 CR(不是 CRLF),则在推送期间,它们不会转换为 LF,并将在 GIT 存储库中保持 CR。彻底检查行尾

【讨论】:

    【解决方案2】:

    我是一名 .NET 开发人员,多年来一直使用 Git 和 Visual Studio。我强烈建议将行尾设置为 true。并在存储库的生命周期内尽可能早地执行此操作。

    话虽如此,我讨厌 Git 改变我的行尾。源代码管理应该只保存和检索我所做的工作,它不应该修改它。曾经。但确实如此。

    如果您没有将每个开发人员都设置为 true,会发生什么情况,一个开发人员最终会设置为 true。这将开始将您所有文件的行尾更改为 LF 在您的存储库中。当用户设置为 false 时,Visual Studio 会警告您,并要求您更改它们。您将很快发生两件事。一,你会得到越来越多的警告,你的团队越大,你得到的越多。第二个也是更糟糕的事情是,它会显示每个修改文件的每一行都已更改(因为每一行的行尾都会被真正的人更改)。最终,您将无法再可靠地跟踪存储库中的更改。让每个人都保持真实比试图让每个人都保持虚假要容易和干净得多。忍受你信任的源代码控制正在做它不应该做的事情的事实是多么可怕。永远。

    【讨论】:

    • 使用策略(强制文件)执行此操作的问题在于,在 Windows 机器上,您可以拥有本地、全局和隐藏的配置文件(ProgramData/Git/Confg)。您可以通过将其签入 repo 来强制执行本地文件,但全局和隐藏文件优先。此外,本地和全局(或隐藏)也可能不同。如果是,它们将在同一台机器上相互冲突,导致没有行结束错误。这是一个痛苦的追踪。 :(
    • 正是我的想法。随心所欲地弄乱代码文件不是源代码控制的工作。行尾应该只是编辑工具的关注点,仅此而已。
    • 如果您的项目仅适用于 Windows,则没有问题。但是,如果您或您的同事在 *nix 平台上工作,那么您的“强烈推荐”将导致问题。尝试运行以\r\n 结尾的shebang 的bash、perl 或python 脚本,你会看到。
    • 您所描述的情况不是GIT的问题,将设置设置为通常应该的FALSE,它就消失了。 Instad,这是团队工作中的一个问题。 “最终一个开发人员设置true”是什么意思? 为什么你会首先允许他们这样做?当您将它们设置为访问 git repo 时,就像您不允许使用不同的语言污染某些区域(因此任何从事该工作的人都可以阅读它),或者就像您沿着选择的方向保留分支/合并/变基/等政策,他们应该得到一个明确的规则:设置正确的crlf。
    • 这样的帖子提醒我,我们必须将行尾视为代码文化中的一等公民。
    【解决方案3】:

    我在 GitHub 上工作,我发现 this article 很有帮助。

    它描述了 git autocrlf 的配置和设置 .gitattributes 文件。

    【讨论】:

      【解决方案4】:

      对我来说。

      编辑 .gitattributes 文件。

      添加

      *.dll binary
      

      然后一切顺利。

      【讨论】:

      • 不幸的是,我的存储库中有许多二进制文件不是 DLL:为了确定我有正确的文件扩展名列表添加到@987654322 @ 将需要审查数以万计的文件。
      【解决方案5】:

      更新 2

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

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

      在它存在的时候,这个错误在我在问题中提到的代码库中引起了少量的欢闹(直到今天使用autocrlf=false),并导致许多“EOL”提交消息并最终导致我的编写一个 git pre-commit 钩子来检查/防止引入混合行结尾。

      更新

      注意:正如 VonC 所述,从 Git 2.8 开始,合并标记 will not introduce Unix-style line-endings to a Windows-style file

      原创

      我注意到此设置的一个小问题是,当存在合并冲突时,git 添加的用于标记差异的行 not 具有 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
      

      * 它并不真正值得这个词:“问题”。

      【讨论】:

      • 注:当 Visual Studio 遇到这样的文件时,它会为您提供规范化行尾。选择 Windows 行尾或选择 not 来规范行尾可以正常工作(因为 VS 仍然正确显示它,一旦冲突解决,违规行将被删除)。
      • 不幸的是,公司版本控制纳粹不同意它(合并冲突标记上的 LF)不是问题。
      • 我同意合并冲突标记上的 LF 不应该成为问题。无论如何,这些行不应该提交给 repo。
      • 注意:从 git 2.8(2016 年 3 月)开始,合并标记实际上会以 CRLF 行结尾。见stackoverflow.com/a/35474954/6309
      【解决方案6】:

      autocrlf 设置为true 的唯一具体原因是:

      • 避免 git status 将所有文件显示为 modified,因为在将基于 Unix 的 EOL Git 存储库克隆到 Windows 时会自动进行 EOL 转换(例如,请参阅 issue 83
      • 您的编码工具以某种方式依赖于您的文件中存在的 native EOL 样式:

      除非您可以看到必须处理原生 EOL 的特定处理,否则您最好使用leaving autocrlf to false (git config --global core.autocrlf false)。

      请注意,此配置将是一个 本地 配置(因为配置不会从仓库推送到仓库)

      如果您希望克隆该存储库的所有用户都使用相同的配置,请查看“What's the best CRLF handling strategy with git?”,使用.gitattributes file 中的text 属性。

      例子:

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

      注意:从 git 2.8(2016 年 3 月)开始,合并标记将不再在 CRLF 文件中引入混合行结尾 (LF)。
      见“Make Git use CRLF on its “<<<<<<< HEAD” merge lines

      【讨论】:

      • @VonC 谢谢!这让我更有信心使用autocrlf=false 对我来说是安全的。出于兴趣,您知道为什么即使您将autocrlf设置为false,git仍然会进行eol转换吗?
      • @VonC:我认为这个答案不正确。在 Windows 上使用 core.autocrlf=true 可以按预期工作。来自 repo 的所有文件(在这种情况下应该具有 LF 行结尾)在结帐到 Windows PC 时转换为 CRLF 行结尾。从 Windows PC 提交时,所有文件都会转换回 LF 行结尾。遇到麻烦的方法是首先检查到具有错误 core.autocrlf 设置的 Windows PC(这太容易做到了)。
      • @Michael 所以在这种情况下,在我的场景中不使用core.autocrlf=false 的唯一原因是如果我有一些工具/编辑器会被行尾混淆?
      • 我肯定会使用false,我从来都不喜欢在后台发生的自动或魔法事件。只需在任何地方使用\nUTF-8 就可以了。如果某个傻瓜不明白有什么约定俗成的规则,忘记使用UTF-8\n,那就有人手动转换,打他的脸。
      • @Pauld'Aoust 我仍然更愿意在core.eol 文件中通过core.eol 属性指定需要该CRLF 的文件类型,而不是使用这个不分青红皂白地应用于全局core.autocrlf 设置所有个文件。
      猜你喜欢
      • 1970-01-01
      • 2012-07-10
      • 2020-04-23
      • 2017-03-22
      • 1970-01-01
      • 2021-08-10
      • 2011-04-10
      • 2012-02-11
      • 1970-01-01
      相关资源
      最近更新 更多