3

I am checking out a third party project "libjpeg" from https://github.com/winlibs/libjpeg on Linux (it is just one example, actually I have the same problem with many other projects as well). I have the following Git line endings configuration.

I have only global settings configured (set to checkout with LF line endings):

$ git config --system -l | grep core
core.eol=lf
core.autocrlf=false

$ git config --global -l | grep core
core.eol=lf
core.autocrlf=false

There are no local (repo) settings regarding line endings.

I read this article about the Git line endings configuration: https://adaptivepatchwork.com/2012/03/01/mind-the-end-of-your-line and I think that my configuration should give me LF for all text files on Linux. However it does not work. I get CRLF instead in my workspace. For example:

~/gitclonetest/libjpeg$ file libjpeg.map
libjpeg.map: ASCII text, with CRLF line terminators
~/gitclonetest/libjpeg$ cat -v libjpeg.map
LIBJPEG_9.0 {^M
  global:^M
    *;^M
};^M

Can someone help me to understand what I am missing? My goal is to have all text files (for any project) automatically be converted to LF when I clone it on Linux host.

UPDATE: The goal is to configure Git to check out on Linux host with LF even if then file was stored with CRLF in the repository.

Alexander Samoylov
  • 2,358
  • 2
  • 25
  • 28
  • Probably, the file committed inside the repository has CRLF line endings already. If that's the case, and you instruct Git not to mess with line endings at all—as one generally would on Linux—then Git will *keep* the CRLF line endings that are in the repository copy of the file, when extracting that file to a useful, editable Linux file. That is, if you tell Git: *preserve this binary data exactly* Git does so. The fact that the binary data is text doesn't matter. – torek Jun 11 '19 at 18:07
  • @torek, I have updated my question. If the flags that I posted now are wrong, can you tell please, which flags do you propose to achieve conversion to LF? It seems for me that I tried all possible combinations and no one worked. – Alexander Samoylov Jun 12 '19 at 10:54
  • 1
    I checked (by cloning the repository) and indeed the committed file has CRLF line endings in it. You *can* tell Git to modify such files during the conversion process (as the file is extracted from the index to the work-tree), but since you're on a "good" OS (Linux) you generally are not supposed to do this. The person who wrote this library *wanted* you to keep the committed file with CRLF line endings internally inside Git. – torek Jun 12 '19 at 15:14
  • @torek, what is then the solution for my case? Yes, it is clear that the file was committed with CRLF. But I want to obtain always LF when I checkout on Linux. I don't care with which lines the file was committed, I just want Git to checkout it me with the lines which I say to Git. Should not core.eol=lf do this? If not, then what setting should do this? – Alexander Samoylov Jun 13 '19 at 08:52
  • In that case, you'll need a `.gitattributes` file with the directive: `text eol=lf` for those particular files. But the effect will be that in every *new* commit you make, the file stored in the *repository* will have LF-only line endings, which is contrary to the desires of whoever put the file into the repository with CRLF line endings. In which case there's little point in having *Git* do this at all: you can just extract all files, convert them all once, and commit. You are, in essence, declaring the previous repository maintainer wrong. [continued] – torek Jun 13 '19 at 15:01
  • If you're going to do *that* —declare the previous repository maintainer wrong—you can then just say that certain files are text, and others are binary, and have *their* Windows systems convert LF-only line endings (stored in the repository) to CRLF line endings on *their* systems, and do nothing at all on your Linux system. In which case `eol=lf` will be unnecessary and arguably *wrong*. Have a look at the `.gitattributes` file in the Git repository for Git (github.com/git/git). – torek Jun 13 '19 at 15:03

4 Answers4

3

The problem is that you have core.autocrlf set to true. The documentation says the following:

Setting this variable to "true" is the same as setting the text attribute to "auto" on all files and core.eol to "crlf". Set to true if you want to have CRLF line endings in your working directory and the repository has LF line endings.

You definitely don't want to set that variable to true on a Unix or Linux system; it should be set to false unless you're on a Windows system (and even then there are better alternatives).

bk2204
  • 64,793
  • 6
  • 84
  • 100
  • Tried this also - the same issue. $ git config --system -l | grep core core.eol=lf core.autocrlf=false $ git config --global -l | grep core core.eol=lf core.autocrlf=false $ rm -rf libjpeg; git clone https://github.com/winlibs/libjpeg 2>/dev/null; file libjpeg/libjpeg.map libjpeg/libjpeg.map: ASCII text, with CRLF line terminators Will update the question as well now to make it clearer ... – Alexander Samoylov Jun 12 '19 at 09:59
2

Old, but still correct answer about EOL-headache in Git

In short:

core.autocrlf = false 
core.eol = native

will produce correct EOLs on all and any mix of OSes

Lazy Badger
  • 94,711
  • 9
  • 78
  • 110
  • Lazy Badger, I tried your settings and it does not work for https://github.com/winlibs/libjpeg (can you reproduce it on your host?). $ git config --system -l | grep core core.eol=native core.autocrlf=false $ git config --global -l | grep core core.eol=native core.autocrlf=false $ rm -rf libjpeg; git clone https://github.com/winlibs/libjpeg >& /dev/null; file libjpeg/libjpeg.map libjpeg/libjpeg.map: ASCII text, with CRLF line terminators – Alexander Samoylov Jun 11 '19 at 16:43
  • @AlexanderSamoylov, well, try `= input`. I don't have|use Git (I'm on Mercurial side of war) and haven't LF-OS now – Lazy Badger Jun 11 '19 at 19:45
0

You more than likely have set up some of the flags that tell git to mess up with EOL formats (and those flags are a mess). If you would rather have git not mess with them, you can do so by adding this to .gitattributes:

* -text

That way git won mess with the files when you add them or checkout. If you need some other kind of thing (like, real automatic EOL conversion), you might check the available things there.

https://git-scm.com/docs/gitattributes

Either way, steer away from using the flags you used on the question. They are a mess.

eftshift0
  • 26,375
  • 3
  • 36
  • 60
  • 1
    Can you please tell which else flags do you mean (where to check it)? I think I don't have anything else than I described above. Another question: you propose to use .gitattributes.. At first, I cannot add this file to the repo, because it is an external repo (not developed by me). At second, the sense of my question is however to understand why the default configuration does not work if I did everything correct. What else should I check? – Alexander Samoylov Jun 11 '19 at 14:56
  • @AlexanderSamoylov The flags are the ones you described on the question. They are a mess, for real. They are like the first iteration of EOL handling on git. Then the second one (the one using attributes) was created. You can have the same thing on your repo only if you add that into `.git/info/attributes`. There's good information about how to do stuff there, hope it works for your requirements: https://git-scm.com/docs/gitattributes – eftshift0 Jun 11 '19 at 15:00
  • as I told you above I cannot modify the repo. However I read your link and tried global /etc/gitattributes file. It did not help. The second that I tried was: "git config --system core.eol lf" in a combination with all 3 different values (input, false, true) for core.autocrlf. It did not help as well. About the "mess" in my flags...Actually I have only 2 flags set: core.eol and core.autocrlf on the user (--global) level. I posted another ones to illustrate in my question that the others are NOT SET. – Alexander Samoylov Jun 11 '19 at 15:31
  • Are you able to try on your host clone libjpeg and give me such a combination of global flags which makes it to be cloned with LF? I am just wondering if someone else can achieve it. – Alexander Samoylov Jun 11 '19 at 15:32
  • @AlexanderSamoylov I don't mean that what you set up is a mess. I mean that the implementation of the flags you used is a mess **in git**. and `.git/info/attributes` can be modified on your **local** repo without messing with the original repo or branch. – eftshift0 Jun 11 '19 at 15:34
0

I had this issue when I created a shell script to perform some automatic operation in my git repositories and the script could not run git add neither git checkout on some files with "LF to be replaced by CRLF"

To solve the issue you have two options:

git config --global core.autocrlf = false # Not recommended to deactivate this feature at all
git config --global core.safecrlf false # Just silent it instead (warning is ignored)

My final advice is to use the second approach at the beginning of your script (or manual operation) and then at the end of the script just restore it to default value:

git config --global core.safecrlf true # I'm assuming you didn't mess with autocrlf itself
Maf
  • 696
  • 1
  • 8
  • 23