git status shows modifications even with autocrlf=false
Asked Answered
I

6

42

I'm experiencing the same issues as in this question: git status shows modifications, git checkout -- <file> doesn't remove them

Git continues to show working directory modifications, even with git config --global core.autocrlf false:

E:\_dev\github\Core [master +0 ~93 -0]> git config --get-all core.autocrlf
false
false

(Note that I've even set the --system setting to be false)

Why does it appear that Git is still modifying my end of lines?

Attempts to get rid of modifications

Baseline

E:\_dev\github\Core [master +0 ~93 -0]> git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   tools/StatLight/StatLight.EULA.txt
... more changes ...
no changes added to commit (use "git add" and/or "git commit -a")

git checkout -- .

E:\_dev\github\Core [master +0 ~93 -0]> git checkout -- .
E:\_dev\github\Core [master +0 ~93 -0]> git status
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed) 
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   tools/StatLight/StatLight.EULA.txt
... more changes ...
no changes added to commit (use "git add" and/or "git commit -a")

Occasionally this will have an effect in an odd way:

E:\_dev\github\Core [master +0 ~628 -0]> git checkout -- .
E:\_dev\github\Core [master +0 ~361 -0]> git checkout -- .
E:\_dev\github\Core [master +0 ~93 -0]> git checkout -- .
E:\_dev\github\Core [master +0 ~93 -0]> git checkout -- .
E:\_dev\github\Core [master +0 ~93 -0]> git checkout -- .

git reset --hard

E:\_dev\github\Core [master +0 ~93 -0]> git reset --hard
HEAD is now at 11a7f9a Merge pull request #8 from RemiBou/master
E:\_dev\github\Core [master +0 ~93 -0]>

git add .; git stash; git stash drop

E:\_dev\github\Core [master +0 ~93 -0]> git add .
... warnings ....
warning: CRLF will be replaced by LF in tools/StatLight/StatLight.EULA.txt.
The file will have its original line endings in your working directory.

E:\_dev\github\Core [master +0 ~93 -0]> git stash
Saved working directory and index state WIP on master: 11a7f9a Merge pull request #8 from 
RemiBou/master
HEAD is now at 11a7f9a Merge pull request #8 from RemiBou/master

E:\_dev\github\Core [master +0 ~93 -0]> git stash drop
Dropped refs/stash@{0} (de4c3c863dbad789aeaf563b4826b3aa41bf11b7)

E:\_dev\github\Core [master +0 ~93 -0]> git status .\tools\StatLight\StatLight.EULA.txt
# On branch master
# Changes not staged for commit:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   tools/StatLight/StatLight.EULA.txt
#
no changes added to commit (use "git add" and/or "git commit -a")
Indecent answered 12/6, 2012 at 22:18 Comment(2)
I have this problem here - they are likely the same problem. In my question I also verified no gitattributes are interfering.Jd
@Jd could you put the output of git config -l in a pastebin and link it here? And make sure there is no .gitattributes in your project root or any other folder.Boutis
U
23

This seems like a bug in msysgit indeed. As a workaround, try creating a .gitattributes file containing

* -text

This will tell git not to perform EOL conversions on any files.

Unwinking answered 1/3, 2013 at 15:39 Comment(3)
Seems the bug is not restricted to msysgit. Can reproduce it on Mac OS X easily: #22823504Stites
After looking at dozens of stackoverflow posts about git and line endings, this is the one that saved me!Intervale
It did not help in my case, git still shows a file is modified even though I have "core.autocrlf false" and an attribute file with above content under .git/infoBrioche
S
10

Check if you have no .gitattributes file

As mentioned in the "Effect" section of the gitattributes man page, those files can also have an effect on eol and automatic transformation:

text ^^^^^^

This attribute enables and controls end-of-line normalization.
When a text file is normalized, its line endings are converted to LF in the repository.
To control what line ending style is used in the working directory, use the eol attribute for a single file and the core.eol configuration variable for all text files.

Check also your config for core.eol, as mentioned in "How line ending conversions work with git core.autocrlf between different operating systems".


Git 2.41 (Q2 2023) includes a doc update to clarify how text and eol attributes interact to specify the end-of-line conversion.

See commit 6696077 (02 May 2023) by Alex Henrie (alexhenrie).
(Merged by Junio C Hamano -- gitster -- in commit c05615e, 10 May 2023)

docs: rewrite the documentation of the text and eol attributes

Helped-by: Torsten Bögershausen
Signed-off-by: Alex Henrie

These two sentences are confusing because the description of the text attribute sounds exactly the same as the description of the text=auto attribute:

"Setting the text attribute on a path enables end-of-line normalization"

"When text is set to "auto", the path is marked for automatic end-of-line conversion"

Unless the reader is already familiar with the two variants, there's a high probability that they will think that "end-of-line normalization" is the same thing as "automatic end-of-line conversion".

It's also not clear that the phrase "When the file has been committed with CRLF, no conversion is done" in the paragraph for text=auto does not apply equally to the bare text attribute which is described earlier.
Moreover, it falsely implies that normalization is only suppressed if the file has been committed.
In fact, running git add(man) on a CRLF file, adding the text=auto attribute to the file, and running git add again does not do anything to the line endings either.

On top of that, in several places the documentation for the eol attribute sounds like either it does not affect normalization on checkin or it forces normalization on checkin.
It also sounds like setting eol (or setting a config variable) is required to turn on conversion on checkout, but the text attribute can turn on conversion on checkout by itself if eol is unspecified.

Rephrase the documentation of text, text=auto, eol, eol=crlf, and eol=lf to be clear about how they are the same, how they are different, and in what cases conversion is performed.

gitattributes now includes in its man page:

This attribute marks the path as a text file, which enables end-of-line conversion: When a matching file is added to the index, the file's line endings are normalized to LF in the index. Conversely, when the file is copied from the index to the working directory, its line endings may be converted from LF to CRLF depending on the eol attribute, the Git config, and the platform (see explanation of eol below).

gitattributes now includes in its man page:

conversion on checkin and checkout as described above. Line endings are normalized to LF in the index every time the file is checked in, even if the file was previously added to Git with CRLF line endings.

gitattributes now includes in its man page:

When text is set to "auto", Git decides by itself whether the file is text or binary. If it is text and the file was not already in Git with CRLF endings, line endings are converted on checkin and checkout as described above. Otherwise, no conversion is done on checkin or checkout.

gitattributes now includes in its man page:

This attribute marks a path to use a specific line-ending style in the working tree when it is checked out. It has effect only if text or text=auto is set (see above), but specifying eol automatically sets text if text was left unspecified.

gitattributes now includes in its man page:

This setting converts the file's line endings in the working directory to CRLF when the file is checked out.

gitattributes now includes in its man page:

This setting uses the same line endings in the working directory as in the index when the file is checked out.

Unspecified

If the eol attribute is unspecified for a file, its line endings in the working directory are determined by the core.autocrlf or core.eol configuration variable (see the definitions of those options in git config). If text is set but neither of those variables is, the default is eol=crlf on Windows and eol=lf on all other platforms.

Saum answered 13/6, 2012 at 9:14 Comment(11)
No .gitattributes in the repository or working directory, nor in my profile. core.eol was not set; set it in turn to all 3 of { 'lf', 'crlf', 'native' } and in each case after git checkout -- . modified files remain, and "warning: LF will be replaced by CRLF" appears on checkout.Indecent
@Indecent ok. The idea was to not set any core.eol or .gitattributes text directives, and to keep auto.crlf to false. If that still fails to prevent eol transformation, then we can eliminate those and keep looking.Saum
Thanks for the specifics. Given that core.eol wasn't set, and the issue persisted; I had no other options but to try setting it and determining if it at least modified the result in order to get insight into why git insists on changing line endings.Indecent
Any followups on this? Or workarounds? Seems like a bug somewhere in git/mysgit if with autocrlf = false it still insists on converting files (files that seem to have inconsistent line endings).Neace
Also having the same problem for days already, no working solution found yet?Quiles
@Neace no workaround that I know of. If you can reproduce consistently the issue with a small example, please open a bug report at github.com/msysgit/msysgit/issuesSaum
@RangelReale no working solution that I know of. If you can reproduce consistently the issue with a small example, please open a bug report at github.com/msysgit/msysgit/issuesSaum
@Saum The problem I am having isn't only on msysgit, git on linux seems to be having the same problem. The upstream project will test more on Linux, I'll post here if finding something relevant.Quiles
@Saum - the issue as I documented it above reproduces it reliably. If Rangel or core24 want to help by creating the issue, I can fill in the details about which file I used there.Indecent
In my case I overlooked a .gitattributes. @Indecent did you verify they didn't exist at any level? Was a git issue opened? This is an issue a lot of git users run into so I'm trying to get this question/answer in a good state for future reference.Jd
Also is this a case to convert an answer into a community wiki? There's about 8 debug steps across all these answers and I would prefer authoritative coverage on debugging this problem - at present you have to understand git config (global/user/repo level) and gitattributes very well to resolve this.Jd
T
8

I'm investigating the weird behavior of core.autocrlf in MSysGit, and I found that having:

[core]
    autocrlf = false
    safecrlf = true
    ignorecase = true
    eol = native 

in the global config file and NO core.autocrlf setting in a repo copied from another PC (not cloned, only copied), issuing a git status command results in ALL text files marked as modified (no gitattributes around).

But if you add a local (repository) core.autocrlf setting to true, and then issue a git status command, all the changes disappears and the repository turns back to be clean.

BUT (and this is the strange behavior) if you remove the just added core.autocrlf setting from the repository config file (thus returning to the exact initial state), the git status command continues to report no changes!

Given that no operations has been performed on the repository, only changing a config setting, and reverting back to the original state, has done the trick...

If this isn't a bug, I can't imagine who in the world can call this a "normal" behavior.

Tattoo answered 3/12, 2013 at 11:18 Comment(0)
H
6

This problem can be caused by gitattributes' text option.

Please read the documentation carefully but essentially autocrlf only matters if text is not set in a .gitattributes:

Unspecified
If the text attribute is unspecified, git uses the core.autocrlf configuration variable to determine if the file should be converted.

Find your .gitattributes file via:

find <root-dir> -name .gitattributes

And grep for text, eol or crlf to find your culprit and revise as necessary.

You may just change this file and revert the change without committing for long enough to get through your issue.

Housum answered 28/3, 2013 at 17:5 Comment(0)
G
1

"autocrlf" issue is a typical issue for cross multi platform repo (i.e. using a samba share with tortoisegit over a server under linux)

I realized, that sometimes (often), it's more a "chmod" issue than a autocrlf one : - git status windows display pending modifications - git status linux display nothing

"mode change 100755 => 100644 config/packager.xml"

Check that your "static" files are not +x, (and in this case tortoisegit wont like it)

Gigahertz answered 13/1, 2014 at 8:36 Comment(1)
Confirmed, I have also seen this with cygwin git on windows.Adulterate
S
0

Although i don't know what is causing this weird behaviour, i know one more way of discarding changes that might work.

Warning! Be extremely careful and do a backup first; this can be highly destructive.

If all data that you care about is committed in the repository, you can simply delete everything in your working directory (of course except hidden .git directory) and run git reset --hard HEAD to have git recreate the working directory solely from the repository data.

Remember to carefully check if you don't have any important data that is not tracked by git before doing this. It's not enough to check git status for uncommitted changes - remember that deleting all files from the working dir will also delete files which you told git to ignore, and they won't be recreated with git reset --hard HEAD because they're not tracked at all.

Snook answered 14/2, 2013 at 22:45 Comment(3)
Why will this have any effect other than a git reset --hard assuming there are no untracked files?Jd
@Jd because git doesn't keep track that it used to have different eol settings in the already checked-out files. This has been observed in several installations where core.eol and core.autocrlf settings have been changed on the fly for existing files. git reset --hard won't do anything if it thinks it doesn't need to.Tamelatameless
This suggestion didn't work for me. Removed everything, did a git reset --hard HEAD, still see the files as modified.Incardination

© 2022 - 2024 — McMap. All rights reserved.