text=auto Git will handle the files in whatever way it thinks is best. This is a good default option. text eol=crlf Git will always convert line endings to CRLF on checkout. You should use this for files that must keep CRLF endings, even on OSX or Linux.
Historically, Windows uses different line endings (CRLF) than Linux/macOS (LF). This often leads to issues on cross-platform development teams, e.g.: Inconsistent (mixed) line endings.
You can set the mode to use by adding an additional parameter of true or false to the above command line. If core. autocrlf is set to true, that means that any time you add a file to the Git repository that Git thinks is a text file, it will turn all CRLF line endings to just LF before it stores it in the commit.
Whereas Windows follows the original convention of a carriage return plus a line feed ( CRLF ) for line endings, operating systems like Linux and Mac use only the line feed ( LF ) character. The history of these two control characters dates back to the era of the typewriter.
The best explanation of how core.autocrlf
works is found on the gitattributes man page, in the text
attribute section.
This is how core.autocrlf
appears to work currently (or at least since v1.7.2 from what I am aware):
core.autocrlf = true
LF
characters are normalized to CRLF
in your working tree; files that contain CRLF
in the repository will not be touchedLF
characters in the repository, are normalized from CRLF
to LF
when committed back to the repository. Files that contain CRLF
in the repository will be committed untouched.core.autocrlf = input
CRLF
characters are normalized to LF
when committed back to the repository.core.autocrlf = false
core.eol
dictates EOL characters in the text files of your working tree.core.eol = native
by default, which means working tree EOLs will depend on where git is running: CRLF
on a Windows machine, or LF
in *nix.gitattributes
settings determines EOL character normalization for commits to the repository (default is normalization to LF
characters).I've only just recently researched this issue and I also find the situation to be very convoluted. The core.eol
setting definitely helped clarify how EOL characters are handled by git.
The issue of EOLs in mixed-platform projects has been making my life miserable for a long time. The problems usually arise when there are already files with different and mixed EOLs already in the repo. This means that:
CRLF
and LF
in the same file.How this happens is not the issue here, but it does happen.
I ran some conversion tests on Windows for the various modes and their combinations.
Here is what I got, in a slightly modified table:
| Resulting conversion when | Resulting conversion when | committing files with various | checking out FROM repo - | EOLs INTO repo and | with mixed files in it and | core.autocrlf value: | core.autocrlf value: -------------------------------------------------------------------------------- File | true | input | false | true | input | false -------------------------------------------------------------------------------- Windows-CRLF | CRLF -> LF | CRLF -> LF | as-is | as-is | as-is | as-is Unix -LF | as-is | as-is | as-is | LF -> CRLF | as-is | as-is Mac -CR | as-is | as-is | as-is | as-is | as-is | as-is Mixed-CRLF+LF | as-is | as-is | as-is | as-is | as-is | as-is Mixed-CRLF+LF+CR | as-is | as-is | as-is | as-is | as-is | as-is
As you can see, there are 2 cases when conversion happens on commit (3 left columns). In the rest of the cases the files are committed as-is.
Upon checkout (3 right columns), there is only 1 case where conversion happens when:
core.autocrlf
is true
and LF
EOL.Most surprising for me, and I suspect, the cause of many EOL problems is that there is no configuration in which mixed EOL like CRLF
+LF
get normalized.
Note also that "old" Mac EOLs of CR
only also never get converted.
This means that if a badly written EOL conversion script tries to convert a mixed ending file with CRLF
s+LF
s, by just converting LF
s to CRLF
s, then it will leave the file in a mixed mode with "lonely" CR
s wherever a CRLF
was converted to CRCRLF
.
Git will then not convert anything, even in true
mode, and EOL havoc continues. This actually happened to me and messed up my files really badly, since some editors and compilers (e.g. VS2010) don't like Mac EOLs.
I guess the only way to really handle these problems is to occasionally normalize the whole repo by checking out all the files in input
or false
mode, running a proper normalization and re-committing the changed files (if any). On Windows, presumably resume working with core.autocrlf true
.
core.autocrlf
value does not depend on OS type but on Windows default value is true
and for Linux - input
. I explored 3 possible values for commit and checkout cases and this is the resulting table:
╔═══════════════╦══════════════╦══════════════╦══════════════╗
║ core.autocrlf ║ false ║ input ║ true ║
╠═══════════════╬══════════════╬══════════════╬══════════════╣
║ ║ LF => LF ║ LF => LF ║ LF => LF ║
║ git commit ║ CR => CR ║ CR => CR ║ CR => CR ║
║ ║ CRLF => CRLF ║ CRLF => LF ║ CRLF => LF ║
╠═══════════════╬══════════════╬══════════════╬══════════════╣
║ ║ LF => LF ║ LF => LF ║ LF => CRLF ║
║ git checkout ║ CR => CR ║ CR => CR ║ CR => CR ║
║ ║ CRLF => CRLF ║ CRLF => CRLF ║ CRLF => CRLF ║
╚═══════════════╩══════════════╩══════════════╩══════════════╝
Things are about to change on the "eol conversion" front, with the upcoming Git 1.7.2:
A new config setting core.eol
is being added/evolved:
This is a replacement for the 'Add "
core.eol
" config variable' commit that's currently inpu
(the last one in my series).
Instead of implying that "core.autocrlf=true
" is a replacement for "* text=auto
", it makes explicit the fact thatautocrlf
is only for users who want to work with CRLFs in their working directory on a repository that doesn't have text file normalization.
When it is enabled, "core.eol" is ignored.Introduce a new configuration variable, "
core.eol
", that allows the user to set which line endings to use for end-of-line-normalized files in the working directory.
It defaults to "native
", which means CRLF on Windows and LF everywhere else. Note that "core.autocrlf
" overridescore.eol
.
This means that:[core] autocrlf = true
puts CRLFs in the working directory even if
core.eol
is set to "lf
".core.eol:
Sets the line ending type to use in the working directory for files that have the
text
property set.
Alternatives are 'lf', 'crlf' and 'native', which uses the platform's native line ending.
The default value isnative
.
Other evolutions are being considered:
For 1.8, I would consider making
core.autocrlf
just turn on normalization and leave the working directory line ending decision to core.eol, but that will break people's setups.
git 2.8 (March 2016) improves the way core.autocrlf
influences the eol:
See commit 817a0c7 (23 Feb 2016), commit 6e336a5, commit df747b8, commit df747b8 (10 Feb 2016), commit df747b8, commit df747b8 (10 Feb 2016), and commit 4b4024f, commit bb211b4, commit 92cce13, commit 320d39c, commit 4b4024f, commit bb211b4, commit 92cce13, commit 320d39c (05 Feb 2016) by Torsten Bögershausen (tboegi
).
(Merged by Junio C Hamano -- gitster
-- in commit c6b94eb, 26 Feb 2016)
convert.c
: refactorcrlf_action
Refactor the determination and usage of
crlf_action
.
Today, when no "crlf
" attribute are set on a file,crlf_action
is set toCRLF_GUESS
. UseCRLF_UNDEFINED
instead, and search for "text
" or "eol
" as before.Replace the old
CRLF_GUESS
usage:
CRLF_GUESS && core.autocrlf=true -> CRLF_AUTO_CRLF
CRLF_GUESS && core.autocrlf=false -> CRLF_BINARY
CRLF_GUESS && core.autocrlf=input -> CRLF_AUTO_INPUT
Make more clear, what is what, by defining:
- CRLF_UNDEFINED : No attributes set. Temparally used, until core.autocrlf
and core.eol is evaluated and one of CRLF_BINARY,
CRLF_AUTO_INPUT or CRLF_AUTO_CRLF is selected
- CRLF_BINARY : No processing of line endings.
- CRLF_TEXT : attribute "text" is set, line endings are processed.
- CRLF_TEXT_INPUT: attribute "input" or "eol=lf" is set. This implies text.
- CRLF_TEXT_CRLF : attribute "eol=crlf" is set. This implies text.
- CRLF_AUTO : attribute "auto" is set.
- CRLF_AUTO_INPUT: core.autocrlf=input (no attributes)
- CRLF_AUTO_CRLF : core.autocrlf=true (no attributes)
As torek adds in the comments:
all these translations (any EOL conversion from
eol=
orautocrlf
settings, and "clean
" filters) are run when files move from work-tree to index, i.e., duringgit add
rather than atgit commit
time.
(Note thatgit commit -a
or--only
or--include
do add files to the index at that time, though.)
For more on that, see "What is difference between autocrlf and eol".
Here is my understanding of it so far, in case it helps someone.
core.autocrlf=true
and core.safecrlf = true
You have a repository where all the line endings are the same, but you work on different platforms. Git will make sure your lines endings are converted to the default for your platform. Why does this matter? Let's say you create a new file. The text editor on your platform will use its default line endings. When you check it in, if you don't have core.autocrlf set to true, you've introduced a line ending inconsistency for someone on a platform that defaults to a different line ending. I always set safecrlf too because I would like to know that the crlf operation is reversible. With these two settings, git is modifying your files, but it verifies that the modifications are reversible.
core.autocrlf=false
You have a repository that already has mixed line endings checked in and fixing the incorrect line endings could break other things. Its best not to tell git to convert line endings in this case, because then it will exacerbate the problem it was designed to solve - making diffs easier to read and merges less painful. With this setting, git doesn't modify your files.
core.autocrlf=input
I don't use this because the reason for this is to cover a use case where you created a file that has CRLF line endings on a platform that defaults to LF line endings. I prefer instead to make my text editor always save new files with the platform's line ending defaults.
No, the @jmlane answer is wrong.
Checkin (git add, git commit)
:text
property is Set, Set value to 'auto'
, the conversion happens enen the file has been committed with 'CRLF'text
property is Unset
:nothing happens, enen for Checkout
text
property is Unspecified
, conversion depends on core.autocrlf
autocrlf = input or autocrlf = true
, the conversion only happens when the file in the repository is 'LF', if it has been 'CRLF', nothing will happens.autocrlf = false
, nothing happensCheckout
:text
property is Unset
: nothing happens.text
property is Set, Set value to 'auto
: it depends on core.autocrlf
, core.eol
.
core.eol
text
property is Unspecified
, it depends on core.autocrlf
.
2.1
2.2
text
property is Unspecified
So the Default behavior is text
property is Unspecified
and core.autocrlf = false
:
text
property is set, checkin behavior is depends on itself, not on autocrlfIf you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With