Why won't "git reset HEAD" undo my uncommitted, unstaged changes?

git
17,367

Solution 1

If you need to remove local changes then run following command

git checkout -- file_name

git reset HEAD does not remove local changes.

Solution 2

I suspect that you had files saved with CRLF line endings in your repository, and then somewhere along the way your configuration was changed so that git started normalizing end-of-line characters (either core.autocrlf was set to true, or the .gitAttributes file was added or changed). When I ran into this problem, it turned out that a .gitAttributes file that contained * text=auto had been added to my repo.

(EOL normalization means that git will write the end-of-line characters as LF in its database, regardless of what you use in your working copy).

Git doesn't automatically check your files to see if they require EOL normalization after you enable it. You have to explicitly tell it to check all of your files, or else you end up in this situation: the files in your repository still have CRLF line endings, and git will only notice that it should normalize them when it touches each file. So the next time you commit some changes to a file, git will write the file to its database with LF line endings.

The problem occurs when git touches the file through a read operation. Say you make changes to a file that has CRLF line endings and then try to discard your changes. Git will read the clean copy from its database, see that it has CRLF line endings, and then mark the file as modified. The file has not actually been modified, but git is saying that it wants to write a change to the EOL characters to its database. This happens every time you attempt to discard your changes, check out that file, or even do a hard reset. That is why it seems to be impossible to undo those modifications.

You should have git normalize the line endings on all of your text files, so this problem doesn't continue to pop up (see https://stackoverflow.com/a/4683783/1369 for instructions on how to do that). If it's possible, you might even want to modify your history so the line endings are normalized at the same time the .gitAttributes settings were changed.

If you cannot modify your history, then you may run into situations where you need to check out old versions of your files that still have the CRLF line endings. You will probably get stuck with a list of modified files that you cannot discard and don't want to commit. In that case, you can use this work-around to essentially make git forget that it wants to modify those files:

  1. Check out the old version
  2. Turn off end-of-line normalization
  3. git reset
  4. Re-enable end-of-line normalization

Solution 3

I ran into something similar. My setup is using git on a web server to pull down the most recent code. For an unknown reason, it ran into this issue.

# git reset HEAD —hard

Unstaged changes after reset:

 'File Name'

I tried all the suggested things here. None fixed it.

I fix it in this case by doing

git add 'File Name'

then,

git reset --hard HEAD

Which cleared the issue for me.

Share:
17,367

Related videos on Youtube

Nilzor
Author by

Nilzor

I am a software engineer developing for Android, Windows, Windows Phone and any other platform I find interesting. Currently working for Schibsted with Android phones, but I have also years of experience in the consulting industry on the Microsoft platform. I have an MA in Computer Science from NTNU, Trondheim.

Updated on August 17, 2022

Comments

  • Nilzor
    Nilzor over 1 year

    I've previously been able to undo changes through SourceTree by performing the "Discard" function, which under the hood produces this command:

    git -c diff.mnemonicprefix=false -c core.quotepath=false reset -q HEAD -- myproj.csproj 
    git -c diff.mnemonicprefix=false -c core.quotepath=false checkout HEAD -- myproj.csproj
    

    Suddenly this doesn't work. I do the Discard, no error occurs, refreesh the view, but the files are still "modified". I've then tried to do the same in the command line with the following, same result:

    c:\myproject> git reset HEAD
    
    Unstaged changes after reset:
    M       myproj.csproj
    

    Why is it still listed as an unstaged change?

    I've verified that the file is indeed writable (no process is holding a lock)

    update

    git checkout didn't work either:

    C:\myproject>git checkout myproj.csproj
    
    C:\myproject>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:   myproj.csproj
    #
    no changes added to commit (use "git add" and/or "git commit -a")
    

    Update 2 Also tried:

    • git checkout --
    • git checkout -- .
    • git checkout HEAD

    ,none of which solves my problem

    update 3 - huge step closer:

    Turns out when I do the checkout, the .csproj is indeed reverted to the correct version, but the checked out version uses a different line feed encoding. While the checked-in version has CR-LF (0D-0A) for line feed, the checked-out has only LF (0A). Hence git belives the file to be different on every single line. Why this?

    update 4: added the second line of git-commands issued by SourceTree. I didn't notice that the first time around, that's why I thought git reset HEAD would do anything. This doesn't change the fact that the underlying problem still is CR/LF-related (I think)

    summary I never found a solution to the issue, but I "solved" it by checking in the file. My original question didn't contain information that SourceTree indeed issued the correct commands to rollback what I wanted, so most answers here address that issue. The real issue is still unclear, but my main theory is that it was CR/LF related.

    • devnull
      devnull over 10 years
    • Nilzor
      Nilzor over 10 years
      I'm inclined to give up - "solved" the issue by checking in the new line feed encoding. Neither git config --global core.autocrlf true nor false helped either. If anyone have any more suggestions, I have a clone of the repo for further testing.
    • Kate
      Kate over 4 years
      First of all I closed SourceTree. Then I set both core.autocrlf and core.safecrlf to true as was said in comments here - stackoverflow.com/questions/1575682/…. After that I used git reset --hard. Fortunantly, all changes disapeared.
  • Nilzor
    Nilzor over 10 years
    See update in question. git checkout didn't work either. Is my repo corrupted?
  • Nilzor
    Nilzor over 10 years
    I've tried both git --config global core.autocrlf true followed by git reset HEAD --hard and git --config global core.autocrlf false followed by the same command. Git still believes I have an uncommitted change in my working folder. I believe it is CR/LF-related, but I can't figure out how to solve it without checking in the file.
  • Nilzor
    Nilzor over 10 years
    I'm accepting this answer because my question was incomplete/unclear in the beginning, and this would indeed solve the initial problem. However noone has provided an answer to the CR/LF-problem
  • webbo
    webbo about 10 years
    also check file permissions, I've had co-workers see file permission changes show up as a difference, but no actuall lines, if git diff doesn't show anything permissions may very well be the issue.. Also If you have both CR , LR, and CRLF in the file there could be issues no matter what option you pick.