gitdockerline-endingscore.autocrlf

Line ending for asset files in Docker container


I have copied my git project into a Docker container.

app/
    .git/
    src/
    .gitattributes

At first, calling git status showed every single project file as modified. This was because my project was worked on Windows, and uses CRLF line endings for every file. I followed this guide and added the following settings to my .gitattributes file.

* text=auto
*.* text eol=crlf

Now none of the source files are marked as modified. But all the asset files still do. modified asset files

As the picture shows, all my source files are gone (I was editing the docker files, so ignore those please). But the .png, .jpg, .ttf files are still marked.


Solution

  • There are a couple things to be aware of here. First, when you set the text attribute for *.*, you're asking Git to apply line-ending conversion to every file matching that pattern (that is, every file with a dot in its name). As a result, you've asked it to perform line ending changes on every font file and image in your repository, corrupting them, which is probably not what you wanted.

    The much safer thing to do is this:

    * text=auto
    

    That performs line ending conversion automatically.

    You can force the use of CRLF line endings with eol=crlf, but if your project is running in a Linux container, you probably do not want to. The Linux kernel and Unix shells do not treat carriage returns specially, so if you have any files with a shebang (e.g., a first line with #!) or any shell scripts, those will be completely broken and won't function if they have CRLF line endings. This is true even of shell scripts on Windows.

    If your editor is cross-platform and reasonably capable, you'd probably be better off forcing the use of LF endings with * text=auto eol=lf instead. If you're going to be collaborating with others, then just set * text=auto and run git config core.eol lf in your repository, which doesn't force others to use the same line endings as you do.

    Alternatively, if you know that you're always going to commit before creating the container, you can just run git reset --hard as part of the container build process, and then you don't have to know or care which line endings were used because you'll blow all the changes away and reset to the last commit.

    Once you've fixed your .gitattributes file and committed that (and only that), you can reset the working tree and blow away all your changes by running git reset --hard, which should return your tree to a clean state.

    I will point out that in general, it can be tricky to share repositories across systems. Git's index keeps metadata about each file in the working tree, so when you change the operating system, you're going to necessarily force a re-read of every file in the tree the next time you use git status. Certain features, such as alternates, also write path names into the repository which simply are not portable across systems, so you need to be careful not to use those features.