8

Our repository uses LF, my Git for Windows installation uses Checkout as-is, commit Unix-style line endings,

enter image description here

but I still end up with wall of errors in every file I checkout in my IDE as it still receives CRLF all the time even though it does support LF and is configured to use LF via checked in .editorconfig file (or in its own settings).:

.editorconfig
root = true

[*]
end_of_line = lf

It is 2020 already and IDEs and tooling already support LF on Windows, so how can I have the nice things too?

Qwerty
  • 29,062
  • 22
  • 108
  • 136
  • Pls see [this answer](https://stackoverflow.com/a/59644154/3700414). With a 4th point added in your case : core.eol=lf. Try with a fresh repo before trying to clean messed repos. Important to emphasize: autocrlf should be false at all levels: system, global, repo – Rusi Jul 27 '20 at 07:01

2 Answers2

18

There are two git config attributes that affect the line endings: core.autocrlf and core.eol.
Previously, you were told to use core.autocrlf = true to be able to work on cross-platform projects, but it's not true any more.

If your system/IDE/tooling support LF and you do want to use LF as everyone else in your team without any silent lf->crlf->lf normalizations, you must turn off autocrlf and configure eol to not infer native line endings, but force it to use lf.

Now there are two ways to achieve LF in all your files a/o repos:

  1. Globally for all repositories on your local machine.
  2. Per-repository via checked-in .gitattributes file.
    This file overrides any local configuration for everyone who clones the repo.

I personally recommend to go with both for all local repos and to ensure cross-platform cross-dev consistency.


1) Globally for all repositories on your local machine

Being in your working directory (your local repo):

  1. First commit everything

  2. Let's be paranoid a bit and set it both globally and in repo as well. Just in case.

    git config --global core.eol lf
    git config --global core.autocrlf false
    
    git config core.eol lf
    git config core.autocrlf false
    
  3. Delete everything "code" except .git.
    You can also omit dependencies, installed files (such as node_modules), build files and any git-ignored file as well.

  4. and lastly run

    git reset --hard HEAD
    

Things should be working now. Newly checked files should follow the new configuration and keep whatever line-endings were cloned from the remote repo.

Note that if your remote repo uses mix of crlf lf endings, you will also have to run and push

git add --renormalize .

2) Per-repository via checked-in .gitattributes file

Being in your working directory (your local repo):

  1. Create .gitattributes file in the root with this content:

    * text=auto eol=lf
    
  2. Commit the file (and everything else)

  3. Same as above

  4. Same as above

IMPORTANT NOTE: After you introduce the file into the repository, it is necessary that everyone who still has old CRLF files does step 3 and 4 to update their working directory as just checking out the commit doesn't affect already existing files.

git reset hard


Notes

setting core.autocrlf to true or input overrides core.eol

https://www.git-scm.com/docs/git-config#Documentation/git-config.txt-coreautocrlf

core.autocrlf = input is the preferred value on unix systems. https://stackoverflow.com/a/41282375/985454
https://stackoverflow.com/a/4425433/985454

Troubleshooting

Reinstall git for windows with third option (as in the screenshot in Q)

Checkout as is - Commit as is (core.autocrlf = false)

Qwerty
  • 29,062
  • 22
  • 108
  • 136
2

The way to go is to use a .gitattributes with the good instruction to give to git.

See https://www.edwardthomson.com/blog/git_for_windows_line_endings.html

For your case, it should be: * text=auto eol=lf

.editorconfig is only for saving files for editors supporting it...

But after that, you will have to normalize the files:

git add --renormalize .

You could find this answer useful: https://stackoverflow.com/a/50645024/717372

Philippe
  • 28,207
  • 6
  • 54
  • 78
  • Actually I don't want `CRLF`. And yes, I am talking about IDE and tooling that supports `LF`, hence the `.editorconfig`. From what I have learned, `.gitattributes` can be quite complicated and you need to tweak certain extensions there. Anyway, to use `.gitattributes` you still need to make sure each dev's git installation is set properly and therefore I think the other solution is more straight forward and requires less work and further maintanance. – Qwerty Jun 25 '20 at 08:21
  • I mean, `.gitattributes` file works only if you also set `core.autocrlf = false`. But if you also set `core.eol = lf`, then the `.gitattributes` has implicitly value `* text=auto eol=lf` even if you don't create it IIUC. – Qwerty Jun 25 '20 at 08:33
  • Sorry, I forgot to edit the line to change to `LF` (edited now). And no `.editorconfig` is not the solution. And yes, `.gitattributes` is the good solution nowaday because it doesn't required that all devs have rightfully configured their git. Did you read the post from edward thomson? And no, you're solution is not the one more staright forward because some time to times a dev commit bad eol... – Philippe Jun 25 '20 at 08:34
  • 1
    No, `.gitattributes` overrides `core.autocrlf`, period. Get it right, check it in to your repository, and it doesn't matter what `core.autocrlf` or `core.eol` are set to. That's _the point_ of `.gitattributes`. – Edward Thomson Jun 25 '20 at 08:35
  • As I said in the Question, the repo uses `LF` already, I don't need to run normalization. Can you confirm that for `.gitattributes` to take effect, one must set their local git config to `core.autocrlf = false`? – Qwerty Jun 25 '20 at 08:36
  • 1
    No. `.gitattributes` overrides `core.autocrlf`, it doesn't matter what you have it set to. If you have a `.gitattributes` configured for a file, `core.autocrlf` will be ignored. – Edward Thomson Jun 25 '20 at 08:37
  • this is awesome! – Qwerty Jun 25 '20 at 08:39
  • I advise you to do the normalization. If all your files are good, you will have nothing to commit and it will be perfect. And you could also see the bad effects if you did something wrong. – Philippe Jun 25 '20 at 09:19
  • I have actually just tried your way with a fresh intall of Git for Windows with default `autocrlf=true` and it checked out the files with `CRLF` line endings and `git add --renormalize .` took several seconds but did nothing eventually. Note that I firste cloned the repo, then added `.gitattributes` file. Should it be done differently? Should I first push the file and clone again? – Qwerty Jun 25 '20 at 10:20
  • The solution was to delete everything and do a hard reset. I can imagine a fresh clone would also work. – Qwerty Jun 25 '20 at 11:26
  • That makes sense - you were (hopefully) already normalized since `core.autocrlf` indicates that files are CRLF in the working directory but go into the repository as LF. In your new setup, you want files as LF in the working directory _and_ the repository. So there's nothing to renormalize in your repository. Indeed a fresh checkout is all that's needed to update the on-disk files. – Edward Thomson Jun 25 '20 at 12:43