Search code examples
giteolgitattributes

What is the difference between "* text=auto" and "* text=auto eol=lf"?


I was reading about the .gitattributes file and the rule to force line endings in some tutorials it's written like * text=auto and in some others, it's like * text=auto eol=lf at the first line of the file.

Are there any differences? what does the first one exactly do? Does it even force any line endings?

Also in some repositories it's mentioned that * text=auto preforms LF normalization! I don't know whether it's true or not.


Solution

  • There's a difference between these attributes. text asks Git to perform line ending conversion. Any time Git does this, it will store LF endings in the repository, and it will convert them when it checks files out in the working tree. text=auto asks Git to search the beginning of the file for a NUL byte, and if it finds one, then the file is binary and conversions are not performed; otherwise, the file is text, and conversions are performed. This usually works fine in most cases, and is a sensible default.

    By default, Git honors several configuration variables to decide what line ending conversion should be used in the working tree (LF or CRLF), unless the eol attribute is set. If eol is set, then (a) the file is automatically set to be text and (b) that line ending is always used.

    So in the former case, * text=auto says, "Guess whether this is a text file, and if it is, check this file out with the user's preferred line endings." The eol=lf applies only to files that are guessed as text in this case, as of Git 2.10. In general, eol applies if text is set explicitly, text=auto is set and the file is detected as text, or if text is left unspecified; in Git 2.10 and newer, it doesn't affect files explicitly marked -text or detected as binary with text=auto.

    However, if you're using older versions of Git, this can cause some binary files to be mishandled, since it will force them to always be text. If your repository contains only text files, then it will work, but this is better written as * text eol=lf. Otherwise, you can specify different types of files separately:

    * text=auto
    *.c text
    *.jpg -text
    *.sh text eol=lf
    *.bat text eol=crlf
    

    The above sets shell files to LF because those are required for them to work, and likewise with batch files having CRLF endings. JPEG files won't have any conversion, since they're binary.