如何在git上使用CRLF提交文件?

时间:2017-10-11 18:50:03

标签: git gitattributes core.autocrlf

我有一个包含5个已使用CRLF提交的文件的存储库。我不知道这是怎么发生的,但是如果我使用这个命令就打扫干净就会打印出5个文件(数百个):

git grep -I --files-with-matches --perl-regexp '\r' HEAD

有谁知道如何重现此问题?换句话说,什么是可以导致这种情况的一组git设置?

2 个答案:

答案 0 :(得分:3)

在内部,Git只存储原始数据。如果你运行git hash-object -w,你可以将你喜欢的任何blob数据推送到存储库中(尽管你需要附加一个标记,或者将blob添加到索引中以将其存储到新的提交中)。

正如我在回答What does "check out code" mean in git documentation for line endings?时所提到的那样,Git会在您运行git add时启用此类翻译的任何文件上应用CRLF-to-LF-line-endings翻译在那个文件上。结果是索引中的文件版本(或更准确地说,索引中的blob哈希,表示in-repo blob对象)具有仅LF的行结尾。

如果您使用以下命令在该文件上运行git add

  • 全球禁用翻译,或
  • 在该特定路径名称上禁用的翻译

然后Git 将不会执行这些翻译,并且文件的索引版本将在工作树版本中具有任何'\r'个字符

.gitattributes和/或core.autocrlf中的设置控制是否启用翻译,如果启用,则控制要执行的翻译。由于历史设置(从Git什么都不做,从添加Windows支持的早期阶段,通过Git的各种中间版本到当前相当复杂的.gitattributes方法),所有这些的规则都是相当的复杂。

  

换句话说,什么是可以导致这种情况的一组git设置?

有许多不同的方法可以做到这一点,但到目前为止最简单的方法是编写一个.gitattributes文件,只需:

* -text

或将core.autocrlf设置为false(但请注意,.gitattributes一般会覆盖core.autocrlf。现在,Git会将所有文件视为二进制文件,在git add期间不进行“清理”,在git checkout期间不进行“涂抹”。现在,工作树内容将逐字节地匹配索引内容,除了您自己做出的任何更改,或者通过运行程序对工作树文件进行的更改。然后,您可以git add将这些新文件添加到索引中,然后逐字节地复制它们;并且您创建的每个新git commit将使用索引中的内容。

一旦您存储了永久和不可更改的提交,您关注的特定文件的特定版本,您可以修改.gitattributes以包含您要测试的任何其他设置,并运行git checkout <commit> -- <path>使Git将文件从提交,索引,污迹过滤器和工作树复制。您可以按照自己喜欢的方式修改任何工作树文件,然后运行git add <path>以通过清理过滤器运行文件以将其复制到索引中。这些过滤器将由运行命令时.gitattributes 中的任何内容控制,因此您可以尝试不同的属性,而无需进行新的提交。

答案 1 :(得分:0)

您可能正在使用git config --global core.autocrlf true

要获得更好的解释,请查看docs