当做git diff时,它说文件末尾没有换行符;。
git diff
这条信息的意义是什么,它想告诉我们什么?
它只是指出文件的末尾没有换行符。这不是一个灾难,这只是一个信息,让它更清楚地表明,在查看命令行中的差异时,不存在差异。
它表示在文件末尾没有换行符(通常是\n,也就是LF或CRLF)。
\n
也就是说,简单地说,文件中的最后一个字节(如果在Windows系统中,则为字节)不是换行符。
之所以显示此消息,是因为没有办法区分末尾有换行符和没有换行符的文件。Diff无论如何都必须输出换行符,否则结果将难以读取或自动处理。
注意,在文本文件中,如果文件格式允许,总是将换行符作为最后一个字符是一种很好的风格。此外,例如,对于C和c++头文件,它是语言标准所要求的。
如果您在现有文件的末尾添加一行新的文本,而该文件的末尾还没有newline character,那么差异将显示旧的最后一行已被修改,即使在概念上它并没有被修改。
newline character
这至少是在结尾添加newline character的一个很好的理由。
文件包含:
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
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。事实上,这是发生的事情,但不是从概念上讲发生的事情,所以它可能会令人困惑。
}
}\n
这实际上会导致一个问题,因为行结束符会自动修改,而不会对文件进行任何更改。请参阅这篇文章以获得解决方案。
git用CRLF替换LF
这不仅仅是糟糕的样式,还可能导致在文件上使用其他工具时出现意想不到的行为。
这是test.txt:
test.txt
first line second line
最后一行没有换行符。让我们看看文件中有多少行:
$ wc -l test.txt 1 test.txt
也许这就是您想要的,但在大多数情况下,您可能希望文件中有2行。
此外,如果你想合并文件,它可能不会像你期望的那样表现:
$ cat test.txt test.txt first line second linefirst line second line
最后,如果你要添加一个新的行,它会使你的差异稍微更嘈杂。如果您添加了第三行,它将显示对第二行以及新添加的内容的编辑。
您的原始文件可能没有换行符。
然而,一些编辑器,如linux中的中用户,会在文件末尾无声地添加换行符。在使用这种编辑器时,您无法删除此消息。
我试图克服这个问题的是用Visual studio代码编辑器打开文件
这个编辑器清楚地显示了最后一行,您可以根据需要删除该行。
不管怎样,当我在Mac上创建IntelliJ项目,然后将该项目转移到Windows机器上时,我遇到了这种情况。我必须手动打开每个文件,并更改IntelliJ窗口右下方的编码设置。可能不会发生在大多数读到这个问题的人身上,但这可以节省我几个小时的工作时间……
唯一的原因是Unix在历史上有一个约定,所有人类可读的文本文件都以换行符结束。在当时,这避免了在显示或连接文本文件时进行额外的处理,并避免了将文本文件与包含其他类型数据的文件区别对待(例如原始二进制数据,它不是人类可读的)。
由于这种惯例,那个时代的许多工具都期望结尾换行符,包括文本编辑器、差分工具和其他文本处理工具。Mac OS X是建立在BSD Unix上的,而Linux是为了与Unix兼容而开发的,所以这两个操作系统继承了相同的惯例、行为和工具。
Windows并不是为了与unix兼容而开发的,所以它没有相同的约定,大多数Windows软件都可以很好地处理没有末尾换行符的情况。
但是,由于Git首先是为Linux开发的,而许多开源软件是建立在unix兼容的系统上,如Linux、Mac OS X、FreeBSD等,大多数开源社区及其工具(包括编程语言)继续遵循这些惯例。
在1971年,有一些技术上的原因是合理的,但在这个时代,它主要是为了保持与现有工具的兼容性。
源文件通常由工具连接(C, c++:头文件,Javascript:捆绑器)。如果省略换行符,可能会引入令人讨厌的错误(一个源文件的最后一行与下一个源文件的第一行相连)。希望所有的源代码连接工具都在连接文件之间插入换行符,但情况并非总是如此。
问题的关键在于——在大多数语言中,换行符具有语义意义,而文件结束符并不是语言定义的换行符的替代品。因此,您应该用换行符结束每个语句/表达式——包括最后一个。
有一件事我在之前的回答中没有看到。关于没有行尾的警告可能是在文件的一部分被截断时发出的警告。这可能是数据丢失的症状。
之所以采用这种惯例,是因为在类unix操作系统上,换行符被视为行结束符和/或消息边界(这包括进程之间的管道、行缓冲等)。
例如,考虑将只有换行符的文件视为单个空行。相反,长度为0字节的文件实际上是一个没有任何行的空文件。可以通过wc -l命令确认。
wc -l
总的来说,这种行为是合理的,因为如果\n字符只是行分隔符而不是行结束符,那么就没有其他方法来区分空文本文件和只有一行空的文本文件了。因此,有效的文本文件应该总是以换行符结束。唯一的例外是文本文件是空的(没有行)。
ubuntu$> vi source.cpp :set binary noeol
当做git差异时,它会说“文件末尾没有换行符”。
在某些方面,是的,但它更微妙和微妙。
当执行git diff时,git会显示文件版本之间的差异,显示为文件不同的块。这可能包括文件末尾的块。
如果文件的两个版本都没有以换行符结束,则读取数据块的末尾
\ No newline at the end of file
而如果只有一个版本不以换行符结束,则数据块将以任意一个版本结束
-last line \ No newline at the end of file +new last line
或
-last line +new last line \ No newline at the end of file
这条消息的意义是什么
原因很简单。git diff的主要目的之一是显示变化,明确地说,这样它就可以用作输入到git apply。要做到这一点,Git需要知道在应用diff时应该如何处理换行符。它应该移除、保留还是改变它们?
git apply
\ No newline at the end of file就是这样做的一种方式。对于希望了解此类更改的人来说,这也很有帮助,因为在某些情况下,是否有换行符对文件很重要。
它想告诉我们什么?
好吧,只是在这个文件的末尾没有换行符。或者以前没有,现在有了。或者曾经有过,但现在没有了。