【问题标题】:Enforce core.autocrlf=input through .gitattributes通过 .gitattributes 强制执行 core.autocrlf=input
【发布时间】:2017-07-28 19:46:27
【问题描述】:

有没有办法在.gitattributes 中强制执行core.autocrlf=input,以便在我的同事中传播该政策?

详细来说,我想要在 add 上转换为 lf 并在 checkout 上留下 as is

问题是texteol.gitattributes 中都没有做我想做的事,因为eol 有3 个可接受的值:

  1. lf
  2. crlf
  3. native

理想情况下,我希望我的 .gitattributes 文件看起来像这样:

* text eol=asis

【问题讨论】:

  • 您希望存储库本身的行结尾是什么?如果?工作树中最初是什么?
  • 你要找的设置是这样的:* text=auto eol=lf

标签: git line-endings eol gitattributes core.autocrlf


【解决方案1】:

目前尚不清楚工作树中“原样”的确切含义。如果您希望 Git 将行尾存储在存储库中的 LF 中,并让用户决定他们想要在工作树中的内容(基于他们的平台和/或设置),那么使用这个:

* text

这将强制行结束转换,Git 会将文件转换为存储库中的 LF,并在结帐时遵守用户首选的行结束。如果不是所有文件都是文本(即,你有图像或其他二进制文件)并且你希望 Git 猜测,那么你可以使用这个:

* text=auto

请注意,正如 LoopInFool 所提到的,这不会导致已经是 CRLF 的文件被转换,因此您需要确保您的文件已经在存储库中的 LF 中,或者将这些文件类型明确列出为文本(例如,*.c text)。

core.autocrlf=input 的行为是在添加到存储库时强制转换为 LF,而不是在结帐时执行任何转换;也就是说,无论用户的设置如何,始终使用 LF 结尾。如果这是您想要的行为,那么您可以使用以下方法:

* eol=lf

请注意,设置eol 会有效设置text 属性,因此您不应在任何二进制文件上设置它。

如果您希望 Git 匹配结帐时工作树中已经存在的行尾(例如,通过读取文件),那么它不会这样做。 Git 总是根据配置进行行尾转换,而不考虑已经存在的内容,因此用户必须以某种方式表明他们的偏好或接受平台默认行为。

此外,Git 始终将文件大小的任何修改计为 git status 中的修改,即使它在添加时忽略了这些更改(例如,因为您只更改了行尾);这同样是无法避免的。

如果你想要的是完全不同的东西,请详细说明你想要什么行为,我会更新更多细节。

【讨论】:

    【解决方案2】:

    详细来说,我想要的是在提交时转换为 lf 并在结帐时保持原样。

    Git 不会在提交时转换,而是在 git add 时转换。 (更准确地说,它对将对象复制到存储库并产生哈希值的操作进行转换——但对于大多数目的,无论如何,这只是git add。)此时它应用任何“干净”过滤器并执行输入端EOL 操作。 (同样,输出端“涂抹”过滤器和 EOL 操作在从存储库复制到工作树时发生,在大多数情况下是 git checkoutgit reset --hard。)

    根据the gitattributes documentation,设置eol=lf

    ... 强制 Git 将行尾标准化为 LF on 签入并防止文件转换为 CRLF 签出。

    因此,虽然我没有实际测试过,但听起来* eol=lf 正是您想要的。 请注意,这与 core.eol 不同,后者的行为与您在问题中描述的一样;这仅适用于.gitattributes 设置,适用于匹配名称模式的文件。

    【讨论】:

    • 嗯...我之前向 OP eol=lf 求婚...不高兴:stackoverflow.com/questions/3206843/…
    • @torek 正如你所说,我将 commit 更正为 add。关于 gitattributes 文档 (git-scm.com/docs/gitattributes#_effects) 我引用了“要控制在工作目录中使用哪种行尾样式,请对单个文件使用 eol 属性,对所有文本文件使用 core.eol 配置变量。”这表明core.eol 实际上与eol 相同。此外,我再次引用“...确保 .vcproj 文件在工作目录中具有 CRLF 并且 .sh 文件具有 LF,...”指的是 *.sh text eol=lf"
    • core.* 设置仅在.gitattributes 中没有更具体的设置时适用。特别是,如果路径名没有 .gitattributes eol= 条目,Git 必须 (1) 确定文件是否为文本,然后 (2) 应用 core.eolcore.autocrlf 规则。 * text=auto .gitattributes 条目将 Git 的猜测应用于所有没有后行更具体规则的文件。请注意,如果有多个.gitattributes 文件和/或.git/info/attributes,您还必须应用所有优先规则;并且有哪些索引和工作树.gitattributes 覆盖的规则。
    • 顺便说一句,这方面的文档似乎在逐渐完善,但仍然一团糟,有时代码中的某些内容似乎与文档中的某些内容不匹配。因此,您可能还需要提及特定的 Git 版本。我怀疑 Windows Git 人员有时也会与非 Windows 人员在这些事情上发生争执 :-)
    • 文档并不糟糕,但至少令人困惑。我正在使用 git 2.8.3 under cygwingit 1.8.3.1 under CentOS 7 我已经检查过并且都使用eol而不是向后兼容的crlf .gitattributes。 @torek 建议您在文档中找到的另一件事是 eol=lf 的向后兼容是 crlf=input。然而,在动手之后,我发现autocrlf=input 会给我一个干净的克隆,而eol=lf 在克隆后会有行尾冲突。
    【解决方案3】:

    最接近core.autocrlf=input 的是在.gitattributes 中使用text=auto

    指定它们是文本文件,因此新文件将被放入以 LF 行结尾的 repo 中。 并且,根据The gitattributes documentation,通过设置text=auto

    使用 CRLF 提交文件后,不会进行任何转换。

    我们最近将 Mercurial 存储库转换为 Git。 Mercurial 不进行 eol 转换,因此我们的许多文件在转换后已经具有 CRLF。为这些文件扩展名设置 text=auto 允许新文件仍被规范化为 LF,但不会触及现有文件,并且不会在当前目录中将它们显示为已修改。

    【讨论】:

      猜你喜欢
      • 2012-11-22
      • 1970-01-01
      • 2019-03-30
      • 1970-01-01
      • 1970-01-01
      • 2013-07-14
      • 2018-08-15
      • 1970-01-01
      • 2018-04-22
      相关资源
      最近更新 更多