避免在git diff中出现"No newline at end of file"的情况

11

我非常确定我理解了文件末尾没有换行符的含义。我想提供一个拉取请求,这是我很久以前创建并重新定位的分支(提交可能来自于在添加.gitattributes之前的时间)。我发现一些.java源代码文件只有这种更改。

-}
\ No newline at end of file
+}

无论配置如何,我只想将这些更改从PR提交中排除。我想避免使用git difftool选择更改,并加深对git的理解。
问题在于,我已经不明白为什么会有这种变化,因为存在一个带有.gitattributes的文件。
# Set the default behavior, in case people don't have core.autocrlf set.
* text=auto

# Explicitly declare text files you want to always be normalized and converted
# to native line endings on checkout.
*.c text
*.h text
*.java text
*.css text
*.js text
*.xml text
*.dtd text
*.xsl text
*.properties text
*.txt text
*.svg text
*.yml text
*.md text

# Declare files that will always have CRLF line endings on checkout.
*.sln text eol=crlf

# Denote all files that are truly binary and should not be modified.
*.png binary
*.gif binary
*.jpg binary
*.jpeg binary
*.eot binary
*.ttf binary
*.woff binary
*.woff2 binary

在代码库中,我运行了git rm --cached -r . && git add .,这应该会将所有行结尾转换为LF,因为有*.java text(也尝试过*.java text),但是没有显示任何更改(与HEAD相比),并且git diff仍然显示行结束的差异。
此外,find ./ -type f -name '*.java' -exec dos2unix {} \;不会导致git status识别出任何更改,并且git diff master仍然显示行结束的变化(虽然工作目录没有已暂存或未暂存的更改)。
我不想隐藏更改,就像git diff --ignore-all-space所做的那样。
我正在Ubuntu 18.04上使用git 2.17.1。
2个回答

3
问题:文件结尾没有换行符。
$ git diff
diff --git a/abc.txt b/abc.txt
index 5996e61..6a3c3a9 100644
--- a/abc.txt
+++ b/abc.txt
{
+  **Actual change**
FR(srctxt,reptxt,fname)
else:
-    os._exit(1)
\ No newline at end of file
+    os._exit(1)

解决方案: 使用echo -n "删除最后一行的文本并在末尾添加相同的文本" >>abc.txt 命令,删除最后一行并将没有换行符的相同文本附加到文件的末尾。

$ **echo -n "    os._exit(1)" >> abc.txt**

$ **git diff**
diff --git a/abc.txt b/abc.txt
index 5996e61..f2b2e74 100644
--- a/abc.txt
+++ b/abc.txt
@@ -419,6 +419,7 @@ EStatus 
{
+  **Actual change**
FR(srctxt,reptxt,fname)

2
事实上,我已经不理解这个更改怎样存在了......
这个更改显示whatever.java文件的a/版本缺少一个换行符,而b/版本有一个。 "缺少一个换行符"意味着文件结尾没有任何行终止符——这不是CRLF与LF的问题,而是"有终止符"与"没有终止符"的问题。
一些编辑器能够处理最后一行缺少终止符的文件。其他编辑器则不能,并且甚至注意不到有终止符缺失(一般只是假装有)。一些编辑器会默认添加终止符,如果合适的话可能会附带警告。这里有很多变化。
您没有展示特定的git diff命令(以及选项)生成的差异,所以很难说a/b/版本来自哪里,但我将假设下面是HEAD提交和索引或工作树。(也就是说,我们正在查看被修剪过的git diff --cachedgit diff HEAD输出。无论哪种方式,我们都会看到同样的东西,因为git diff必须将工作树文件通过任何清洗过滤器和任何行尾过滤器)

... since there's a .gitattributes [that includes]

*.java text

... and I ran git rm --cached -r . && git add . which should convert all line endings to LF ...

这将把工作区中任何现有的CRLF行尾转换为索引中仅有的LF行尾。根据convert.c中的代码(crlf_to_git),我认为它不会在没有结尾的行上添加LF结尾。
因此,这意味着您的文件在工作区副本中具有最后两个字节的CRLF,或者具有最后一个单字节的LF行尾。Git会将其作为最终的换行符进行git add。同时,如果提交本身以一个孤立的右括号结尾(既没有CRLF也没有newline),那么这意味着提交(HEAD)中的文件副本与相同文件的索引版本之间的差异在于提交的副本完全缺少任何行结束符号,您将看到您所看到的内容。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接