42

I have a repo I added a gitattributes to it and was working on it fine. I sync it via dropbox to another machine. When I opened it to the other machine a bunch of files suddenly appeared on the unstaged area as total diffs (all the file a huge diff which means line endings diff) - my crlf endings are basically .* text=auto and I am working on windows. I tried to stash the changes, reset the branch etc. At long last I decided to commit the files and then made some other commits I wanted to reorder (and squash) before the line endings commit. When I try rebasing I get a :

error: Your local changes to the following files would be overwritten by merge
        # those same files
Please, commit your changes or stash them before you can merge.
Aborting
Could not apply 89b25b81fff1a1e7893319e123aaaca9c4162a95... <commit message>

Of course stash does not work

Is it a bug ?

Related:

EDIT Nothing to do with machines - on the same machine some (...) operations just make those files (they are on the .gitattributes as text) appear in the "changed" section. The only workaround that seems to exist is:

git rm --cached -r .
git reset --hard

USE CAREFULLY

EDIT: hack above moved to alias status:

[alias]
     crlf = !git rm -r . --cached -q && git reset --hard

UPDATE 2015.09.30: I have a git repo in an NTFS partition I use from windows 7 and arch linux in a dual boot environment. When I shut windows down and I boot into arch two files (html) show as total diffs (line ending diffs). The above workaround does not work - unless you apply it several times refreshing the gui in between...

My .gitattributes:

* text=auto

*.py text diff=python
*.html text
.project text
*.pkl -text

# M$ files
*.bat text eol=crlf

# UNIX files
**/generate_second_post text eol=lf

# git files - have them with LF, as I edit them via the shell (echo etc)
*.gitignore text eol=lf
*.gitattributes text eol=lf

NB: linux will let me commit, switch branches etc but won't let me rebase - plus those diffs always appear in gitk/git gui.

2018/12/14 moved to mac and my workaround does not work anymore. I posted a message to the git mailing list: https://marc.info/?l=git&m=154482149623324&w=2

Let's hope this will get some attention

$ git --version
git version 2.19.2
Mr_and_Mrs_D
  • 32,208
  • 39
  • 178
  • 361
  • 2
    Have you tried this? `git add -u .; git reset;` – Attila Szeremi Jul 11 '14 at 11:57
  • 1
    @SzerémiAttila: have you tried it in my scenario and it works ? What is is supposed to do ? – Mr_and_Mrs_D Jul 11 '14 at 13:09
  • 1
    Adds all tracked files to the index, then removes them with the index, keeping all the changes in your files. I've done this before in a similar situation and made Git realized that nothing has actually changed, making the line ending problems go away. And I've already answered a question like this before with the same answer: http://stackoverflow.com/questions/10890380/git-thinks-files-have-changed/11258263 – Attila Szeremi Jul 11 '14 at 13:46
  • Will test again when I get these stupid random changes again :) Meanwhile you might attempt an answer - maybe touching on _why_ this happens (as is a part of the question). Looks like a bug - if it is it shouyld be finally reported and fixed – Mr_and_Mrs_D Jul 11 '14 at 15:02
  • Not quite sure, but there's some sort of mismatch between the the checks `diff` and `status` say about whether a file was changed (taking `.gitattributes` into account) and what `reset` and `stash` look at. This has actually been a problem for as long as I can remember (5 years) with the older and less preferred `core.autocrlf` config property. If the Git team has not bothered to fix this since then, even along with the `.gitattributes` file, then they probably just don't care, and don't expect a fix for this ever. `git add` seems to clear some common cache for git with files. – Attila Szeremi Jul 11 '14 at 15:29
  • @SzerémiAttila: thanks for your comments - please consider adding them to an answer - will accept if this works in my case. If it is indeed a bug then it must be properly reported to be fixed. It does cause endless conflicts in everyday scenarios though - and people new to git just commit the diffs making it all harder – Mr_and_Mrs_D Jul 11 '14 at 16:38
  • If I understand you, you're sharing a *working directory* (ie. checked out files) via Dropbox with both a Windows and a Linux machine? What is `core.eol` set to? – Schwern Oct 17 '15 at 21:31
  • @Schwern: forget dropbox, does not always run - it's the same physical folder, in an NTFS partition (the windows one) that I mount on linux. My windows `git config --list` is here: https://www.dropbox.com/s/fnyajvn6tz1s7wq/windows-config-all.txt?dl=0 - I do not have a `core.eol` setting but `core.autocrlf=false` – Mr_and_Mrs_D Oct 17 '15 at 23:53
  • You could also perhaps try running `dos2unix` or `unix2dos` on the command line and check the diff between the changed file and a previous commit. I did this on a file that somehow was changed to `crlf` endings: `$ cp myfile.php myfile_backup.php; dos2unix myfile.php; git diff myfile.php` (I am comparing unix-ified file to last commit). I see now only a couple of changes, where I actually changed code. I still don't know if it is git or PhpStorm actually changing the file. But now I can commit my real changes instead of all those spurious `crlf` line endings. – Buttle Butkus May 08 '16 at 01:52

7 Answers7

30

Finally after 5 years here is a complete answer, thanks to Torsten Bögershausen.

The way to debug this eol situation is to investigate using the --eol switch to git ls-files added by Torsten Bögershausen. Turns out that the file(s) in question were committed with CRLF while the .gitattributes file added later specified text for these files. This results in an "illegal state". Nothing to be done, for old commits.

What should be done is git add --renormalize . so the files are added with correct (lf) line endings and then reset --hard to have those lineendings in the working tree.

Now this won't help with old commits, however (the commits that are in this illegal state, so between the files were committed with wrong line endings and the gitattributes commit) - checking those out will probably lead to those unresetable changes. The fix for this is provided by the answer by @iKlsR:

$ cat .git/info/attributes
"Mopy/Docs/Bash Readme Template.html" -text

the reason being that:

When deciding what attributes are assigned to a path, Git consults $GIT_DIR/info/attributes file (which has the highest precedence), .gitattributes file in the same directory as the path in question, and its parent directories up to the toplevel of the work tree [ect]

(emphasis mine)

Just be sure to add the line after you renormalise, otherwise the file(s) won't be added to the renormalise commit!

Mr_and_Mrs_D
  • 32,208
  • 39
  • 178
  • 361
  • 2
    After running renormalization; I needed to run `git reset --hard origin/master && git pull` on all affected clones with "line ending diffs". – gekkedev Oct 06 '19 at 14:12
4

The same issue happened with me today. Try this

git config --local core.fileMode false

as discussed here: How do I make Git ignore file mode (chmod) changes?

Community
  • 1
  • 1
e.novikov
  • 41
  • 1
  • This is the only answer working for me, developing a repo of linux in windows, had CRLF and LF issue and could not reset files – Sayyed Dawood Mar 17 '22 at 12:30
4

We ran into this issue today where it seemed the problem stemmed from some CRLF-related issues related to a newly added .gitattributes file with a single line * text=auto. When you rebased or created a new branch, said file would follow you and ruin any changes that came after along with preventing you from leaving that branch without first committing it.

We initially fixed this by checking out a temporary branch, reverting the file back to a sane state (before modifications), committing and then doing a rebase on the entire branch back to the oldest commit to make it look like master. That worked for a while but a similar file popped up after that and the same fix didn't work again.

What we eventually went with was similar to what op shared in his update.. a single line inside .git/info/attributes with file-to-remove -text seems to mitigate the problem. I say mitigate because I'm not sure if there are any adverse implications to doing this, this was also for one file so might not work as well if at all.

iKlsR
  • 2,642
  • 6
  • 27
  • 45
2

Have you tried this?

git add -u .
git reset
Attila Szeremi
  • 5,235
  • 5
  • 40
  • 64
  • Please consider adding the rest of your comments to appease the commenters - they're right but you already provided the info they need in your comments ;) – Mr_and_Mrs_D Jul 11 '14 at 16:42
  • 2
    Nope -didn't work - still stuck with `git rm --cached -r .; git reset --hard` – Mr_and_Mrs_D Jul 13 '14 at 12:36
1

A re-write of @Mr_and_Mrs_D's excellent answer above:

git add --renormalize .  
git reset --hard   
git ls-files --eol | grep 'crlf' |  awk '{print $5 " -text"}' > .git/info/attributes  
git reset --hard  
git pull  
rm .git/info/attributes

I'm not certain if both resets are necessary. Also, be careful with the git ls-files line - I've got it filtering for crlf anywhere, so this might pick up files that have crlf in their name; there's probably a cleaner way to do this. It will also truncate .git/info/attributes if you already have one; modify with >> if required, and edit the file manually afterwards to remove those lines if you need.

askvictor
  • 3,621
  • 4
  • 32
  • 45
0

Same issue here, I am using Win7, sourceTree v3.0.9, git v1.9.5

In repo root, when .gitattribute file has text=auto, it shows a lot of local file changes about line ending and it prevents me from doing anything. After I set text=crlf, all local changes are gone.

Previously I tried to adding "[core] autocrlf = false" in config file, but it didn't help.

Updated on 12/06/2018: My SourceTree was using embedded git with old version, just update it in SourceTree and everything works now with "text=auto" in .gitattributes

Yang
  • 111
  • 6
  • Git 1.9.5? That is.... (`git tag -l --format="%(refname) %(taggerdate)" --sort="v:refname" v1.9.5`) from Dec. 2014!? Could you check if the issue persists with Git 2.20-rc2? (https://github.com/git-for-windows/git/releases) – VonC Dec 04 '18 at 21:49
  • @VonC the issue does persist with git `2.19.0` on an affected repository - by affected I mean that a file was committed once with line endings that confuse git – Mr_and_Mrs_D Dec 04 '18 at 22:02
  • @Yang this does not really fix anything though - it just tells git to commit crlf line endings which is probably not whatt you want - and yes do update git :) – Mr_and_Mrs_D Dec 04 '18 at 22:03
  • @Mr_and_Mrs_D Note that for refreshing an index regarding the `.gitattributes` rule, you now have `git add --renormalize` since Git 2.16 (Q1 2018): https://stackoverflow.com/a/47580886/6309 – VonC Dec 04 '18 at 22:06
  • @VonC, thank you for pointing out the out-of-dated git I use SourceTree and it is configured to use embedded git, which was v1.9.5 I think it was installed long time ago along with an older version of sourceTree. I just updated the embedded git in SourceTree, and set text=auto back in .gitattribtues, my issue was solved now. – Yang Dec 05 '18 at 22:26
  • @Yang Well done, and good catch. You can edit your answer to make your solution more visible. – VonC Dec 05 '18 at 22:41
0

None of this works on my Windows 10 WSL, I had diff in README.md and was not able to pull changes, so I've did this from

echo README.md >> .gitignore # not sure if this is needed
rm README.md # this need to be rm without git
git pull
git checkout .gitignore # to remove the change

I think that it will also work if you just do:

rm file
git checkout <branch>

but I'm not able to test because my repo is working now.

jcubic
  • 61,973
  • 54
  • 229
  • 402
  • Adding a tracked file to .gitignore does not have any effect, so probably the .gitigore line is not needed - was README.md tracked? – Mr_and_Mrs_D Sep 18 '19 at 09:16
  • @Mr_and_Mrs_D yes it was tracked, that's why I've got diff the main reason for the problem. I've deleted the file, not sure if .gitignore affect the README file, because of this. – jcubic Sep 18 '19 at 10:03
  • Didn't you get a conflict on pulling upstream README? – Mr_and_Mrs_D Sep 18 '19 at 10:22
  • @Mr_and_Mrs_D I don't have conflicts because I'm not able to pull, git is telling me to commit changes first. – jcubic Sep 18 '19 at 11:49
  • But you did issue `git pull` no? – Mr_and_Mrs_D Sep 18 '19 at 12:03
  • @Mr_and_Mrs_D I use git pull to get back the README.md file from repo (with latest changes), so git just reset that file. I've deleted the file, so my local index was clear before I've pulled the changes (did't have conflict because I didn't have any changes on my disk) that did reset the file to correct state. This the same as if I would clone the repo. – jcubic Sep 18 '19 at 14:09