当执行git diff时,它会说"文件末尾没有换行符"。
好的,文件末尾没有换行符。有什么大不了的?
信息的意义是什么?它试图告诉我们什么?
- 也许,如果您有一个文件结尾没有换行符,并且您添加了另一行,那么git将不得不显示前一行的最后一行已经更改,因为它包含换行符作为行的一部分?
它表示文件末尾没有换行符(通常是'
',也就是cr或crlf)。
也就是说,文件中的最后一个字节(如果在Windows上,则为字节)不是换行符。
显示该消息是因为,否则无法区分文件结尾有新行和没有新行的文件之间的区别。diff必须输出新行,否则结果将难以自动读取或处理。
请注意,如果文件格式允许,最好始终将换行符作为最后一个字符。此外,例如,对于C和C++头文件,它是由语言标准所要求的。
- 出于好奇,你能解释为什么总是用换行符作为最后一个角色被认为是好的风格吗?编辑:找到此讨论。
- JAR文件的清单文件还需要在文件末尾添加新行。请参阅docs.oracle.com/javase/tutorial/deployment/jar/modman.html
- @Paulbellora从历史上看,这实际上是C语言标准stackoverflow.com/a/729725/233098做出的决定,因为许多Unix工具都需要或期望它能够正确显示stackoverflow.com/a/729795/233098。从哲学上讲,因为文本文件中的每一行都以"行尾"字符结尾——最后一行不应该是任何异常。从不同的角度考虑,让我们来探索相反的情况。如果有"行首"标记而不是"行尾",您会省略第一行的"行首"字符吗?
- @乔,这没什么意义。换行符是新行,即行与行之间的分隔符,而不是行尾。我们没有行首字符,因为它们不是必需的。由于同样的原因,我们没有行尾字符。
- @Acjay I认为,"行与行之间的分隔符"与"行的末尾"之间有着本质上更好的区别。这两种观点本质上都不是对的或错的,只是一种看待它的方式。我建议我们继续使用历史上可行的观点,因为我们已经这样做了,当你接受它的时候它确实是有意义的。一致性很重要。不需要以"行与行之间的分隔符"的名义来打破这个观点。
- @乔,如果这一切都是为了一致性,那么在文件末尾添加一行新行将是"新的"事情。我公司以前从来没有人听说过这种行为。我查找它的唯一原因是Github对它做了这么大的贡献。
- @wormss"对我来说是新的"和"一个新的约定"不一样,这就像发现任何其他类型的编程约定一样。你就这么做吧。你可能会偏离,但你只是孤立你自己。(或者在本例中,实际上是破坏工具。)想想有多少其他人发现了Rails约定或PEP8,以及这些社区作为一个整体是如何保持一致的,因为它们确实让步了——尽管编写了相反的代码。
- 我真的看不出添加任何多余的东西是如何"好的风格"。如果diff不能处理没有diff的文件,那么diff有问题。这些换行符很容易造成真正的问题。
- @托比伯,你有一个例子说明它可能导致的问题吗?
- @ SRICKS…一个wiki解释器将新行解释为文字新行并相应地呈现它们//想象一个建立在"wiki页面"上的模板系统,其中模板包含的每个模块在其末尾引入了一个讨厌的新行…每一个按钮,每一个工具栏,每一个侧边栏,每一个内容块//这样的wiki就是Tiddlywiki
- @Tobibeer使用了一个更好的wiki解释程序(假设的?)你用的那个很坏。
- @Pacerier"停止培养新一代的黑猩猩程序员",这对谈话毫无帮助。更糟糕的是,如果不给你5分钟,你也会有误导程序员的风险。除非你独自工作,否则骑自行车是个真正的问题。它会导致不必要的延迟,基本上没有。为了偏离而偏离是绝对有害的。
- 只是为了记录:C++不需要文件换行结束。2.2.2如果源文件不为空,且不以新行字符结尾,或在进行任何此类拼接之前以反斜杠字符开头的新行字符结尾,则应像附加新行字符一样对其进行处理。
- 看来vi对此也有意见……unix.stackexchange.com/questions/263869(它更喜欢它)。
这不仅仅是不好的样式,它还可能导致在文件上使用其他工具时出现意外行为。
这是test.txt:
最后一行没有换行符。让我们看看文件中有多少行:
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 |
最后,如果您要添加一个新行,它会使您的差异稍微大一些。如果您添加了第三行,它将显示对第二行的编辑以及新添加内容。
- cat的结果是正常的,但是wc参数"-l,-lines"是错误的。即使是手册上说的"打印新行计数",而不是"打印行计数"。
它只是表示文件的结尾没有换行符。这不是一场灾难,它只是一个让人更清楚的信息,当在命令行中查看diff时,没有一个。
唯一的原因是,Unix历史上有一个所有人类可读的文本文件都以换行符结尾的约定。当时,这避免了在显示或连接文本文件时进行额外的处理,并避免了将文本文件与包含其他类型数据的文件(例如原始二进制数据,这是人类无法读取的)进行不同的处理。
由于这种惯例,那个时代的许多工具都期望换行结束,包括文本编辑器、差异化工具和其他文本处理工具。Mac OS X是在BSD Unix上构建的,Linux是为与Unix兼容而开发的,因此两个操作系统都继承了相同的约定、行为和工具。
Windows并没有开发成与Unix兼容,所以它没有相同的约定,而且大多数Windows软件都会处理得很好,没有后继的换行符。
但是,由于Git首先是为Linux开发的,并且许多开源软件都建立在与Unix兼容的系统上,如Linux、Mac OS X、FreeBSD等,因此大多数开源社区及其工具(包括编程语言)继续遵循这些约定。
有一些技术原因在1971年是有意义的,但在这个时代,它主要是传统的,并保持与现有工具的兼容性。
如果在现有文件的末尾添加了一行新行,而该新行在结尾处已经没有新行,那么在概念上不添加新行时,diff也会将旧的最后一行显示为已修改。
至少有一个很好的理由在末尾添加新行。
- 我们可以在另一个方向上写同样的东西:如果您在现有文件的末尾删除了一行新行,而该新行在末尾已经有了新行,那么diff在概念上不显示新行时,也会将旧的最后一行显示为已修改。至少有一个很好的理由在末尾删除换行符。
- @gentiane您混淆了"新行"(新行)和"新行"(1或2个字符分隔行尾)
- @我不知道,Gentiane不知道。也许你只是不知道"新线"和"新线"是一样的。
- @不可信的是,这两个词在答案中的用法有着截然不同的含义。我不知道你是想成为一个聪明的人,还是只是误解了发生的事情。
我在之前的回答中没有看到一件事。当文件的某个部分被截断时,有关行结尾的警告可能是一个警告。这可能是数据丢失的症状。
- 总的来说,这是一个很好的观点,但我认为在这个特定问题的背景下,这是没有意义的。
- @CST1992 StackOverflow中的答案应该尽可能有用,这意味着它们应该适用于所有可能性。这个问题很简短,我不知道在哪里排除了我提出的可能性。
这种约定之所以生效是因为在类Unix操作系统上,换行符被视为行终止符和/或消息边界(这包括进程之间的管道、行缓冲等)。
例如,考虑只使用换行符的文件被视为单个空行。相反,长度为零字节的文件实际上是一个零行的空文件。这可以根据wc -l命令进行确认。
总之,这种行为是合理的,因为如果
字符只是一个行分隔符而不是行终止符,就没有其他方法来区分空文本文件和只有一个空行的文本文件。因此,有效的文本文件应该总是以换行符结尾。唯一的例外是文本文件是空的(没有行)。
- 为什么我被否决-2?我指出,不仅确认了其他答案(即基于Unix的标准工具希望换行符作为行的终止符),而且无法区分空文件和单个空行,这是绝对正确的。我特别回答了最初的问题"信息的意义是什么,它试图告诉我们什么?"
- 我没有投你反对票,但是这个响应似乎是针对Unix类型的系统的,因为它只适用于换行符只是换行符的情况。不清楚这在这里适用。另外,如果文件只包含一个空行,那么该警告似乎是无用的。然而,我避免堆积如山,因为人们常常在没有解释的情况下投反对票。
核心问题是你定义了什么样的线,以及是否在线上结束。字符序列是否为行的一部分。基于Unix的编辑器(如vim)或工具(如git)使用eol字符序列作为行终止符,因此它是行的一部分。类似于在c和pascal中使用分号(;)。在C中分号终止语句,在pascal中它将它们分隔开。
源文件通常由工具(C,C++:头文件,JavaScript:捆绑器)级联。如果省略换行符,则可能会引入讨厌的错误(其中一个源的最后一行与下一个源文件的第一行连接)。希望所有的源代码concat工具都能在连接的文件之间插入新行,但情况并非总是如此。
问题的关键在于——在大多数语言中,换行符都具有语义意义,文件结尾不是换行符的语言定义替代项。所以您应该用换行符终止每个语句/表达式——包括最后一个。
- 在C/C++中,你可以用一行写整个项目。不需要换行。
这确实会造成问题,因为行尾会自动修改脏文件,而不会对其进行任何更改。请参阅此文章以获得解决方案。
Git用crlf替换lf
原始文件可能没有换行符。
然而,一些像Linux中的gedit这样的编辑器会在文件末尾悄悄地添加换行符。在使用此类编辑器时,无法删除此消息。
我试图克服这个问题的是用Visual Studio代码编辑器打开文件
此编辑器清楚地显示最后一行,您可以根据需要删除该行。
值得一提的是,当我在Mac上创建了一个Intellij项目,然后将该项目移到我的Windows计算机上时,我遇到了这个问题。我必须手动打开每个文件并更改Intellij窗口右下角的编码设置。如果有人读过这个问题的话,可能不会发生在大多数人身上,但这可以帮我节省几个小时的工作…