Avoid “No newline at end of file” in git diff

Avoid “No newline at end of file” in git diff



I'm quite sure I understand what No newline at end of file means. I want to provide a pull request of a branch which I created long time ago and rebased (commits might be from the time before .gitattributes has been added). I see that some .java source code files have only the change


.gitattributes


.java


-}
No newline at end of file
+}



regardless of the configuration, I'd simply like these changes to be excluded from the PR commit. I'd like to avoid picking the changes with git difftool and broaden my understanding of git.


git difftool


git



The thing is that I already don't understand how this change can exist since there's a .gitattributes with


.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



in the repository and I ran git rm --cached -r . && git add . which should convert all line endings to LF because of *.java text (also tried *.java text), but there're no changes shown (against HEAD) and git diff still shows the line ending difference.


git rm --cached -r . && git add .


*.java text


*.java text


HEAD


git diff



Also find ./ -type f -name '*.java' -exec dos2unix ; doesn't causes any changes to be recognized by git status and git diff master still displays the line ending change (while the working directory has no staged or unstaged changes).


find ./ -type f -name '*.java' -exec dos2unix ;


git status


git diff master



I'm not interested in hiding the changes, like git diff --ignore-all-space would do.


git diff --ignore-all-space



I'm using git 2.17.1 on Ubuntu 18.04.


git




1 Answer
1



The thing is that I already don't understand how this change can exist ...



The change shows that the a/ version of the whatever.java file is missing a newline, while the b/ version of the file has one. "Missing a newline" means that the file ends with no line terminator—it's not a question of CRLF vs LF, it's a question of "has terminator" vs "does not have terminator".


a/


whatever.java


b/



Some editors are capable of handling files that have a final line that lacks a terminator. Other editors are not and don't even notice that there is one missing (mostly just pretending there was one). Some editors will default to adding a terminator if it seems appropriate, perhaps with a warning. There is a lot of variation here.



You don't show what particular git diff command (with what options) generated the diff, so it's hard to say where the a/ and b/ versions came from, but I'll assume HEAD commit and either-index-or-work-tree below. (That is, we're looking at trimmed git diff --cached or git diff HEAD output. Either way we'll see the same thing since git diff has to run the work-tree file through any clean filter and any end-of-line filtering.)


git diff


a/


b/


HEAD


index


git diff --cached


git diff HEAD


git diff


clean



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


.gitattributes


*.java text



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


git rm --cached -r . && git add .



This will convert any existing CRLF line endings in the work-tree to LF-only line endings in the index. I do not believe it will an add LF-ending to lines that have no ending at all (based on the code in crlf_to_git in convert.c).


crlf_to_git


convert.c



So, that suggests that your work-tree copy of the file has a final CRLF as the last two bytes of the file, or a final LF-only newline byte as the last single byte of the file. Git would git add that as a final newline. Meanwhile, if the commit itself has a lone close-curly brace (with no line endings at all, neither CRLF nor newlne) as its final byte, that means that the committed (HEAD) copy of the file differs from the index version of the same file by having the committed copy lack any line terminator at all, and you'd see just what you do see.


git add


HEAD






By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)