git 文件末尾没有换行符

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/5813311/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 10:48:09  来源:igfitidea点击:

No newline at end of file

gitgit-svn

提问by Pacerier

When doing a git diffit says "No newline at end of file".

执行 a 时,git diff它会显示“文件末尾没有换行符”

Ok, there is no newline at end of file. What's the big deal?

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

What's the significance of the message and what's it trying to tell us?

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

采纳答案by Alexander Gladysh

It indicates that you do not have a newline (usually '\n', aka CR or CRLF) at the end of file.

它表示您'\n'在文件末尾没有换行符(通常,又名 CR 或 CRLF)。

That is, simply speaking, the last byte (or bytes if you're on Windows) in the file is not a newline.

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

The message is displayed because otherwise there is no way to tell the difference between a file where there is a newline at the end and one where is not. Diff has to output a newline anyway, or the result would be harder to read or process automatically.

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

Note that it is a good style to always put the newline as a last character if it is allowed by the file format. Furthermore, for example, for C and C++ header files it is required by the language standard.

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

回答by Dean

It's not just bad style, it can lead to unexpected behavior when using other tools on the file.

这不仅仅是糟糕的风格,它可能会导致在文件上使用其他工具时出现意外行为。

Here is test.txt:

这是test.txt

first line
second line

There is no newline character on the last line. Let's see how many lines are in the file:

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

$ wc -l test.txt
1 test.txt

Maybe that's what you want, but in most cases you'd probably expect there to be 2 lines in the file.

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

Also, if you wanted to combine files it may not behave the way you'd expect:

此外,如果您想合并文件,它可能不会像您期望的那样运行:

$ cat test.txt test.txt
first line
second linefirst line
second line

Finally, it would make your diffs slightly more noisy if you were to add a new line. If you added a third line, it would show an edit to the second line as well as the new addition.

最后,如果您要添加新行,它会使您的差异变得更加嘈杂。如果您添加了第三行,它将显示对第二行的编辑以及新添加的内容。

回答by Nathan Craike

The only reason is that Unix historically had a convention of all human-readable text files ending in a newline. At the time, this avoided extra processing when displaying or joining text files, and avoided treating text files differently to files containing other kinds of data (eg raw binary data which isn't human-readable).

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

Because of this convention, many tools from that era expect the ending newline, including text editors, diffing tools, and other text processing tools. Mac OS X was built on BSD Unix, and Linux was developed to be Unix-compatible, so both operating systems have inherited the same convention, behaviour and tools.

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

Windows wasn't developed to be Unix-compatible, so it doesn't have the same convention, and most Windows software will deal just fine with no trailing newline.

Windows 不是为了与 Unix 兼容而开发的,因此它没有相同的约定,并且大多数 Windows 软件都可以很好地处理,没有尾随换行符。

But, since Git was developed for Linux first, and a lot of open-source software is built on Unix-compatible systems like Linux, Mac OS X, FreeBSD, etc, most open-source communities and their tools (including programming languages) continue to follow these conventions.

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

There are technical reasons which made sense in 1971, but in this era it's mostly convention and maintaining compatibility with existing tools.

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

回答by Jaseem

If you add a new line of textat the end of the existing file which does not already have a newline characterat the end, the diff will show the old last line as having been modified, even though conceptually it wasn't.

如果您在现有文件的末尾添加一行新的文本,而该文本的末尾还没有newline character,则差异将显示旧的最后一行已被修改,即使从概念上讲它没有。

This is at least one good reason to add a newline characterat the end.

这至少是newline character在末尾添加 a 的一个很好的理由。

Example

例子

A file contains:

一个文件包含:

A() {
    // do something
}

Hexdump:

十六进制转储:

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

You now edit it to

您现在将其编辑为

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..

The git diff will show:

git diff 将显示:

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

In other words, it shows a larger diff than conceptually occurred. It shows that you deleted the line }and added the line }\n. This is, in fact, what happened, but it's not what conceptuallyhappened, so it can be confusing.

换句话说,它显示出比概念上出现的更大的差异。它表明您删除了该行}并添加了该行}\n。事实上,这就是发生的事情,但这不是概念上发生的事情,因此可能会令人困惑。

回答by JohnD

It just indicates that the end of the file doesn't have a newline. It's not a catastrophe it's just a message to make it clearer that there isn't one when looking at a diff in the command line.

它只是表明文件的末尾没有换行符。这不是一场灾难,它只是一条消息,让您在查看命令行中的差异时更清楚地表明没有灾难。

回答by Leslie Krause

The reason this convention came into practice is because on UNIX-like operating systems a newline character is treated as a line terminator and/or message boundary (this includes piping between processes, line buffering, etc.).

这个约定付诸实践的原因是因为在类 UNIX 操作系统上,换行符被视为行终止符和/或消息边界(这包括进程之间的管道、行缓冲等)。

Consider, for example, that a file with just a newline character is treated as a single, empty line. Conversely, a file with a length of zero bytes is actually an empty file with zero lines. This can be confirmed according to the wc -lcommand.

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

Altogether, this behavior is reasonable because there would be no other way to distinguish between an empty text file versus a text file with a single empty line if the \ncharacter was merely a line-separator rather than a line-terminator. Thus, valid text files should always end with a newline character. The only exception is if the text file is intended to be empty (no lines).

总而言之,这种行为是合理的,因为如果\n字符只是行分隔符而不是行终止符,则没有其他方法可以区分空文本文件与具有单个空行的文本文件。因此,有效的文本文件应始终以换行符结尾。唯一的例外是文本文件是否为空(无行)。

回答by user34660

There is one thing that I don't see in previous responses. Warning about no end-of-line could be a warning when a portion of a file has been truncated. It could be a symptom of missing data.

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

回答by mmcorrelo

The core problem is what you define line and whether end-on-line character sequence is part of the line or not. UNIX-based editors (such as VIM) or tools (such as Git) use EOL character sequence as line terminator, therefore it's a part of the line. It's similar to use of semicolon (;) in C and Pascal. In C semicolon terminates statements, in Pascal it separates them.

核心问题是你定义什么行,行尾字符序列是否是行的一部分。基于 UNIX 的编辑器(如 VIM)或工具(如 Git)使用 EOL 字符序列作为行终止符,因此它是行的一部分。它类似于在 C 和 Pascal 中使用分号 (;)。在 C 中分号终止语句,在 Pascal 中它分隔它们。

回答by Brian Blum

This actually does cause a problem because line endings are automatically modified dirtying files without making any changes to them. See this post for resolution.

这实际上确实会导致问题,因为行结尾会自动修改脏文件而不对其进行任何更改。请参阅此帖子以获取解决方案。

git replacing LF with CRLF

git 用 CRLF 替换 LF

回答by Doug Coburn

Source files are often concatenated by tools (C, C++: header files, Javascript: bundlers). If you omit the newline character, you could introduce nasty bugs (where the last line of one source is concatenated with the first line of the next source file). Hopefully all the source code concat tools out there insert a newline between concatenated files anyway but that doesn't always seem to be the case.

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

The crux of the issue is - in most languages, newlines have semantic meaning and end-of-file is not a language defined alternative for the newline character. So you ought to terminate every statement/expression with a newline character -- including the last one.

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