我有一个包含5个已使用CRLF提交的文件的存储库。我不知道这是怎么发生的,但是如果我使用这个命令就打扫干净就会打印出5个文件(数百个):
git grep -I --files-with-matches --perl-regexp '\r' HEAD
有谁知道如何重现此问题?换句话说,什么是可以导致这种情况的一组git设置?
答案 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。