在Windows上使用Git:crlf设置是什么意思?

82

我不理解与 git 相关的 CrLf 设置复杂性: core.autocrlfcore.safecrlf

我正在团队中开发一个跨平台项目,希望 Windows 和 Linux 开发人员能够一起工作,而不会因为行尾样式的不同而被 git 标记为已修改。

各种设置意味着什么?选择任何选项会有什么后果?对于我的情况,最好的解决方案是什么?

是的,我知道 这个问题,那里的答案并没有给出深入的见解,因此不太有用。


其他相关问题:https://dev59.com/Y3I-5IYBdhLWcg3wF0Uc和https://dev59.com/lHM_5IYBdhLWcg3wvF3J - Cascabel
自动crlf的副作用示例:https://dev59.com/hnI-5IYBdhLWcg3wF0Uc - VonC
1
只是为了让你感到更舒适:没有人完全做到 :) - eckes
3个回答

110

autocrlf有三个值:

  • true - 当内容进入仓库(提交)时,其换行符将被转换为LF,在内容从仓库中提取(检出)时,换行符将被转换为CRLF。这通常是为不熟悉的Windows用户/编辑器设计的。假设编辑器(或用户)将创建具有CRLF换行符的文件,并且如果看到普通的LF换行符,会感到困惑,但您希望在仓库中使用LF换行符,那么这将有所帮助。但可能会出现问题。有关于链接问题中的虚假合并冲突和修改文件的报告。

  • input - 当内容进入仓库时,其换行符将被转换为LF,但内容在提取时不会更改。这基本上与true在同一领域,但假设编辑器实际上可以正确处理LF换行符;您只是防止意外创建具有CRLF换行符的文件。

  • false - git根本不处理换行符。这取决于你。这是许多人推荐的。使用此设置时,如果文件的换行符将被破坏,您必须了解它,因此合并冲突的可能性要小得多(假设用户有知识)。教育开发人员如何使用他们的编辑器/IDE可以解决这个问题。我看到的所有为程序员设计的编辑器都能够正确处理此设置,如果进行适当配置。

请注意,autocrlf 不会影响存储库中已经存在的内容。如果您之前提交了带有 CRLF 结尾的内容,则它们将保持不变。这是避免依赖 autocrlf 的一个非常好的理由;如果某个用户没有设置它,他们可以将具有 CRLF 结尾的内容放入存储库中,并且它将一直存在。更强制规范化的方法是使用 text 属性;为给定路径设置为 auto 将标记它以进行行尾规范化,假设 git 决定内容是文本(而不是二进制)。
另一个相关选项是safecrlf,它基本上只是一种确保不对二进制文件进行不可逆的 CRLF 转换的方法。
我没有处理 Windows 问题和 git 的丰富经验,因此有关影响/陷阱的反馈肯定是受欢迎的。

感谢您提供清晰详细的答案!以下是我的几个问题:1)text attr是否属于repo?如果新程序员克隆它,他会收到attr吗?2)了解换行符样式的动机是什么?3)假设没有一个,根据您的解释,我应该a)设置autocrlf=true b)在repo的根路径上设置text attr=auto,c)设置safecrlf=??4)如果我设置autocrlf=input,并使用未正确配置的IDE“touch”文件(可能将LF更改为CRLF),那么git会将该文件视为已修改吗? - Jonathan Livni
1
@Jonathan:(1)请查看链接的gitattributes手册。属性是在.gitattributes文件中配置的,可以像任何其他文件一样进行跟踪。(2)将IDE配置为生成正确类型的输出只需要一次,并且这是绝对必要的——一致的缩进、间距和格式化怎么办?意识到这一点意味着没有惊喜。(3a,b)将文本属性设置为“auto”对于所有内容来说应该会使autocrlf设置变得不必要,除非有人选择了一个编辑器(记事本?)无法处理LF。这是一种更安全的方法。 - Cascabel
@Jonathan:(3c)在任何具有跟踪二进制文件和某种行结束转换的存储库中启用safecrlf可能是一个好主意。(4)我认为,在这种情况下,您不应该看到修改-但我已经看到很多人提到虚假的修改文件指示。 - Cascabel
在阅读了您在SA上的链接后,我发现很多人建议将autocrlf设置为false。从您最初的回答中,我认为您也倾向于将autocrlf设置为false。我猜我需要配置我的IDE并理解正在发生的事情,并使用在线工具将所有当前文件转换为LF格式... - Jonathan Livni
@Jonathan:在线吗?dos2unix(在某些系统中打包为fromdos)是标准的方法。如果您想尝试规范化行尾,我真的不建议使用autocrlf;文本gitattribute是更干净的方法,并且我相信它在最近的git版本中得到了改进。 - Cascabel
比《Pro Git》书更好的解释,请参见http://git-scm.com/book/ch7-1.html#Formatting-and-Whitespace。谢谢! - Drew LeSueur

13

我探索了三种可能的提交和检出情况,这是得出的表格:

╔═══════════════╦══════════════╦══════════════╦══════════════╗
║ core.autocrlf ║     false    ║     input    ║     true     ║
╠═══════════════╬══════════════╬══════════════╬══════════════╣
║   git commit  ║ LF => LF     ║ LF => LF     ║ LF => LF     ║
║               ║ CR => CR     ║ CR => CR     ║ CR => CR     ║
║               ║ CRLF => CRLF ║ CRLF => LF   ║ CRLF => LF   ║
╠═══════════════╬══════════════╬══════════════╬══════════════╣
║  git checkout ║ LF => LF     ║ LF => LF     ║ LF => CRLF   ║
║               ║ CR => CR     ║ CR => CR     ║ CR => CR     ║
║               ║ CRLF => CRLF ║ CRLF => CRLF ║ CRLF => CRLF ║
╚═══════════════╩══════════════╩══════════════╩══════════════╝

我建议在所有平台上使用core.autocrlf = input。这样,如果Git遇到CRLF,它将自动将其转换为LF,而现有的带有LF的文件则保持原样。


2
你在Windows电脑还是Unix电脑上进行这些实验的? - Edward Falk
1
@EdwardFalk,core.autocrlf的行为不取决于操作系统类型。但如果我没记错,在Windows上的默认值是true,而在Linux上则是input。还有一件可能会导致问题的事情是,大多数Windows上的IDE默认配置为使用CRLF来创建新文件,而在Linux上则是LF。 - pratt
我认为你在inputtrue之间搞反了。Srikanth Popuri下面的表格看起来对我来说是正确的。 - Gandalf Saxe
@GandalfSaxe 看起来你是对的。让我来修复它。 - pratt

4

顺便说一下,Windows默认的换行符是CRLF,Linux默认的是LF。请查看下面的表格以更清楚地理解。

╔═══════════════╦══════════════╦══════════════╦══════════════╗
║ core.autocrlf ║    false     ║    input     ║    true      ║
║               ║ Win => Unix  ║ Win => Unix  ║ Win => Unix  ║
╠═══════════════╬══════════════╬══════════════╬══════════════╣
║   git commit  ║ LF => LF     ║ LF => LF     ║ LF => LF     ║
║               ║ CR => CR     ║ CR => CR     ║ CR => CR     ║
║               ║ CRLF => CRLF ║ *CRLF => LF  ║ *CRLF => LF  ║
╠═══════════════╬══════════════╬══════════════╬══════════════╣
║  git checkout ║ LF => LF     ║ LF => LF     ║ *LF => CRLF  ║
║               ║ CR => CR     ║ CR => CR     ║ CR => CR     ║
║               ║ CRLF => CRLF ║ CRLF => CRLF ║ CRLF => CRLF ║
╚═══════════════╩══════════════╩══════════════╩══════════════╝

在上面的表格信息中,符号*突出了Windows和Unix之间的差异。以下是基于操作系统平台的CLRF信息:

对于Windows用户

  • 如果Windows用户与跨平台项目一起工作,则必须在Windows机器上设置core.autocrlf=true,在Unix机器上设置core.autocrlf=input
  • 如果Windows用户仅使用Windows项目,则可以同时设置core.autocrlf=truecore.autocrlf=false。但在这种情况下,设置core.autocrlf=input会导致问题。

对于Unix用户(Linux / Mac OS)

  • 如果Unix用户与跨平台项目一起工作,则必须在Windows机器上设置core.autocrlf=true,在Unix机器上设置core.autocrlf=input
  • 如果Unix用户仅使用Unix项目,则可以同时设置core.autocrlf=inputcore.autocrlf=false。但在这种情况下,设置core.autocrlf=true会导致问题。

对于相同操作系统的用户

  • 对于纯Windows项目或纯Unix项目,可以设置core.autocrlf=false

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