Fixing the Line-Endings in a Git Repository Using the '.Gitattributes' File

.gitattributes file not converting line endings

Git conversions happen to the destination of whatever operation you're performing, and you can have different ones on the way into and out of the repo. Here you're telling it to convert text eol's both ways but haven't actually pulled any content from the repo yet. Do a git reset --hard to force a refresh of your current worktree from the committed content using any new filters/attributes.
Since git 2.16 you can also use

git add --renormalize .

It might be a bit counterintuitive that text attribute processing governs what happens on the way into the repo, and core.eol governs what happens on the way out:

text
This attribute enables and controls end-of-line normalization. When a text file is normalized, its line endings are converted to LF in the repository. To control what line ending style is used in the working directory, use the eol attribute for a single file and the core.eol configuration variable for all text files.

Can I use Git to bulk-change line endings after updating gitattributes?

You could remove them and then run git checkout -- blah.sh to get it back.

gitattribute end of line setting

A good source for .gitattributes info are the gitscm.com docs (https://git-scm.com/docs/gitattributes#__code_text_code)

  1. I do not believe * text eol=crlf will work. It should be * text crlf

  2. You need to break the single line * text eol=lf*.java eol=crlf*.csv eol=crlf*.jar binary*.sql eol=crlf into the multiple lines.

Add these lines to your . gitattributes file.

# other files will have LF
* text=lf

# .java .csv .jar .sql will have CRLF
*.java eol=lf
*.csv eol=crlf
*.jar eol=crlf
*.sql eol=crlf

Fixing the line-endings in a Git repository using the `.gitattributes` file

Try just using

*.md text eol=native

instead of

*.md text

in your .gitattributes.

I did set up a small test repo with a CR-LF file in it and followed your first procedure to perform normalization:

git rm --cached -r .
git reset --hard
git add .
git commit -m "Normalize line endings"

That correctly normalized file on check-in.
But, weirdly, it still maintained CR-LF when checking-out, even if I am on OSX.

Supposedly, default value for core.eol is native. So, I expected git to checkout my files using just LF. But it seems that for some reason, it's just not doing that.
So, my understanding of .gitattributes is flawed, or we have a bug to be filed to git...

In any case, explicitly setting eol=native in .gitattributes did the trick for me, as I said.

How can I use `LF` line endings in Git for Windows in 2020 for good?

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)



Related Topics



Leave a reply



Submit