git status shows modifications, git checkout -- <file> doesn't remove them

Viewed 146916

I would like to remove all changes to my working copy.
Running git status shows files modified.
Nothing I do seems to remove these modifications.
E.g.:

rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   Rhino.Etl.Core/Enumerables/CachingEnumerable.cs
#       modified:   Rhino.Etl.Core/Pipelines/SingleThreadedPipelineExecuter.cs
#       modified:   Rhino.Etl.Tests/Rhino.Etl.Tests.csproj
#       modified:   Rhino.Etl.Tests/SingleThreadedPipelineExecuterTest.cs
#
no changes added to commit (use "git add" and/or "git commit -a")

rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ git checkout -- Rhino.Etl.Core/Enumerables/CachingEnumerable.cs

rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   Rhino.Etl.Core/Enumerables/CachingEnumerable.cs
#       modified:   Rhino.Etl.Core/Pipelines/SingleThreadedPipelineExecuter.cs
#       modified:   Rhino.Etl.Tests/Rhino.Etl.Tests.csproj
#       modified:   Rhino.Etl.Tests/SingleThreadedPipelineExecuterTest.cs
#
no changes added to commit (use "git add" and/or "git commit -a")

rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ git checkout `git ls-files -m`

rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   Rhino.Etl.Core/Enumerables/CachingEnumerable.cs
#       modified:   Rhino.Etl.Core/Pipelines/SingleThreadedPipelineExecuter.cs
#       modified:   Rhino.Etl.Tests/Rhino.Etl.Tests.csproj
#       modified:   Rhino.Etl.Tests/SingleThreadedPipelineExecuterTest.cs
#
no changes added to commit (use "git add" and/or "git commit -a")

rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ git reset --hard HEAD
HEAD is now at 6c857e7 boo libraries updated to 2.0.9.2 and rhino.dsl.dll updated.

rbellamy@PROMETHEUS /d/Development/rhino-etl (master)
$ git status
# On branch master
# Changed but not updated:
#   (use "git add <file>..." to update what will be committed)
#   (use "git checkout -- <file>..." to discard changes in working directory)
#
#       modified:   Rhino.Etl.Core/Enumerables/CachingEnumerable.cs
#       modified:   Rhino.Etl.Core/Pipelines/SingleThreadedPipelineExecuter.cs
#       modified:   Rhino.Etl.Tests/Rhino.Etl.Tests.csproj
#       modified:   Rhino.Etl.Tests/SingleThreadedPipelineExecuterTest.cs
#
no changes added to commit (use "git add" and/or "git commit -a")
24 Answers

There are multiple problems that can cause this behaviour:

Line ending normalization

I've had these kinds of problems too. It comes down to git automatically converting crlf to lf. This is typically caused by mixed line endings in a single file. The file gets normalized in the index, but when git then denormalizes it again to diff it against the file in the working tree, the result is different.

But if you want to fix this, you should disable core.autocrlf, change all line endings to lf, and then enable it again. Or you can disable it altogether by doing:

git config --global core.autocrlf false

Instead of core.autocrlf, you can also consider using .gitattributes files. This way, you can make sure everyone using the repo uses the same normalization rules, preventing mixed line endings getting into the repository.

Also consider setting core.safecrlf to warn if you want git to warn you when a non-reversible normalization would be performed.

The git manpages say this:

CRLF conversion bears a slight chance of corrupting data. autocrlf=true will convert CRLF to LF during commit and LF to CRLF during checkout. A file that contains a mixture of LF and CRLF before the commit cannot be recreated by git. For text files this is the right thing to do: it corrects line endings such that we have only LF line endings in the repository. But for binary files that are accidentally classified as text the conversion can corrupt data.

Case-insensitive file systems

On case-insensitive filesystems, when the same filename with different casing is in the repository, git tries to checkout both, but only one ends up on the file system. When git tries to compare the second one, it would compare it to the wrong file.

The solution would either be switching to a non-case insensitive filesystem, but this in most cases is not feasible or renaming and committing one of the files on another filesystem.

Try doing a

git checkout -f

That should clear all the changes in the current working local repo

Normally, in GIT to clear all your modifications & new files the following 2 commands should work very nicely (be CAREFUL, this will delete all your new files+folders you may have created & will restore all your modified files to the state of your current commit):

$ git clean --force -d
$ git checkout -- .

Maybe a better option sometimes is just doing "git stash push" with optional message, like so:

$ git stash push -m "not sure if i will need this later"

This will also clear all your new and modified files, but you'll have all of them stashed in case you want to restore them. Stash in GIT carries from branch to branch, so you can restore them in a different branch, if you wish to.

As a side note, in case you have already staged some newly added files and want to get rid of them, this should do the trick:

$ git reset --hard

If all of the above doesn't work for you, read below what worked for me a while ago:

I ran into this problem few times before. I'm currently developing on Windows 10 machine provided by my employer. Today, this particular git behavior was caused by me creating a new branch from my "develop" branch. For some reason, after I switched back to "develop" branch, some seemingly random files persisted and were showing up as "modified" in "git status".

Also, at that point I couldn't checkout another branch, so I was stuck on my "develop" branch.

This is what I did:

$ git log

I noticed that the new branch I created from "develop" earlier today was showing in the first "commit" message, being referenced at the end "HEAD -> develop, origin/develop, origin/HEAD, The-branch-i-created-earlier-today".

Since I didn't really need it, I deleted it:

$ git branch -d The-branch-i-created-earlier-today

The changed files were still showing up, so I did:

$ git stash

This solved my problem:

$ git status
On branch develop
Your branch is up to date with 'origin/develop'.

nothing to commit, working tree clean

Of course $ git stash list will show stashed changes, and since I had few and didn't need any of my stashes, I did $ git stash clear to DELETE ALL STASHES.

NOTE: I haven't tried doing what someone suggested here before me:

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

This may have worked as well, I'll be sure to try it next time I run into this problem.

I had an older redundant branch with different line-endings. Switching to this got me a bit stuck until I applied some --force.

git checkout mainbranch --force

Followed by a swift git branch -D brokenbranch.

I commited all the changes and then did and undo on the commit. This worked for me

git add .

git commit -m "Random commit"

git reset --hard HEAD~1

Nothing else on this page worked. This finally worked for me. Showing no untracked, or commited files.

git add -A
git reset --hard

For me the problem was that Visual Studio was opened when performing the command

git checkout <file>

After closing Visual Studio the command worked and I could finally apply my work from the stack. So check all applications that could make changes to your code, for example SourceTree, SmartGit, NotePad, NotePad++ and other editors.

I solved it by editing .git / config, adding:

[branch "name_branch"]
    remote = origin
    merge = refs/heads/name_branch

Then I went to .git / refs / heads / name_branch and place the id of the last commitenter code here

I solved it this way:

  1. Copy the contents of the correct code you want
  2. Delete the file that is causing the problem ( the one that you can't revert ) from your disk. now you should find both versions of the same file marked as being deleted.
  3. Commit the deletion of the files.
  4. Create the file again with the same name and paste in the correct code you have copied in step 1
  5. commit the creation of the new file.

That's what worked for me.

One proposed solution here didn't work, I found out the file was actually a link to some special characters:

% ls -l StoreLogo.png
lrwxrwxrwx 1 janus janus 8 Feb 21 10:37 StoreLogo.png -> ''$'\211''PNG'$'\r\n\032\n'

% git status    
Changes not staged for commit:
    modified:   StoreLogo.png

% git rm --cached -r StoreLogo.png
rm 'src/GWallet.Frontend.XF.UWP/Assets/StoreLogo.png'

% git reset StoreLogo.png         
Unstaged changes after reset:
M   src/GWallet.Frontend.XF.UWP/Assets/StoreLogo.png

% git status                      
Changes not staged for commit:
    modified:   StoreLogo.png
Related