Mär*_*Mär 6 git line-endings core.autocrlf
在一个相对较大的项目中,使用签出CRLF和提交LF的策略。为此,我的系统使用:
git config --global core.autocrlf true
Run Code Online (Sandbox Code Playgroud)
但是,当提交文件(在本例中为.gitattributes文件)时,会返回警告:
LF would be replaced by CRLF in .gitattributes
Run Code Online (Sandbox Code Playgroud)
文件.gitattributes本身包含该行* text=auto !eol,并且文件本身使用 LF 行结尾。
为什么会发生这种情况?为什么 Git 告诉我要小心,因为它会将 LF 转换为 CRLF,即使我希望此文件在存储库中以 LF 结尾进行规范化?
我一定错过了一些完全明显的东西,因为我已经经历过:
还有更多,但这仍然没有像我想象的那样工作。
让我们分几个部分来看看:
\n\n!eol这里没有任何功能。这设置eol为unspecified,但这已经是默认值,并且未指定的值eol不会禁用 LF 到 CRLF 转换。
由于您确实指定了text=auto,Git 将检查 的内容是否.gitattributes显示为文本或二进制,当然它们应该显示为文本。
因此,这个特定条目告诉 Git 它应该在.gitattributes.
同时,认识到行结束变换是一般清理和涂抹过滤器概念的特例是有用的。 VonC 在您的第三个链接中接受的答案有一个很好的图画,说明了污迹过滤器的工作方式,但缺少说明清洁过滤器如何工作的图,所以让我们深入探讨这一点,并了解一些背景知识。
\n\nGit 的正常1 个原子存储单元是提交。提交保存源树的完整快照(加上我不会在此处介绍的提交元数据)。出于许多充分的原因,提交中的文件以压缩、冻结、只读和仅限 Git 的存储格式保存。我最近开始将这些文件称为“冻干”。这有助于将它们与您实际使用的文件区分开来。
\n\n与 Git 内部键值对象数据库中的所有内容一样,这些提交及其文件都是只读的。这意味着它们将永远保留(或者只要提交本身继续存在),这对于存档很有用,但对于完成任何新工作完全没有用。因此 Git 必须提供一种方法来“重新水化”文件,将它们变成可以使用的普通文件。
\n\n你的工作树是 Git 放置重新水化文件的地方。它们有普通的形式,在普通的文件中,用普通的名字。计算机上的每个程序都可以处理它们,并且您可以随心所欲地操纵它们。
\n\nGit可以停在这里:你将拥有冻结的提交文件和可延展的工作树文件,Git 将从工作树构建新的提交。Mercurial 在很多方面与 Git 非常相似,但也仅限于此。但 Git 并不止于此。相反,它继续在当前冻结的提交和工作树之间添加一个中介。这个中介就是 Git 的索引。Git 有时将其称为暂存区或缓存,具体取决于谁/Git 文档的哪一部分正在执行调用。不过,这三个都是同一实体的名称。
\n\n索引/暂存区域仅保存每个文件的额外副本。这个额外副本的格式是冻干的、内部的、仅限 Git 的存储格式。这种格式的文件会在具有相同文件的所有提交之间自动共享,因此这意味着当索引中的副本与任何提交中的副本相同时,它实际上与该提交共享。
\n\n这也意味着git commit,必须冻干每个文件才能永久存储它,实际上几乎是零工作:文件已经冻干了! 当您运行 时,冷冻干燥过程发生得较早git add。这就是 Git 速度提升的主要原因。这也是Git 一直要求您这样做的原因git add。2 请注意,这意味着当您运行时git commit,Git 甚至不需要查看您的工作树。 (不过,默认情况下它仍然会快速运行一半git status,为您的提交消息创建注释文本。)
1我在这里说正常是因为 Git 还通过所谓的blob对象提供对简单键值存储的低级访问。但是,要使用它,您必须诉诸于使用一些所谓的管道命令,而不是至少在理论上用户友好的命令。:-)
\n\n2 Mercurial 使用工作树作为建议的下一次提交,不需要您保留hg add文件。完成初始操作后hg add,系统会hg commit扫描您的工作树并提交您所做的任何更改。这对于新人来说就友好多了,但是这也意味着在一个大项目中,当你跑的时候hg commit,要做好等待的准备。
请记住,索引存储每个文件的冻干、Git 化副本。这意味着索引到工作树的“补充”步骤是进行任何您想要完成的转换的好地方。这就是链接答案中的污迹过滤器的用武之地:污迹过滤器可以修改提交的文本,以便工作树文本更有用。
\n\n同样,工作树到索引的“冷冻干燥”步骤\xe2\x80\x94(运行git add\xe2\x80\x94时发生的步骤)是进行任何你想要完成的转换的好地方。这就是干净过滤器的用武之地:干净过滤器可以删除不应该进入存储库中实际提交的内容。
Git 中的行结束转换只是 clean 和 smudge 过滤器的特例。冻干的存储库内文件可以具有您喜欢的任何行结尾。3例如 ,当我们让 Git 将文件从索引/暂存区域复制到工作树时git checkout,我们可以让 Git 将这些行结尾从仅 LF更改为 CRLF。当我们让 Git 将该文件从工作树复制到索引/暂存区域时,我们可以让 Git 将这些行结尾从 CRLF更改为仅 LF。
这是文本文件的默认 CRLF 转换。这些转换会将仅 LF 冻干文件更改为 CRLF 再水化文件,并将 CRLF 再水化文件更改为仅 LF 冻干文件。
\n\n只要 Git 检测到这可能会执行与已经执行的操作不同的操作,您就应该收到警告。.gitattributes因此,假设您的工作树中的文件现在只有 LF 行结尾。进一步假设提交和/或索引/暂存区域中的冻干副本也具有仅 LF 行结尾。假设指令说索引 -> 工作树应该将 LF-only 更改为 CRLF:那么,为什么有些东西很奇怪,Git 应该发出警告。
我发现这些警告有时有点令人兴奋。我无法将其归咎于特定 Git 版本中的特定情况,因为我自己尽最大努力永远不会让 Git 摆弄我的数据。我希望工作树副本每次都与冻干副本相匹配,因为我避免使用需要愚蠢的行结束特殊性的操作系统。但上面是一般规则,你现在收到的警告是有道理的:实际的冻干文件和工作树文件现在都只有 LF 行结尾,但你的设置告诉 Git 的文本应该有已转换为在工作树中具有 CRLF 行结尾。.gitattributes
3 Linus Torvalds 要求您应该喜欢仅 LF 的行结尾。:-) 开玩笑吧,Git 有点喜欢这个。如果您通过根本不启用 CRLF 或将所有文件标记为 来禁用所有转换\xe2\x80\x94 -text,Git 将永久存储\xe2\x80\x94!\xe2\x80\x94 无论您说什么行结尾。如果您随后改变主意,您将陷入已经冻结的行结尾,因为任何提交中的任何内容都无法更改。 如果这些提交是错误的,您唯一能做的就是停止使用它们。您可以创建新的、改进的、更正的并使用它们。
我认为正是这些“冻结提交的副本是错误的,因为它有 CRLF 结尾”的情况通常会触发虚假的 CRLF 行结尾警告问题。由于我自己实际上并没有使用行结束转换代码,因此很难确定这一点。
\n| 归档时间: |
|
| 查看次数: |
5104 次 |
| 最近记录: |