当做一个git差异,它说“没有换行在文件末尾”。

这条信息的意义是什么,它想告诉我们什么?


当前回答

它表示在文件末尾没有换行符(通常是\n,也就是LF或CRLF)。

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

之所以显示此消息,是因为没有办法区分末尾有换行符和没有换行符的文件。Diff无论如何都必须输出换行符,否则结果将难以读取或自动处理。

注意,在文本文件中,如果文件格式允许,总是将换行符作为最后一个字符是一种很好的风格。此外,例如,对于C和c++头文件,它是语言标准所要求的。

其他回答

如果您在现有文件的末尾添加了新的文本行,而该文本行末尾还没有换行符,则diff将显示最后一行已被修改的旧文本行,尽管在概念上它并没有被修改。

这至少是在末尾添加换行符的一个好理由。

例子

文件包含:

A() {
    // do something
}

Hexdump:

00000000: 4128 2920 7b0a 2020 2020 2f2f 2064 6f20  A() {.    // do 
00000010: 736f 6d65 7468 696e 670a 7d              something.}

现在将其编辑为

A() {
    // do something
}
// Useful comment

Hexdump:

00000000: 4128 2920 7b0a 2020 2020 2f2f 2064 6f20  A() {.    // do 
00000010: 736f 6d65 7468 696e 670a 7d0a 2f2f 2055  something.}.// U
00000020: 7365 6675 6c20 636f 6d6d 656e 742e 0a    seful comment..

git差异将显示:

-}
\ No newline at end of file
+}
+// Useful comment.

换句话说,它显示了比概念上发生的更大的差异。它显示您删除了行}并添加了行}\n。这就是实际发生的情况,但不是概念上的情况,所以会让人困惑。

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

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

Windows并不是为了与unix兼容而开发的,所以它没有相同的约定,大多数Windows软件都可以很好地处理没有末尾换行符的情况。

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

在1971年,有一些技术上的原因是合理的,但在这个时代,它主要是为了保持与现有工具的兼容性。

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

然而,一些编辑器,如linux中的gedit,会在文件末尾无声地添加换行符。在使用这种编辑器时,您无法删除此消息。

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

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

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

问题的关键在于——在大多数语言中,换行符具有语义意义,而文件结束符并不是语言定义的换行符的替代品。因此,您应该用换行符结束每个语句/表达式——包括最后一个。

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