Git with autocrlf=true checks out files with mixed line endings as-is
Asked Answered
C

2

8

So, I always thought that with core.autocrlf=true Git replaces all LF endings with CRLF when checking out the file into the working directory.

From the Git book:

If you’re on a Windows machine, set it to true – this converts LF endings into CRLF when you check out code

However, when checking out a file with mixed line endings and core.autocrlf set to true, my version of Git checks out the file as-is.

I've found a very convenient GitHub repository to test this behaviour - https://github.com/YueLinHo/TestAutoCrlf

Test results:

  • A file with LF endings only (LF.txt)
    • With autocrlf=false: checked out as-is (all line endings are LF)
    • With autocrlf=true: all line endings are changed to CRLF on checkout

So far so good, everything as I expected. Now for the file with mixed line endings:

  • A file with mixed line endings (MIX-more_CRLF.txt, MIX-more_LF.txt)
    • With autocrlf=false: checked out as-is (a mix of LF and CRLF)
    • With autocrlf=true: checked out as-is (a mix of LF and CRLF)

Why does this happen? I haven't seen anything about autocrlf=true not touching files with mixed line endings.

Are my Git settings at fault? I checked the core.autocrlf setting running git config --get core.autocrlf in the repository folder after checking out with autocrlf=true in the global .gitconfig, and the command returned true. There is no .gitattributes file to overwrite the settings.

All tests were made on Git version 1.9.5.msysgit.0.

EDIT: Same behaviour on the latest msysgit version 1.9.5.msysgit.1.

My original problem is that I somehow managed to commit a mixed-line ending file with only LF endings while having core.autocrlf set to true, meaning the file was checked out as-is, but commited with CRLF changed to LF. I'm currently working from another machine and cannot reproduce this behaviour on my msysgit version.

Cowskin answered 22/4, 2015 at 9:32 Comment(2)
It actually sounds like a good default; if a file has mixed line-endings, then there probably is a good reason for that in general situations. The obvious solution is to convert the file to the system default line-endings and then commit it, allowing git to convert the line-endings.Florie
@Florie Maybe it's a good default, but I haven't seen this behaviour documented anywhere, so I was wondering why it happens.Cowskin
C
3

I am reposting an answer that was deleted by its owner, because I think it gives the best explanation. I have no idea why the author deleted it, I think it's correct and I've voted to undelete.

Apparently this behavior is hardcoded in Git and does not depend on core.safecrlf (and I've tested this, mixed files are left untouched even if I set git config core.safecrlf false.

Original answer follows:


Autocrlf doesn't convert mixed line endings, as the git's source code tells:

https://github.com/git/git/commit/a0ad53c18100226cb1a138cb9b3bc3615170be8f

Note the comments here:

/* No "naked" LF? Nothing to convert, regardless. */

and

/* If we have any CR or CRLF line endings, we do not touch it */
/* This is the new safer autocrlf-handling */

Mixed line endings conversion is non-reversible, when it's done, Git crashed.

So, if you wanna convert your files' line endings automatically, it might be a good idea to set a .gitattributes file dealing with end-of-line. Such as:

LF.txt eol=lf
CRLF.txt eol=crlf
Convent answered 27/2, 2018 at 11:4 Comment(0)
S
2

What is the value of core.safecrlf ?

If core.safecrlf is set to true, then mixed line endings files will not be converted. (Because the converting is not reversible if line endings is mixed)

Sinter answered 22/4, 2015 at 9:53 Comment(4)
git config --get core.safecrlf in the repository folder returns an empty line, so I guess it's not set.Cowskin
So maybe it's default value is true.Sinter
But core.safecrlf=true wouldn't let me commit a file with mixed line endings if any conversions take place. warn would notify me. Instead, I get no message whatsoever on such a commit, even if I explicitly set core.safecrlf to true.Cowskin
@Florie Yes that's it.Sinter

© 2022 - 2024 — McMap. All rights reserved.