Windows git "warning: LF will be replaced by CRLF", 这个警告是在提醒换行符会被替换成回车换行符,不是反向警告。

272

环境:

  • Windows 7
  • msysgit

当我执行 git commit 命令时,它提示:

warning: LF will be replaced by CRLF. 

这个警告是不是反过来了?
我在 Windows 上编辑文件时,行尾是 CRLF,就像这张图片一样:
enter image description here
而 Git 为了提交到仓库中将其改为了 LF
所以我认为正确的警告应该是:

warning: CRLF will be replaced by LF. 

还可以参考https://dev59.com/FnI-5IYBdhLWcg3w9tdw和https://dev59.com/12025IYBdhLWcg3wvIco。 - devnull
2
@devnull 我的意思是警告是反向的,对吧? - Honghe.Wu
@Honghe.Wu 不,它不在Windows上。我已经编辑了我的答案如下 - VonC
22
非常好的问题,因为警告似乎是反向的。在提交时收到关于转换为CRLF的警告非常令人困惑,即使解释Git对空格的处理也无济于事,因为这个警告是反向的 - Stijn de Witt
我在一个没有更改的文件中遇到了完全相同的警告,参见 https://dev59.com/PKLia4cB1Zd3GeqPfztQ#44458163。将这个特定的文件暂存后,警告和错误得到了解决。 - maxik
显示剩余3条评论
13个回答

357

警告:LF 将被替换为 CRLF。

根据您使用的编辑器,带有 LF 的文本文件不一定会保存为 CRLF:现代编辑器可以保留行尾样式。但是,该 git 配置设置坚持更改这些内容...

只需确保(如我在这里建议的):

git config --global core.autocrlf false

那样做可以避免自动转换,并且仍然可以通过 .gitattributes 文件core.eol 指令 来指定它们。

windows git "LF will be replaced by CRLF"

注意: 该警告消息已在 Git 2.37 (2022年第三季度) 中更改

这个警告信息是否反向了?

不是的:你正在使用 Windows,git config 帮助页面也确实提到了

如果您希望工作目录中具有 CRLF 行结尾,即使存储库没有归一化行结尾,请使用此设置。

如 "git replacing LF with CRLF" 所述,它应该只会在 checkout(检出)时(而不是提交时)发生,使用 core.autocrlf=true

       repo
    /        \ 
crlf->lf    lf->crlf 
 /              \    

正如 XiaoPenganswer 中提到的那样,该警告与以下内容相同:

警告:(如果您使用当前的 core.autocrlf 配置将其检出或克隆到另一个文件夹中),LF 将被 CRLF 替换
该文件在您(当前的)工作目录中保留其原始行尾。

git-for-windows/git issue 1242 所述:

我仍然认为这条消息很令人困惑,可以扩展消息以包括有关问题的更好解释,例如:“在删除文件并再次检出之后,LF 将被 CRLF 替换到 file.json 中”。

注意:Git 2.19(2018 年 9 月),当使用 core.autocrlf 时,虚假的“LF 将被替换为 CRLF”警告现已被取消显示


正如quaylar正确评论的那样,如果有转换提交,它只会转换为LF

那个具体的警告“LF将被CRLF替换”来自于convert.c#check_safe_crlf():

if (checksafe == SAFE_CRLF_WARN)
  warning("LF will be replaced by CRLF in %s.
           The file will have its original line endings 
           in your working directory.", path);
else /* i.e. SAFE_CRLF_FAIL */
  die("LF would be replaced by CRLF in %s", path);

这被称为 convert.c#crlf_to_git(),它本身被 convert.c#convert_to_git() 调用,后者被 convert.c#renormalize_buffer() 调用。

而最后一个 renormalize_buffer() 只被 merge-recursive.c#blob_unchanged() 调用。

所以我怀疑这种转换只会在 git commit 中发生,而且仅当该提交是合并过程的一部分时才会发生。


注意:从Git 2.17(2018年第二季度)开始,代码清理添加了一些解释。
请参见commit 8462ff4(2018年1月13日)由Torsten Bögershausen(tboegi完成。
(由Junio C Hamano -- gitster --合并于commit 9bc89b1,2018年2月13日)

convert_to_git(): safe_crlf/checksafe变成int conv_flags

When calling convert_to_git(), the checksafe parameter determines what to do if EOL conversion (CRLF --> LF --> CRLF) cannot be done properly. It also determines whether to renormalize line endings (CRLF --> LF) or keep them as is. checksafe is an enumeration type called safe_crlf and has several values.
SAFE_CRLF_FALSE:       do nothing in case of EOL roundtrip errors
SAFE_CRLF_FAIL:        die in case of EOL roundtrip errors
SAFE_CRLF_WARN:        print a warning in case of EOL roundtrip errors
SAFE_CRLF_RENORMALIZE: change CRLF to LF
SAFE_CRLF_KEEP_CRLF:   keep all line endings as they are

请注意,Git 2.17周期中引入的回归(8462ff4)在"convert_to_git()safe_crlf/checksafe 变为int conv_flags"(2018-01-13, Git 2.17.0),导致autocrlf重写生成警告消息,尽管设置了safecrlf=false

参见 commit 6cb0912(于2018年6月4日由Anthony Sottile (asottile)提交)。
(于2018年6月28日合并至commit 8063ff9,合并者为Junio C Hamano -- gitster --


1
是的,大多数编辑器都可以保留EOL样式,但对于大多数编辑器,在同一项目中创建新文件时,这没有任何影响。请确保您不要签出LF项目,认为“嘘,我的编辑器可以处理LF行结尾,我不需要autocrlf”,然后忘记手动将新文件设置为LF行结尾。 - user743382
18
@VonC,我必须承认我没看懂。Git-Book指出:"在提交时,Git可以通过将CRLF行尾转换为LF,并在从文件系统检出代码时相反地执行此操作来处理此问题"。这意味着在提交时会将行尾转换为LF而不是CRLF,也就是说,警告信息有误。在我的看法中,即使在非Windows情况下,设置core.autocrlf=true仍将始终导致存储库中产生LF,而工作树中产生CRLF。资料来源:链接 - quaylar
15
这个警告是反向的吗?它应该只会在结账时出现。但我在提交时看到了完全相同的警告。所以,是的,它是反向的。它的反向触发了我对此进行搜索。很高兴其他人也注意到了!对于实际阅读这些警告的人来说,看到它说它将转换为CRLF格式的提交消息非常令人困惑。 - Stijn de Witt
7
我怀疑这种转换只会在 Git 的合并过程中发生,但实际上它也可能出现在普通提交中。 - Stijn de Witt
5
让我感到困扰的是这个提示窗口的存在。为什么我需要被警告Git将要执行我已经配置好的操作呢?我不需要一个提示说“嘿,我们正在像你要求的那样继续转换行尾符号”。当系统按照设计行为时,它不应该给出不必要的警告,否则人们会在一大堆无关紧要的信息中错过重要的警告。 - Brent Larsen
显示剩余8条评论

50

是的,这个警告信息是反过来的。

实际上,它甚至不应该成为一个警告。因为所有这个警告信息(不幸的是反过来了)说的就是,你的Windows换行符文件中的CRLF字符在提交时将被替换为LF字符。这意味着它已经规范化到与*nix和MacOS使用的相同的换行符。

并没有什么奇怪的事情发生,这正是你通常想要的行为。

目前这个警告信息可能是以下两种情况之一:

  1. 不幸的错误加上过于谨慎的警告信息,或者
  2. 一个非常聪明的阴谋,让你更加深入地思考...

;)


1
奇怪的是,如果你强制将Windows上的本地文件转换为LF,甚至无法将文件添加到git中,会出现错误信息并取消你的提交。 - phpguru
*nix,我喜欢。 - jacktrader
不,不是这样的。它是在说你的工作树内容中有lf,而且你现在设置的仓库,当你再次检出该内容时,添加的lf将被替换为crlf。它可能解释得更好,但不能以不同的方式解释,工作树中的lf没有改变,仓库中的lf保持不变,唯一的变化将发生在未来,在检出时,lf将被替换为crlf。 - jthill

30

。它并不是在谈论你当前的文件使用CRLF。相反,它是在谈论使用LF的文件。

应该这样阅读:

警告:(如果你使用当前的core.autocrlf配置检出或克隆到另一个文件夹,)LF将被CRLF替换

该文件将保留其原始行结束符在你的(当前)工作目录中。

这张图片应该能解释它的意思。 enter image description here


对我而言,以下设置效果很好:1)core.autocrlf=false 2)在Intellij中设置行分隔符(\n)。我在Mac和Windows上都使用Intellij Idea。 - Devs love ZenUML
1
当文件在Windows中创建,但具有Unix/Mac行结尾(lf),且您的git配置属性autocrlf为true时,就会发生这种情况。基本上,git不会更改您创建的文件,但它将使用Windows行结尾(因为您的autocrlf设置)来检出/克隆它。 - Patrick
1
如果你必须通过“如果你检查它或者在另一个文件夹中克隆并使用当前的core.autocrlf配置”来限定警告,那么这个警告怎么能正确而准确呢?这不是原始信息所说的。它说它将被CRLF替换(而不是可能),这意味着它将以CRLF模式存储在仓库本身中,而不是在某个假设的未来检出中。 - mgiuca

20

以上所有内容均假设 core.autocrlf=true

原始错误:

警告:LF 将被替换为 CRLF
该文件将在您的工作目录中保留其原始行结尾。

错误应该是这样的:

警告:LF 将在您的工作目录中被替换为 CRLF (即本地文件将变为CRLF)
该文件将在Git仓库中保留其原始LF行结尾(即远程文件依然是LF)

解释可参考此处

方便的转换带来的副作用就是,如果您最初编写的文本文件使用的是LF行结尾而不是CRLF,那么它将像往常一样以LF形式存储,但是当以后进行检出时,它将具有CRLF行结尾。对于普通文本文件,这通常没什么问题。此警告仅为“供您参考”,但是如果Git错误地将二进制文件视为文本文件,则这是一个重要的警告,因为Git将破坏您的二进制文件。

基本上,以前LF行结尾的本地文件现在会在本地变成CRLF。


14

git config --global core.autocrlf false 用于全局设置效果很好。

但是,如果你使用的是Visual Studio,对于一些项目类型(例如c#类库应用程序),可能还需要修改.gitattributes文件:

  • 删除行* text=auto

1
希望这个回答能够在帖子中更靠前。我怀疑自从十年前发表最高赞的评论以来,大多数用户已经转向 vscode,使得这个解决方案更具相关性。 - Maile Cupo

10

这是因为在 Windows 上,GitHub Desktop 的配置假设使用 CRLF,但文本编辑器可能正在使用 LF。您可以更改本地仓库设置,以改用 lf

转到 git 仓库的根目录,并按照完全相同的顺序执行以下操作。

git config core.eol lf
git config core.autocrlf input

Source: GitHub issue


3
这个警告信息是否反向?该警告信息首先是令人困惑的。Git 2.37(2022年第三季度)对其进行了重新措辞和澄清。请参见 commit c970d30(由 Alex Henrie (alexhenrie) 于 2022 年 4 月 7 日提交)。(由 Junio C Hamano -- gitster -- 合并于 commit 0a88638,2022 年 5 月 20 日)

convert:澄清行尾转换警告。 签名:Alex Henrie。

The warning about converting line endings is extremely confusing.

LF will be replaced by CRLF in ...
The file will have its original line endings in your working directory.

Its two sentences each use the word "will" without specifying a timeframe, which makes it sound like both sentences are referring to the same timeframe.
On top of that, it uses the term "original line endings" without saying whether "original" means LF or CRLF.

Rephrase the warning to be clear about when the line endings will be changed and what they will be changed to.

在本机行尾符不是CRLF(例如Linux)的平台上,以下序列中的“git add(man)步骤会触发问题中的消息(不再有警告):
$ git config core.autocrlf true 
$ echo 'Hello world!' >hello.txt 
$ git add hello.txt 

In the working copy of 'hello.txt', CRLF will be replaced by LF 
the next time Git touches it.

在一个本地行结束符不是LF的平台上(例如Windows),以下步骤中的 "git add"(man) 触发了问题中的消息(不再是警告):
$ git config core.autocrlf true 
$ echo 'Hello world!' >hello.txt 
$ git add hello.txt 

In the working copy of 'hello.txt', LF will be replaced by CRLF 
the next time Git touches it.

3
我将core.autocrlf=true设置后,在Windows上编辑使用LF的存储库中的文件,在对其进行git add(或可能是在git commit时),我收到了“LF将被CRLF替换”(请注意,不是“CRLF将被LF替换”)的消息。 这是在我设置core.autocrlf=true之前检出的存储库中发生的。
我使用core.autocrlf=true进行新的检出,现在我不再收到这些消息。

0

请确保在.gitignore文件中添加了不必要的文件或文件夹。

e.g. node_modules

如果仍然遇到问题,请运行以下命令:
``git config --global core.autocrlf false```

0

我遇到了类似的问题,在Windows上使用vscode(v1.57)尝试了其他答案中定义的解决方案,但不起作用。

所以对我来说,以下步骤有效:

  1. 在根文件夹中有一个名为.editorconfig的文件
  2. 打开此文件并将end_of_line = lf更改为end_of_line = crlf
  3. 运行git rm --cached,警告即可消失!

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接