587

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
Henke
  • 4,445
  • 3
  • 31
  • 44
sorin
  • 161,544
  • 178
  • 535
  • 806
  • 3
    `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? – CB Bailey Mar 25 '10 at 16:10
  • 5
    The files in the repository are already using only `LF` but when I get them under Windows msysgit converts them to `CR+LF`. – sorin Mar 25 '10 at 16:19
  • 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`? – CB Bailey Mar 25 '10 at 22:46
  • Please post the output of `git config --list | grep crlf` – hasen Mar 26 '10 at 07:10
  • 1
    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). – CB Bailey Mar 26 '10 at 11:14
  • 3
    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. – lfred Mar 26 '15 at 10:37
  • 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. – Fabien Haddadi Dec 29 '20 at 14:34
  • Does this answer your question? [How to change line-ending settings](https://stackoverflow.com/questions/10418975/how-to-change-line-ending-settings) – Aryan Beezadhur Oct 05 '21 at 20:44
  • Not an option, I don't have control over anyone's local git setup. How can this be done in the repo itself? – Peter Kionga-Kamau Oct 21 '22 at 16:30
  • Compare with [What's the strategy for handling CRLF (carriage return, line feed) with Git?](https://stackoverflow.com/q/170961). Also compare with [the recommendation suggested in this answer explaining the purpose of text=auto in the .gitattributes file](https://stackoverflow.com/a/38017715). – Henke Oct 26 '22 at 17:23

6 Answers6

714

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. To do this, go to to the root of your repo and run these commands:

git rm --cached -rf .
git diff --cached --name-only -z | xargs -n 50 -0 git add -f

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 .
Chronial
  • 66,706
  • 14
  • 93
  • 99
  • 4
    I'm getting fatal pathspec '' did not match any files, right after `git diff --cached --name-only -z | xargs -0 git add` – CMCDragonkai Mar 18 '14 at 16:58
  • 3
    what is the output of `git diff --cached --name-only`? – Chronial Mar 18 '14 at 22:29
  • 31
    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 `. – Chris Long Apr 01 '20 at 19:03
  • 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! – Eugene Karataev Dec 17 '20 at 03:37
  • you sir, are a genious – Omeriko Aug 27 '21 at 20:58
  • Git now marks some files as changed, even though all that's changed are the line separators. How do I get rid of that? – EzPizza Oct 19 '21 at 14:46
  • 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. – Chronial Oct 20 '21 at 08:07
  • 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. – Rashid Oct 25 '21 at 15:29
  • 2
    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. – Fee Aug 01 '22 at 10:42
  • 1
    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 :) – Fee Aug 01 '22 at 10:46
  • 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. – Peter Kionga-Kamau Oct 21 '22 at 16:32
  • 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](https://stackoverflow.com/a/38017715). – Henke Oct 26 '22 at 10:30
423

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.

Henke
  • 4,445
  • 3
  • 31
  • 44
Ben Liyanage
  • 4,993
  • 1
  • 21
  • 23
  • 2
    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? – RobG Feb 13 '16 at 18:43
  • `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. – winklerrr Jul 06 '18 at 12:02
  • 4
    The `core.autocrlf input` option overrides the `core.eol` setting, so setting both is redundant. (See https://www.git-scm.com/docs/git-config) – Andrew Marshall Jan 02 '20 at 13:27
  • 1
    Thank you, with your help I have conquered lint and Linux. And can now check in files. – GC_ Apr 04 '20 at 18:58
  • 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. – ttimasdf Jan 18 '22 at 13:54
  • Jesus Christ, those commands just destoyed my changes. Thanks a lot. – xpusostomos Jan 26 '22 at 09:04
  • 1
    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. – Ben Liyanage Mar 18 '22 at 20:31
  • CAUTION!!! Do not use this command if you have uncommited changes in your working tree! Else, all these changes will be lost. – Vasiliy Artamonov Nov 11 '22 at 17:08
184

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.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • 1
    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. – sorin Mar 26 '10 at 11:09
  • 2
    @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. – VonC Mar 26 '10 at 12:24
  • 2
    By now the `.gitattributes` lines should read: `*.txt text eol=lf` as per https://www.git-scm.com/docs/gitattributes – grandchild Jan 09 '20 at 16:41
  • @grandchild Thank you. I have included your comment in the answer for more visibility. – VonC Jan 09 '20 at 21:22
  • 1
    I guess after we add `.gitattributes` we have to do `git add --renormalize .` – KRoy May 25 '20 at 20:04
  • @shuva Yes, but only since Git 2.16: https://stackoverflow.com/a/47580886/6309 – VonC May 25 '20 at 20:26
133

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
koppor
  • 19,079
  • 15
  • 119
  • 161
  • 10
    This was the best solution for me. I also combined this with http://editorconfig.org so that when writing in Intellij I would write out LF EOLs. – Jazzepi Feb 08 '18 at 23:27
  • 2
    This is by far the best solution. No need to manually run any configuration commands! – Cameron Tacklind Feb 09 '20 at 20:00
  • This single line .gitattributes entry is the best, other solutions can be confusing. – Zoltán Hajdú Aug 14 '20 at 16:45
  • 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. – davejbur Jun 08 '23 at 07:41
  • 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. – davejbur Jun 08 '23 at 07:43
32

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.

albertjan
  • 7,739
  • 6
  • 44
  • 74
kusma
  • 6,516
  • 2
  • 22
  • 26
0

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.