How do I force Git to use LF instead of CR+LF under Windows?
Asked Answered
P

7

616

I want to force Git to check out files under Windows using just LF not CR+LF.
I checked the two configuration options, but was not able to find the right combination of settings.

I want to convert all files to have LF line breaks and keep the LF in the files.

Remark: I used autocrlf = input but this just repairs the files when you commit them.
I want to force it to get them using LF.

Probably I wasn't so clear: the repository is already using LF but the files checked out using Git for Windows are using CR+LF and I want to force Git to get them with LF: forcing Unix line endings.

$ git config --list | grep crlf
core.autocrlf=input
Popple answered 25/3, 2010 at 16:7 Comment(10)
autocrlf=input is the correct option. Of course it doesn't protect you from files that genuinely have cr+lf in the repository or creating files with cr+lf in another tool before adding them to git. What problems are you having that this doesn't work for?Ansley
The files in the repository are already using only LF but when I get them under Windows msysgit converts them to CR+LF.Popple
There must be something up with your config; I've just tested this on my msysgit install. With autocrlf set to input, git is leaving lf linefeeds alone. Can you post the output of git config?Ansley
Please post the output of git config --list | grep crlfRuthi
In that case, I suggest that you log a bug; preferably pointing to a test repository that exhibits your problem and including steps to reproduce as the behaviour you are seeing is definitely wrong (but I can't reproduce it).Ansley
A small tip is to also make sure you are running the git commands on the 'git' you think you are. For example you may have git installed on windows, and git installed on cygwin, so make sure you have set the right git config.Two
It may seem unrelated first, but the resolution of this issue may also solve any DoE (denial of execution) of shell scripts introduced by a provisioner "file" and executed by a provisioner "remote-exec" block in a terraform apply run from Windows 10, that should be executing on a Linux-based machine image. It was my case at least. 4 hours spent on this.Anstice
Does this answer your question? How to change line-ending settingsFears
Not an option, I don't have control over anyone's local git setup. How can this be done in the repo itself?Forgetmenot
Compare with What's the strategy for handling CRLF (carriage return, line feed) with Git?. Also compare with the recommendation suggested in this answer explaining the purpose of text=auto in the .gitattributes file.Laryngo
P
750

The proper way to get LF endings in Windows is to first set core.autocrlf to false:

git config --global core.autocrlf false

You need to do this if you are using msysgit, because it sets it to true in its system settings.

Now git won’t do any line ending normalization. If you want files you check in to be normalized, do this: Set text=auto in your .gitattributes for all files:

* text=auto

And set core.eol to lf:

git config --global core.eol lf

Now you can also switch single repos to crlf (in the working directory!) by running

git config core.eol crlf

After you have done the configuration, you might want git to normalize all the files in the repo:

git add --update --renormalize

If you now want git to also normalize the files in your working directory, run these commands:

git ls-files -z | xargs -0 rm
git checkout .
Paratuberculosis answered 31/10, 2012 at 8:38 Comment(12)
I'm getting fatal pathspec '' did not match any files, right after git diff --cached --name-only -z | xargs -0 git addChitin
what is the output of git diff --cached --name-only?Paratuberculosis
It may be worth mentioning that you can set this config while cloning the repo in question, e.g. git clone --config core.autocrlf=false <repo path>.Birdella
I landed this answer because my WebStorm/PHPStorm converted line endings from LF to CRLF every time I click git "Rollback..." on a file. After this action all the file was red because ESLint underlines every line because of incorrect ending. Couple of commands solved my problem: git config --global core.autocrlf false and git config --global core.eol lf. Thanks!Paganism
Git now marks some files as changed, even though all that's changed are the line separators. How do I get rid of that?Myelencephalon
Did you normalize the files in the repository? When you change the line ending normalization, you need to normalize the repo contents with a commit.Paratuberculosis
First I set autocrlf false using command git config --global core.autocrlf false then after git config --global core.eol lf and also for local using command git config core.eol lf. After that, I set hard reset git reset --hard, and its fixed my problem.Horrific
What the bottom commands do: first remove all files from git (but actually keep them!) git rm --cached -rf . then show only names of files that changed (the ones you removed) -z: null-terminate | add them (-0: null-terminated) git diff --cached --name-only -z | xargs -0 git add -f <- This makes sure your git history is nice and LF. null-terminated allows for weird things in filenames.Unpractical
Then, you remove all files from the working directory (xargs executes the rm command on all of the outputs of ls-files): git ls-files -z | xargs -0 rm and check out the working tree (so restore the actual files to your staged changes). It works! Also don't run the commands in the blocks separately, or you may lose uncommited changes :)Unpractical
Again, no control over user's local git settings. How can the repo simply force all line endings to LF instead of CRLF? * text=auto does not work.Forgetmenot
Concerning * text=auto, I think it's worth considering the recommendation suggested in this answer explaining the purpose of text=auto in the .gitattributes file.Laryngo
As of git 2.16, you can run git add --renormalize /path/to/file to change the endings in the index, rather than removing the entire cacheTichon
H
442

I come back to this question fairly often, though none of its other answers are quite right for me.
That said, the right answer for me is a mixture of the others.

What I find works is the following:

git config --global core.eol lf
git config --global core.autocrlf input

For repos (Git repositories) that were checked out after those global settings were set, everything will be checked out as whatever it is in the repo – hopefully LF (\n).
Any CRLF will be converted to just LF on check-in (commit).

With an existing repo that you have already checked out – that has the correct line endings in the repo but not your working copy – you can run the following commands to fix it:

git rm -rf --cached .
git reset --hard HEAD

This will delete (rm) recursively (-r) without prompt (-f), all files except those that you have edited (--cached), from the current directory (.). The reset then returns all those files to a state where they have their true line endings (matching what's in the repo).

If you need to fix the line endings of files in a repo, I recommend grabbing an editor that will let you do that in bulk like IntelliJ or Sublime Text, but I'm sure any good one will likely support this.

Holotype answered 29/10, 2015 at 21:24 Comment(8)
We have a single repo with sub directories that require different line ending handling. So setting a global option does not work for this. Not even in the single repo. How do you apply these same settings in .gitattributes?Brookite
Notepad++ also shows the line ending of the currenlty opened file in the bottom right corner. A right click on that field will allow you to change the line endings.Lennielenno
The core.autocrlf input option overrides the core.eol setting, so setting both is redundant. (See git-scm.com/docs/git-config)Lynnelynnea
Thank you, with your help I have conquered lint and Linux. And can now check in files.Buenabuenaventura
I think the author set core.eol because in some cases some editors or other applications may override core.autocrlf value, so this setting is used as a backup.Psychochemical
Jesus Christ, those commands just destoyed my changes. Thanks a lot.Figured
Definitely commit all work before doing any sort of gitfu. This answer is also almost a decade old, and I have no clue if it still works.Holotype
CAUTION!!! Do not use this command if you have uncommited changes in your working tree! Else, all these changes will be lost.Studio
F
191

The OP added in his question:

the files checked out using msysgit are using CR+LF and I want to force msysgit to get them with LF

A first simple step would still be in a .gitattributes file:

# 2010
*.txt -crlf

# 2020
*.txt text eol=lf 

(as noted in the comments by grandchild, referring to .gitattributes End-of-line conversion), to avoid any CRLF conversion for files with correct eol.

And I have always recommended git config --global core.autocrlf false to disable any conversion (which would apply to all versioned files)

See Best practices for cross platform git config?

Since Git 2.16 (Q1 2018), you can use git add --renormalize . to apply those .gitattributes settings immediately.


But a second more powerful step involves a gitattribute filter driver and add a smudge step

filter driver

Whenever you would update your working tree, a script could, only for the files you have specified in the .gitattributes, force the LF eol and any other formatting option you want to enforce.
If the "clear" script doesn't do anything, you will have (after commit) transformed your files, applying exactly the format you need them to follow.

Flag answered 25/3, 2010 at 16:37 Comment(6)
One question: *.txt refers to all files with .txt extension or to all text files (non binary)? I cannot make a list with all kinds of file extension I will have in the project.Popple
@Sorin: all files with .txt extension. It is preferable to first establish this and test it on a specific group, before generalizing to *, and add a negative rule !*.xyz ... to exclude some few files from that rule.Flag
By now the .gitattributes lines should read: *.txt text eol=lf as per git-scm.com/docs/gitattributesColcannon
@Colcannon Thank you. I have included your comment in the answer for more visibility.Flag
I guess after we add .gitattributes we have to do git add --renormalize .Principal
@shuva Yes, but only since Git 2.16: https://mcmap.net/q/11222/-git-how-to-renormalize-line-endings-in-all-files-in-all-revisionsFlag
B
140

Context

If you

  1. want to force all users to have LF line endings for text files and
  2. you cannot ensure that all users change their git config,

you can do that starting with git 2.10. 2.10 or later is required, because 2.10 fixed the behavior of text=auto together with eol=lf. Source.

Solution

Put a .gitattributes file in the root of your git repository having following contents:

* text=auto eol=lf

Commit it.

Optional tweaks

You can also add an .editorconfig in the root of your repository to ensure that modern tooling creates new files with the desired line endings.

# EditorConfig is awesome: http://EditorConfig.org

# top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file
[*]
end_of_line = lf
insert_final_newline = true
Borer answered 9/2, 2017 at 11:52 Comment(5)
This was the best solution for me. I also combined this with editorconfig.org so that when writing in Intellij I would write out LF EOLs.Flatter
This is by far the best solution. No need to manually run any configuration commands!Hooked
This single line .gitattributes entry is the best, other solutions can be confusing.Goatsucker
What if I want to be able to retain line endings exactly as in the repository, whatever they are? I'm on Windows, but I use various different repositories, all of which might have their own conventions. I simply want to say "Github, don't mess with the line endings. Leave them exactly as in the repo when I check out, and exactly as in my code when I check in." Then I can tell my editor not to mess with the line endings either, and everyone's happy.Granitite
As I read it, setting git config --global core.autocrlf false gets Windows confused; setting git config --global core.autocrlf true means files will always be checked out with CRLF and checked in with LF, and setting * text=auto in .gitattributes seems to make no difference on my setup.Granitite
K
35

core.autocrlf=input is the right setting for what you want, but you might have to do a git update-index --refresh and/or a git reset --hard for the change to take effect.

With core.autocrlf set to input, git will not apply newline-conversion on check-out (so if you have LF in the repo, you'll get LF), but it will make sure that in case you mess up and introduce some CRLFs in the working copy somehow, they won't make their way into the repo.

Korry answered 1/4, 2010 at 0:23 Comment(1)
The commands should be git rm --cached -r . && git reset --hardBorer
P
1

You can find the solution to this problem at: https://help.github.com/en/github/using-git/configuring-git-to-handle-line-endings

Simplified description of how you can solve this problem on windows:

Global settings for line endings The git config core.autocrlf command is used to change how Git handles line endings. It takes a single argument.

On Windows, you simply pass true to the configuration. For example: C:>git config --global core.autocrlf true

Good luck, I hope I helped.

Praefect answered 26/3, 2020 at 20:54 Comment(1)
I am finding that on Windows, I can run git add --renormalize . at any time and it will accept all current file line endings.Keble
P
1

The accepted answer is correct

git config --global core.autocrlf false

For anyone coming here just to learn - one very helpful thing to keep in mind is that modern IDEs can render files with LF or CRLF. So imagine you're a lone windows dev on a team of macOS users. You'll be checking out a codebase that's likely ending in LF. The command above ensures that upon checkout, you don't mess up the LF characters.

In your IDE, for example in JetBrains, you should set the project (or globally) to use LF.

1. CTRL + ALT + S for settings
2. Code Style -> General -> Line Separator

enter image description here

Furthermore, in the bottom righthand IDE toolbar, it will display either LF or CRLF, which indicates the setting of the current file. You can click it to change between styles.

enter image description here

So in summary

  1. git config --global core.autocrlf false to avoid changing line endings on checkout.

    • Set this before repo checkout!
  2. IDE setting to avoid changing them on subsequent edits or on new file creation.

Proton answered 26/3 at 20:17 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.