Git: How to revert 2 files that are stubbornly stuck at “Changed but not committed”?

后端 未结 12 676
北海茫月
北海茫月 2020-12-22 19:15

I have a repo that has two files that supposedly I changed locally.

So I\'m stuck with this:

$ git status
# On branch master
# Changed but not update         


        
相关标签:
12条回答
  • 2020-12-22 19:40

    Try to revert local changes:

    git checkout -- dir1/foo.aspx
    git checkout -- dir2/foo.aspx
    
    0 讨论(0)
  • 2020-12-22 19:41

    I think it would be helpful to provide a hint on how to reproduce the issue, in order to better understand the problem:

    $ git init
    $ echo "*.txt -text" > .gitattributes
    $ echo -e "hello\r\nworld" > 1.txt
    $ git add 1.txt 
    $ git commit -m "committed as binary"
    $ echo "*.txt text" > .gitattributes
    $ echo "change.." >> 1.txt
    
    # Ok let's revert now
    
    $ git checkout -- 1.txt
    $ git status
     modified:   1.txt
    
    # Oooops, it didn't revert!!
    
    
    # hm let's diff:
    
    $ git diff
     warning: CRLF will be replaced by LF in 1.txt.
     The file will have its original line endings in your working 
     directory.
     diff --git a/1.txt b/1.txt
     index c78c505..94954ab 100644
     --- a/1.txt
     +++ b/1.txt
     @@ -1,2 +1,2 @@
     -hello
     +hello
      world
    
    # No actual changes. Ahh, let's change the line endings...
    
    $ file 1.txt 
     1.txt: ASCII text, with CRLF line terminators
    $ dos2unix 1.txt
     dos2unix: converting file 1.txt to Unix format ...
    $ git diff
     git diff 1.txt
     diff --git a/1.txt b/1.txt
     index c78c505..94954ab 100644
     --- a/1.txt
     +++ b/1.txt
     @@ -1,2 +1,2 @@
     -hello
     +hello
      world
    
    # No, it didn't work, file is still considered modified.
    
    # Let's try to revert for once more:
    $ git checkout -- 1.txt
    $ git status
     modified:   1.txt
    
    # Nothing. Let's use a magic command that prints wrongly committed files.
    
    $ git grep -I --files-with-matches --perl-regexp '\r' HEAD
    
    HEAD:1.txt
    

    2nd way to reproduce: In the above script replace this line:
    echo "*.txt -text" > .gitattributes
    with
    git config core.autocrlf=false
    and keep the rest of the lines as is


    What all the above say? A text file can (under some circumstances) be committed with CRLF, (e.g. -text in .gitattributes / or core.autocrlf=false).

    When we later want to treat the same file as text (-text -> text) it will need to be committed again.
    Of course you can temporarily revert it (as correctly answered by Abu Assar). In our case:

    echo "*.txt -text" > .gitattributes
    git checkout -- 1.txt
    echo "*.txt text" > .gitattributes
    

    The answer is: do you really want to do that, because it's gonna cause the same problem everytime you change the file.


    For the record:

    To check which files can cause this problem in your repo execute the following command (git should be compiled with --with-libpcre):

    git grep -I --files-with-matches --perl-regexp '\r' HEAD
    

    By committing the file(s) (supposing that you want to treat them as text), it is the same thing as doing what is proposed in this link http://help.github.com/line-endings/ for fixing such problems. But, instead of you removing .git/index and performing reset, you can just change the file(s), then perform git checkout -- xyz zyf and then commit.

    0 讨论(0)
  • 2020-12-22 19:47

    I spent hours trying to solve a similar issue - a remote branch that I had checked out, which stubbornly showed four files as 'Changed but not updated', even when deleting all files and running git checkout -f again (or other variations from this post)!

    These four files were necessary, but certainly hadn't been modified by me. My final solution - persuade Git that they had not been changed. The following works for all checked out files, showing 'modified' status - make sure you have already committed/stashed any that have really been modified!:

    git ls-files -m | xargs -i git update-index --assume-unchanged "{}"
    

    On Mac OSX, however xargs operates a little bit different (thx Daniel for the comment):

    git ls-files -m | xargs -I {} git update-index --assume-unchanged {}
    

    I've added this as a placeholder for myself for next time, but I hope it helps someone else too.

    -Al

    0 讨论(0)
  • 2020-12-22 19:49

    this is how I fixed the same problem in my case: open .gitattributes change:

    * text=auto
    

    to:

    #* text=auto
    

    save and close , then revert or reset, thanks to @Simon East for the hint

    0 讨论(0)
  • 2020-12-22 19:51

    Another possibility is that the difference (that's preventing your from reverting these files with a checkout command) is one of file mode. This is what happened to me. On my version of git you can discover this by using

    git diff dir1/foo.aspx

    And it will show you file mode changes. It still won't let you revert them, though. For that use either

    git config core.filemode false

    or change your git .config in your text editor by adding

    [core]

    filemode = false
    

    After you do this, you can use

    git reset HEAD dir1/foo.aspx

    and the file should disappear.

    (I got all of this from the answer to How do I make git ignore mode changes (chmod)?)

    0 讨论(0)
  • 2020-12-22 19:55

    I had some phantom changed files that were showing as modified, but were actually identical.

    Running this command sometimes works:
    (Turns off git's "smart" but often unhelpful line-ending conversions)

    git config --local core.autocrlf false
    

    But in another case I found it was due to a .gitattributes file in the root which had some line-ending settings present, which was trying to apply autocrlf for certain files even when it was turned off. That wasn't actually helpful, so I deleted .gitattributes, committed, and the file no longer showed as modified.

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