Does this project use CRLF or LF as line endings?
I am confused about the line endings. I’ve been running into problems where when I try to merge upstream changes locally, they show up as “entire file has changed”, which is problematic since I can’t tell what actually changed.
So I’ve looked at a diff now, and it seems that is because all of the line endings changed. I assume that must be because git or vscode default to LF now and will replace line endings so that you end up with LF in the remote. And I just use the default config so I think my line endings must have been replaced to LF, but then that means this project would be using CRLF as line endings, is that correct?
Comments (10)
-
reporter -
- changed status to open
-
repo owner Since I’m only using Windows these days, I have not given a thought about line endings. I don’t see any problems with using LF consistently,
I added a .gitattributes files at the repo root, with the content
* text=auto * text eol=lf
but that doesn’t seem to change existing files. I cloned the repo to a new place but the file endings don’t seem to have changed; some files use LF and some CRLF. What am I missing here?
-
repo owner The .gitattributes file does something, because I got an error when trying to commit a file with CRLF endings. I manually changed the endings of the python files in the main directory, but have not changed file in subdirectories yet.
-
reporter Using
* text=auto
should make sure that when people clone, they get the default behaviour for text files [1], which is it should checkout with whatever line ending they need on their operating system. This should help when people use git without settingautocrlf
[2] totrue
, and it seems the default is indeedfalse
. It also should produce a warning that CRLF will get converted to LF, which I think you’re already seen. I thought this only applies on checkout, but seems this is wrong and it also makes sure that when you push files the line endings are replaced with LF [3], 4]The other line should not be needed, but will make it so when you checkout you get LF line endings. Right now I am not sure I would add that actually since the
* text=auto
line should work fine if I understand the docs correctly. I actually had a whole section here about settingautocrlf
totrue
, but it seems with* text=auto
that should not be needed (you can still check if its set tofalse
, that would explain why the files seem to be CRLF in the repo, might be easier to just set it totrue
globally if you don’t want to deal with line endings nonsense, that will always replace the line endings, but only for you, not other people).You may try to change the line endings in the entire project once, and then commit that as one big change so that you’re sure the remote has LF endings. With the .gitattributes present in the repo (or autocrlf set to
true
), you can just renormalize all line endings with:git add --renormalize .
[5], that should replace all remaining CRLF line endings with LF, and stage all files that changed. You can then just check withgit status
what would change, and if nothing changes then I think you already have LF line endings in the remote and don’t need to do anything.But a disclaimer: I find these line endings shenanigans with git very confusing. It tries to help but I find it makes it difficult to tell what exactly is going on. So I never really know. Maybe the problem is on my side actually.
[2] https://stackoverflow.com/questions/4181870/git-on-windows-what-do-the-crlf-settings-mean
[3] https://www.git-scm.com/docs/gitattributes
[4] https://stackoverflow.com/questions/30669292/at-what-point-will-gitattribute-eol-settings-be-run
-
reporter Yeah, I just merged again and I think you definitely need to remove the
* text eol=lf
line, that is just forcing all files to be treated as text with LF line endings. When I try to rungit add --renormalize .
it replaces line endings in the *.png files too for example.EDIT: One trick to check line endings is to use gnu find + file + grep to check. All of which should be installed when you have the git command line installed, I think I renamed find.exe (in c:/Program Files/Git/usr/bin/) to gfind.exe to make it work in all windows shells. Otherwise you can use it from the git command line only I think.
→ whereis grep grep: /usr/bin/grep.exe /c/Program Files/Git/usr/bin/grep.exe /usr/share/man/man1/grep.1.gz /usr/share/info/grep.info.gz → whereis gfind gfind: /c/Program Files/Git/usr/bin/gfind.exe → whereis file file: /usr/bin/file.exe /usr/share/file /c/Program Files/Git/usr/bin/file.exe /usr/share/man/man1/file.1.gz /usr/share/man/mann/file.n.gz → gfind . -iname "\*.py" -not -type d -exec file "{}" ";" | grep "with LF"
when you call
file
on a path it will output the file type, and its line ending type:→ file node.py node.py: Python script, ASCII text executable, with CRLF line terminators
This is CRLF, which is correct, since I am on windows and removed the
* text eol=lf
line.So I think you should remove it too, and then you should be good.
You already did a commit which replaced all the line endings in the entire project, so from now the git default behaviour should make it so everyone gets the line ending that fit their operating system (if you remove the
* text eol=lf
line), and everything that is pushed to the repo will have LF line endings. -
repo owner If I understand you right, changing .gitattributes to
* text=auto eol=lf
should do the trick. Done now.
-
reporter Just
* text=auto
should be enough, this will ensure files in the repo are LF, while making it so on Windows people get CRLF on checkout, and on Linux people get LF on checkout.With
* text=auto eol=lf
thetext=auto
still behaves the same, forcing LF in the repo, but it also forces line endings to be LF on checkout, so both Windows and Linux get LF with that.Apparently there was also a bug around this so it wouldn’t work as expected.
https://stackoverflow.com/questions/29435156/what-will-text-auto-eol-lf-in-gitattributes-do
-
repo owner OK, I changed .gitattributes again.
-
- changed status to resolved
- Log in to comment
I actually suggest switching to LF, but if you want to keep using CRLF, then I would add a .gitattributes file that enforces that:
I have been trying to fix the issue locally and its surprisingly difficult, which is why I would suggest just using LF and be done with it. But that .gitattributes file seems to fix the problem for me.
Though I am still not entirely sure if the project really does use CRLF or its somehow some configuration issue on my end. The automatic line ending replacement by git does not make it easier since I am never 100% sure if I am looking at the actual repo state or the git-replaced-the-line-endings-for-me state.
EDIT: I think the .gitattributes doesn’t actually help, this only makes it so files that are checked out have the line endings set to CRLF. So people using Linux will probably hate it.
My problem is that I have a fork that I push to, then git will by default replace CRLF → LF, and then when I merge changes into my fork I get a huge change that for the entire file because of that. I now manually replaced all files I have locally that had LF as line endings with CRLF, and then pushed those to my fork. Hopefully that resolve the issue for me.
I still think you should switch to LF, most people will just expect that and it matches the default behaviour of git. If you don’t do that I think you have to tell people to use
git config core.autocrlf false
when working on the source.