关于git:文件末尾没有换行符

No newline at end of file

当执行git diff时,它会说"文件末尾没有换行符"。

好的,文件末尾没有换行符。有什么大不了的?

信息的意义是什么?它试图告诉我们什么?


它表示文件末尾没有换行符(通常是'
'
,也就是cr或crlf)。

也就是说,文件中的最后一个字节(如果在Windows上,则为字节)不是换行符。

显示该消息是因为,否则无法区分文件结尾有新行和没有新行的文件之间的区别。diff必须输出新行,否则结果将难以自动读取或处理。

请注意,如果文件格式允许,最好始终将换行符作为最后一个字符。此外,例如,对于C和C++头文件,它是由语言标准所要求的。


这不仅仅是不好的样式,它还可能导致在文件上使用其他工具时出现意外行为。

这是test.txt

1
2
first line
second line

最后一行没有换行符。让我们看看文件中有多少行:

1
2
$ wc -l test.txt
1 test.txt

也许这就是你想要的,但在大多数情况下,你可能期望文件中有2行。

此外,如果要合并文件,它可能不会按预期方式工作:

1
2
3
4
$ cat test.txt test.txt
first line
second linefirst line
second line

最后,如果您要添加一个新行,它会使您的差异稍微大一些。如果您添加了第三行,它将显示对第二行的编辑以及新添加内容。


它只是表示文件的结尾没有换行符。这不是一场灾难,它只是一个让人更清楚的信息,当在命令行中查看diff时,没有一个。


唯一的原因是,Unix历史上有一个所有人类可读的文本文件都以换行符结尾的约定。当时,这避免了在显示或连接文本文件时进行额外的处理,并避免了将文本文件与包含其他类型数据的文件(例如原始二进制数据,这是人类无法读取的)进行不同的处理。

由于这种惯例,那个时代的许多工具都期望换行结束,包括文本编辑器、差异化工具和其他文本处理工具。Mac OS X是在BSD Unix上构建的,Linux是为与Unix兼容而开发的,因此两个操作系统都继承了相同的约定、行为和工具。

Windows并没有开发成与Unix兼容,所以它没有相同的约定,而且大多数Windows软件都会处理得很好,没有后继的换行符。

但是,由于Git首先是为Linux开发的,并且许多开源软件都建立在与Unix兼容的系统上,如Linux、Mac OS X、FreeBSD等,因此大多数开源社区及其工具(包括编程语言)继续遵循这些约定。

有一些技术原因在1971年是有意义的,但在这个时代,它主要是传统的,并保持与现有工具的兼容性。


如果在现有文件的末尾添加了一行新行,而该新行在结尾处已经没有新行,那么在概念上不添加新行时,diff也会将旧的最后一行显示为已修改。

至少有一个很好的理由在末尾添加新行。


我在之前的回答中没有看到一件事。当文件的某个部分被截断时,有关行结尾的警告可能是一个警告。这可能是数据丢失的症状。


这种约定之所以生效是因为在类Unix操作系统上,换行符被视为行终止符和/或消息边界(这包括进程之间的管道、行缓冲等)。

例如,考虑只使用换行符的文件被视为单个空行。相反,长度为零字节的文件实际上是一个零行的空文件。这可以根据wc -l命令进行确认。

总之,这种行为是合理的,因为如果
字符只是一个行分隔符而不是行终止符,就没有其他方法来区分空文本文件和只有一个空行的文本文件。因此,有效的文本文件应该总是以换行符结尾。唯一的例外是文本文件是空的(没有行)。


核心问题是你定义了什么样的线,以及是否在线上结束。字符序列是否为行的一部分。基于Unix的编辑器(如vim)或工具(如git)使用eol字符序列作为行终止符,因此它是行的一部分。类似于在c和pascal中使用分号(;)。在C中分号终止语句,在pascal中它将它们分隔开。


源文件通常由工具(C,C++:头文件,JavaScript:捆绑器)级联。如果省略换行符,则可能会引入讨厌的错误(其中一个源的最后一行与下一个源文件的第一行连接)。希望所有的源代码concat工具都能在连接的文件之间插入新行,但情况并非总是如此。

问题的关键在于——在大多数语言中,换行符都具有语义意义,文件结尾不是换行符的语言定义替代项。所以您应该用换行符终止每个语句/表达式——包括最后一个。


这确实会造成问题,因为行尾会自动修改脏文件,而不会对其进行任何更改。请参阅此文章以获得解决方案。

Git用crlf替换lf


原始文件可能没有换行符。

然而,一些像Linux中的gedit这样的编辑器会在文件末尾悄悄地添加换行符。在使用此类编辑器时,无法删除此消息。

我试图克服这个问题的是用Visual Studio代码编辑器打开文件

此编辑器清楚地显示最后一行,您可以根据需要删除该行。


值得一提的是,当我在Mac上创建了一个Intellij项目,然后将该项目移到我的Windows计算机上时,我遇到了这个问题。我必须手动打开每个文件并更改Intellij窗口右下角的编码设置。如果有人读过这个问题的话,可能不会发生在大多数人身上,但这可以帮我节省几个小时的工作…