平台:Windows 8.1 Emacs 24.3
git config --global -l
显示:
user.name=username
user.email=useremail
core.autocrlf=false
core.safecrlf=true
Git存储库.gitattributes
文件:
# Auto detect text files and perform LF normalization
* text=auto
# Custom for Visual Studio
*.cs diff=csharp
*.sln merge=union
*.csproj merge=union
*.vbproj merge=union
*.fsproj merge=union
*.dbproj merge=union
# Standard to msysgit
*.doc diff=astextplain
*.DOC diff=astextplain
*.docx diff=astextplain
*.DOCX diff=astextplain
*.dot diff=astextplain
*.DOT diff=astextplain
*.pdf diff=astextplain
*.PDF diff=astextplain
*.rtf diff=astextplain
*.RTF diff=astextplain
我认为我的Git和存储库设置是正确的。
但每次我使用Emacs创建一个新的文本文件时,我都无法运行git add <newfile>
。该文件由utf-8-unix
编码。
错误消息如下:
E:\workspace\repository [master +0 ~2 -0]> git add .
fatal: LF would be replaced by CRLF in newfile.txt
我不认为是由于emacs编辑器问题。因为我打开了新文件,并且非常确定行结尾是LF
,而不是Windows默认CRLF
。
哪个配置部分决定LF将被CRLF替换?
编辑1
如果safecrlf
设置为warn
,则输出为:
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
有趣的是,如果我用记事本而不是Emacs 24.3创建一个新文件,则可以毫无问题地添加该文件。区别在于记事本采用CRLF
行结束,而Emacs 24.3采用LF
行结束。
所以问题就在某处Git将CRLF
转换为LF
然后转回CRLF
,这会为原始LF
行结束文件生成错误。
编辑3
以前,GitHub Windows GUI客户端警告我没有.gitattributes
我的存储库文件,并建议如上所述的默认.gitattributes
文件。
我认为问题来自* text=auto
行。所以我评论了这一行。
现在一切都很好!
编辑4
核心是:
禁用自动线结束转换 。
依赖平台文件编辑器结束 。
编辑5
text
此属性启用并控制行尾标准化。对文本文件进行规范化后,其行结尾将转换为存储库中的LF
。要控制在工作目录中使用的行结尾样式,请使用eol
属性表示单个文件,并使用core.eol
配置变量对于所有文本文件。
text
属性可启用行尾标准化,并将路径标记为文本文件。行结束转换发生在而不猜测内容类型。text
属性会告知Git 在签入或结帐时不会尝试任何行尾转换。text
设置为&#34; auto
&#34;时,路径会标记为自动行结束规范化。如果 Git决定内容为文本,则其行结尾会在签入时标准化为 LF
。text
属性未指定(通过!text
或根本没有设置条目),Git使用core.autocrlf
配置变量来确定是否应该转换文件(如下所述的后备兼容性)在 编辑8 )。eol
此属性设置要在工作目录中使用的特定行结束样式。它可以在没有任何内容检查的情况下实现行尾标准化,有效地设置text
属性。
eol
会自动设置text
属性。如果eol
放在.gitattributes
文件中,则应将其应用于特定文件类型。同时,它会在签入时自动将特定文件类型标记为text
,以便进行LF规范化。如果将eol
设置为git config --global core.eol xxx
,则会为所有文本文件设置eol
。
请参阅gitattributes - defining attributes per path
编辑6
Git属性在.gitattributes
个文件中指定。行结尾由text
和eol
属性控制。
text
属性告诉Git文件是否为binary
(即在结帐时不应执行EOL
转换)或text
(执行EOL
转换,在检入时始终转换为LF
。设置了可能的值(EOLs转换已打开),未设置(EOLs转换已关闭,默认值)和auto
(如果文件被检测为二进制,无转换,否则执行EOL转换)。
eol
属性:如果设置隐式设置text
属性,则定义在签出时应将文件转换为的EOL。
请参阅Line endings handling in SVN, Git and SubGit
编辑7
可能的解决方案:
* text=auto
gitattributes
文件的.md
中添加一行:*.md eol=lf
.txt
,我还应为其添加一行*.txt eol=lf
* text=auto
更改为* !text
.gitattributes
文件据我所知,我认为:
filetype text
中gitattributes
,在签到时对filetype
执行EOL规范化。default eol
。 default
表示全局配置为git config --global core.eol xxx
或默认操作系统样式为core.eol = native
。
git config --global core.eol
以查看系统上此值的设置。如果没有任何反馈意味着您正在使用操作系统默认值native
。text
属性,而text
暗示默认eol
属性。*.md text=auto
时。 Git将*.md
文件检测为text
文件,并在签入时转换为LF。结账时,*.md
LF将转换为CRLF。此过程由safecrlf = false
全局设置无效,拒绝将文件添加到索引/阶段区域。编辑8
我在 编辑7 中的三个假设已经过验证Mind the End of Your Line
从Git 1.7.2及更高版本开始,EOL设置主要放在工作树根目录下的.gitattributes
中。全局配置autocrlf
仅用于后备兼容性。
*.txt text
将与过滤器*.txt
匹配的所有文件设置为text
。这意味着Git每次将这些文件写入对象数据库时都会对这些文件进行CRLF
到LF
替换,并且在写入工作目录时将运行反向替换
编辑9最终想法
text
和core.autocrlf
(在.gitattributes
中)专注于从工作树写入存储库数据库的EOL转换。eol
和core.eol
(在global config
中)专注于从存储库数据库写入工作树的EOL转换。.gitattributes
的优先级高于global config
。后者实际上是后备参考。有关合理解释,请参阅我的博客znhoo
答案 0 :(得分:0)
罪魁祸首是Git配置中的core.safecrlf=true
。
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.
答案 1 :(得分:0)
可能的解决方案:
* text=auto
gitattributes
文件的.md
中添加一行:*.md eol=lf
.txt
,我还应为其添加一行*.txt eol=lf
* text=auto
更改为* !text
.gitattributes
文件