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

后端 未结 12 735
北海茫月
北海茫月 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: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.

提交回复
热议问题