DEV Community

Discussion on: Git and normalization of line-endings

Collapse
 
matthies profile image
Niklas Matthies • Edited

Git will not perform any conversions when checking out or committing text files.

This is not entirely correct. Text files (files that Git identifies as text files) are ALWAYS converted from CRLF to LF upon check-in. The core.eol option and eol attribute ONLY concern checkout. This isn't properly documented, but I recently performed exhaustive tests and looked at the Git source code.

  • Core.autocrlf=true/input causes text=auto as a default, equivalent to * text=auto in .gitattributes.
  • Core.autocrlf=true effectively sets core.eol=crlf.
  • Core.autocrlf=input effectively sets core.eol=lf.
  • The above are the only effects of core.autocrlf.
  • The effective core.eol serves as a default for the eol attribute for text files.
  • The effective eol attribute of a text file determines whether it is converted from LF to CRLF on checkout. The eol value makes no difference for check-in.

Further notes:

  • Text files with mixed LF/CRLF line endings are handled differently on check-in vs. checkout. As noted above, check-in always performs conversion to LF, which for text files with mixed line endings means that they are normalized to LF upon check-in. Checkout, on the other hand, always leaves text files with mixed line endings as-is, and does not convert them to CRLF even when it otherwise would for LF-only files. (The Git source code explicitly checks for the mixed line endings case.)
  • Since Git supports CRLF to LF conversion only on check-in (and does it unconditionally for text files) and LF to CRLF conversion only on checkout (and also doesn't support conversion of text files with mixed line endings for checkout, see above), the only workable repository line ending format for text files is LF.
  • After modifying .gitattributes, one should always perform git add --renormalize . to ensure correct behavior. In particular for auto-detected text files (text=auto), even committing modified files may otherwise not result in the desired line ending conversion. (This somehow relates to internal Git caching and is highly non-intuitive.)
  • It's likely advisable to set merge.renormalize=true, unless you use non-idempotent custom smudge/clean filters that would lead to unwanted merge results with this setting.
Collapse
 
beu profile image
Hamar Béla

Niklas, great job, congratulations!
And thank you for sharing your findings - the result of several hours of your work and investigation!

Collapse
 
spazmodius profile image
rajiv

Niklas, you say

Core.autocrlf=true/input causes text=auto as a default, equivalent to * text=auto in .gitattributes.

Do you know:

  • if the project has * -text in .gitattributes
  • but a team member has core.autocrlf=true in their config

which one wins when they check out files?

Collapse
 
matthies profile image
Niklas Matthies

The entry in .gitattributes takes precedence, core.autocrlf=true only sets the default.