Search code examples
git

Why isn’t eol=crlf honored in .gitattributes


I wanted to convert all files with windows-style line endings in our git repo to have unix-style line endings.

I followed the instructions from http://www.git-scm.com/docs/gitattributes#_end_of_line_conversion:

echo "* text=auto" >>.gitattributes
rm .git/index     # Remove the index to force Git to
git reset         # re-scan the working directory
git status        # Show files that will be normalized
git add -u
git add .gitattributes
git commit -m "Introduce end-of-line normalization"

I later realized that this had also changed *.bat files which should have remained CRLF. I tried the whole process again with the following .gitattributes file:

# Default 
*         text=auto eol=lf

# Windows-only files
*.bat     text eol=crlf

This did not seem to change the output of git status, the batch files were still marked “changed” even though they were CRLF in my working copy and .gitattributes set them to exactly that. It seemed like git would simply ignore the line with the *.bat. git show --raw also showed me the file was now being stored with LF instead of CRLF.


Solution

  • After hours of trying (and failing) to find a good specification on the format of .gitattributes I decided to try the following (note that this is NOT the correct fix for the problem):

    *.bat     -text
    

    And, lo and behold, the batch files disappeared from git status, indicating that there was no problem with the syntax of the file, as I had initially assumed. While I did not want to have batch files treated as binary, this lead me to what I now believe to be the correct conclusion:

    I’d misunderstood what git actually does when marking a file with the text attribute. It always stores the files with LF line endings internally and only converts to CRLF on checkout. So my initial steps were completely correct, they just produced output that confused me into thinking something was wrong. The files had actually changed; previously they were stored with CRLF but now they would be stored with just LF line endings, which would be corrected during checkout.