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

后端 未结 6 1495
失恋的感觉
失恋的感觉 2021-02-05 09:30

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.mne         


        
相关标签:
6条回答
  • 2021-02-05 09:38

    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
    0 讨论(0)
  • 2021-02-05 09:49

    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.

    0 讨论(0)
  • 2021-02-05 09:49

    I just got stuck in this situation and the only thing which fixed it was the following:

    git log
    

    Find the first commit in the repo and get the hash (in my case started with fdb14f)

    Note: This only works because the repo with the issue was on a Linux server while I had a remote repo "origin" on my Windows box that contained the most recent commit which fixed the CRLF issue.

    git reset --hard fdb14f
    git pull origin master
    

    After trying all kinds of different things this is what finally allowed me to get around the issue. I had fixed the CRLF issue in the most recent commit, but nothing else I tried would allow me to get around these files.

    0 讨论(0)
  • 2021-02-05 09:51

    "Why is it still listed as an unstaged change?"

    Because bare git reset HEAD does not do anything to your working tree. It only resets the HEAD pointer to the commit you name (a no-op in this case, since you name HEAD), and resets the index to match the new HEAD (which, again, is the same in this case - so the net effect is basically only throwing away any git add, git rm, etc. commands you had done).

    0 讨论(0)
  • 2021-02-05 09:57

    If you need to remove local changes then run following command

    git checkout -- file_name
    

    git reset HEAD does not remove local changes.

    0 讨论(0)
  • 2021-02-05 09:59

    What you want is git reset HEAD --hard. git reset HEAD only un stages changes.

    I suggest you also take a look at how git can be set to auto convert/deconvert line endings because on projects with multiple developers working on different platforms this will cause anger when a single edit on a file causes git blame to show you as having changed the whole file.

    0 讨论(0)
提交回复
热议问题