Git CRLF下线转换设置

Git CRLF下线转换设置,git,emacs,core.autocrlf,Git,Emacs,Core.autocrlf,平台:Windows 8.1 Emacs 24.3 git config-global-l显示: Git repository.gittributes文件: 我认为我的Git和存储库设置是正确的 但是每次我用Emacs创建一个新的文本文件时,我都不能运行git add。该文件由utf-8-unix编码 错误消息如下所示: E:\workspace\repository [master +0 ~2 -0]> git add . fatal: LF would be replaced by C

平台:Windows 8.1 Emacs 24.3

git config-global-l显示:

Git repository.gittributes文件:

我认为我的Git和存储库设置是正确的

但是每次我用Emacs创建一个新的文本文件时,我都不能运行git add。该文件由utf-8-unix编码

错误消息如下所示:

E:\workspace\repository [master +0 ~2 -0]> git add .
fatal: LF would be replaced by CRLF in newfile.txt
我不认为这是由于emacs编辑器的问题。因为我打开了新文件,并且非常确定行尾不是windows默认的CRLF

哪个配置部件决定用CRLF替换LF

编辑1 如果safecrlf设置为警告,则输出为:

warning: LF will be replaced by CRLF in _posts/2014-11-19-test.md.
The file will have its original line endings in your working directory.
这意味着该文件已成功添加到索引中。我的文件由utf-8-unix编码

编辑2

有趣的是,如果我用记事本而不是Emacs24.3创建了一个新文件,那么可以毫无问题地添加该文件。区别在于记事本采用CRLF行结尾,而Emacs 24.3采用LF行结尾

所以问题是Git在某种程度上将CRLF转换为LF,然后再转换回CRLF,这会为原始LF行结束文件生成错误

编辑3

以前,GitHub Windows GUI客户端警告我存储库中没有.gittributes文件,并建议使用默认的.gittributes文件,如上所述

我认为问题出在*text=auto这行。所以我把这一行注释掉

现在一切都好了

编辑4

其核心是:

通过GitHub禁用自动行结束转换

行尾依赖于平台文件编辑器

编辑5

文本 此属性启用并控制行结束标准化。规范化文本文件后,其行尾将在存储库中转换为LF。要控制工作目录中使用的行尾样式,请对单个文件使用eol属性,对所有文本文件使用core.eol配置变量。 在路径上设置“文本”属性可启用行尾规范化,并将路径标记为文本文件。行结束转换在不猜测内容类型的情况下进行。 取消设置路径上的文本属性告诉Git在签入或签出时不要尝试任何行尾转换。 当文本设置为“自动”时,路径将标记为自动行尾规范化。如果Git确定内容是文本,那么它的行尾在签入时被规范化为LF。 未指明。如果文本属性未由指定!文本或根本没有设置项,Git使用core.autocrlf配置变量来确定是否应转换文件,如EDIT 8中所述的向后兼容。 下线 此属性设置要在工作目录中使用的特定行尾样式。它可以在不进行任何内容检查的情况下实现行尾规范化,从而有效地设置文本属性。 也就是说eol自动设置文本属性。 设置为字符串值crlf 此设置强制Git在签入时规范化此文件的行尾,并在签出文件时将其转换为CRLF。 设置为字符串值lf 此设置强制Git在签入时将行尾标准化为LF,并防止在签出文件时转换为CRLF。 若eol放在.gittributes文件中,那个么它应该应用于特定的文件类型。同时,它会自动将特定文件类型标记为文本,以便在签入时进行LF规范化。如果将eol设置为git config-global core.eol xxx,则为所有文本文件设置eol

编辑6

Git属性在.gittributes文件中指定。行尾由文本和下线属性控制

text属性告诉Git文件是否为二进制文件,即签出和签入时不应执行EOL转换,或者text执行EOL转换,签入时始终转换为LF。可能的值设置为启用EOLs conversion(下线转换)、禁用unsetEOLs conversion(取消下线转换)、默认值和AUTO(自动)。如果检测到文件为二进制文件,则不进行转换,否则执行下线转换

eol属性:if set隐式设置文本属性并定义文件在签出时应转换为的eol

编辑7

可能的解决办法:

作为编辑3,注释掉*文本=自动 在.md文件的gitattributes中添加一行:*.md eol=lf 如果创建了另一种文本文件,如.txt,我还应该为它添加一行*.txt eol=lf 将*文本=自动更改为*!文本 完全删除.gittributes文件 就我目前所知,我认为:

通过gitattributes中的文件类型文本,在签入时对文件类型执行EOL规范化。 同时,此行暗示在签出时也应执行默认eol。默认意味着取决于git config-global core.eol xxx的全局配置或core.eol=native的默认操作系统样式。 您可以运行git config-global core.eol来查看在您的系统上该值设置为什么。如果没有返回任何内容,则表示您正在使用本机操作系统默认设置。 eol包含文本属性 但是,文本包含默认的eol属性。 因此,当启用*.md text=auto时。*。Git将md文件检测为文本文件,并在签入时将其转换为LF。签出时,*.md LF将转换为CRLF。safecrlf=false全局设置使此过程无效,拒绝将文件添加到索引/阶段区域。 编辑8

我在编辑7中的三个假设得到了验证

自Git 1.7.2及更高版本以来,EOL设置主要放在工作树的根目录中的.gittributes中。全局配置autocrlf仅用于后备兼容性

*.txt文本将与过滤器*.txt匹配的所有文件设置为文本。这意味着每次将这些文件写入对象数据库时,Git都会对其运行CRLF-to-LFreplacement,而在写入工作目录时,会运行反向替换

编辑9最后的想法

text和core.autocrlfin.gittributes重点关注从工作树写入存储库数据库的EOL转换。 eol和core.eolin全局配置侧重于从存储库数据库写入工作树的eol转换。 .gittributes在决定EOL转换时的优先级高于全局配置。后者实际上是回退引用。 如果指定了单向转换,则未指定或未定义另一种方式,则默认的回退选项将用于另一种方式转换。 下线问题与编辑文件时选择的行尾密切相关。 有关逻辑解释,请参阅我的博客

罪魁祸首是Git配置中的core.safecrlf=true

发件人:

可能的解决办法:

作为编辑3,注释掉*文本=自动 在.md文件的gitattributes中添加一行:*.md eol=lf 如果创建了另一种文本文件,如.txt,我还应该为它添加一行*.txt eol=lf 将*文本=自动更改为*!文本 完全删除.gittributes文件
“线端转换激活时”是条件。我已将“autocrlf”设置为“false”。所以我不认为这是因为“安全”哦,你是对的。好吧,只是为了笑一下,如果你把safecrlf改成false或warn会怎么样?输出是warning:LF将被_posts/new file.md中的CRLF替换。该文件将在您的工作目录中有其原始行结尾。啊!man gitattributes表示text=auto可确保Git认为是文本的所有文件在存储库中都有标准化的LF行结尾。编辑时请不要写“编辑”或“更新”之类的评论-每篇文章都有一个修订历史记录,显示每次编辑自动更改的内容,重复这一点毫无益处,并且使这个问题在将来阅读它的人看来真的很奇怪,这也是大多数观点的来源from@Flexo我应该在那里发表什么评论?因为每次我都只改变一点点。不容易描述。老实说,这没什么大不了的,比如“添加缺少的Foo”,但是如果你用一种假装从一开始就包含了所有信息的方式来写,那么这个问题会更好。
E:\workspace\repository [master +0 ~2 -0]> git add .
fatal: LF would be replaced by CRLF in newfile.txt
warning: LF will be replaced by CRLF in _posts/2014-11-19-test.md.
The file will have its original line endings in your working directory.
core.safecrlf
    If true, makes git check if converting CRLF is reversible when
    end-of-line conversion is active. Git will verify if a command
    modifies a file in the work tree either directly or indirectly. For
    example, committing a file followed by checking out the same file
    should yield the original file in the work tree. If this is not the
    case for the current setting of core.autocrlf, git will reject the
    file. The variable can be set to "warn", in which case git will only
    warn about an irreversible conversion but continue the operation.