Git:如何还原两个顽固地停留在“已更改但未提交”的文件?

| 我有一个回购,其中有两个文件,据说我是在本地更改的。 因此,我坚持以下做法:
$ 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:   dir1/foo.aspx
#       modified:   dir2/foo.aspx
#
no changes added to commit (use \"git add\" and/or \"git commit -a\")
执行
git diff
表示整个文件内容都发生了变化,即使从眼球看来似乎是不正确的(似乎diff似乎看不到常见的行范围)。 有趣的是,我不记得在本地更改这些文件。该仓库与一个远程仓库(私有,在GitHub.com,FWIW)一起使用。 无论我尝试了什么,我都不能放弃这些本地更改。我已经尝试了所有:
$ git checkout -- .
$ git checkout -f
$ git checkout -- dir1/checkout_receipt.aspx
$ git reset --hard HEAD
$ git stash save --keep-index && git stash drop
$ git checkout-index -a -f
换句话说,我已经尝试了如何丢弃Git中未分级的更改中描述的所有内容。还有更多。但是,这两个文件仍然停留为“已更改但未提交”。 到底是什么原因导致两个文件像这样被卡住,看似“ un-revert-table”? 附言在上面显示了我已经尝试过的命令的列表中,当我表示
git checkout
时,我错误地写了
git revert
。对不起,谢谢那些回答我应该尝试5英镑的人。我编辑了问题以更正它。我肯定已经尝试过5英镑。     
已邀请:
        文件中的行尾是什么?我敢打赌他们是CRLF。如果是这样,请查看此指南:http://help.github.com/line-endings/ 简而言之,您需要确保将git设置为在提交时将行尾转换为LF,然后提交那些文件。如果正确设置git,则回购中的文件应始终为LF,签出的文件应为操作系统的本机文件。     
        我花了数小时试图解决一个类似的问题-我签出的一个远程分支,即使删除了所有文件并再次运行
git checkout -f
(或本文的其他变体),该分支仍然顽固地将四个文件显示为“已更改但未更新”。 )! 这四个文件是必需的,但我肯定没有对其进行修改。我的最终解决方案-说服Git他们没有被更改。以下内容适用于所有检出的文件,并显示“已修改”状态-确保已提交/存放了真正修改过的文件!:
git ls-files -m | xargs -i git update-index --assume-unchanged \"{}\"
在Mac OSX上,不过xargs的操作略有不同(请评论Daniel):
git ls-files -m | xargs -I {} git update-index --assume-unchanged {}
我已将其添加为下一次自己的占位符,但我希望它也对其他人有所帮助。 铝     
        这就是我解决相同问题的方式: 打开.gitattributes 更改:
* text=auto
至:
#* text=auto
保存并关闭,然后还原或重置, 感谢@Simon East的提示     
        另一种可能性是差异(这是使用checkout命令阻止您还原这些文件的原因)的一种文件模式。这就是我发生的事情。在我的git版本上,您可以使用   git diff dir1 / foo.aspx 它将显示文件模式更改。不过,它仍然不会让您还原它们。为此使用   git config core.filemode错误 或在文本编辑器中通过添加来更改git .config   [核心]
filemode = false
完成此操作后,您可以使用   git reset HEAD dir1 / foo.aspx 文件应该消失了。 (我从如何使git忽略模式更改(chmod)的答案中获得了所有这些信息。)     
        尝试还原本地更改:
git checkout -- dir1/foo.aspx
git checkout -- dir2/foo.aspx
    
        我有一些幻像更改的文件,显示为已修改,但实际上是相同的。 运行此命令有时可行: (关闭git \的“ smart \”,但通常无益于行尾转换)
git config --local core.autocrlf false
但是在另一种情况下,我发现这是由于根目录中存在一个
.gitattributes
文件,并且存在某些行尾设置,即使关闭了该文件,它仍试图对某些文件应用
autocrlf
文件。这实际上并没有帮助,所以我删除了
.gitattributes
,已提交,文件不再显示为已修改。     
        
git checkout dir1/foo.aspx
git checkout dir2/foo.aspx
    
您可能还遇到了与目录字母大小写有关的问题。 您的某些同事可能已更改目录名称 来自例如从myHandler到MyHandler。 如果以后再推和拉原始目录的某些文件,则在远程存储库中将有2个单独的目录,而在本地计算机上只有1个目录,因为在Windows上,您只能有1个。而且您遇到了麻烦。 要检查是否是这种情况,只需查看远程存储库是否具有双重结构。 要解决此问题,请在回购之外创建父目录的备份副本,然后删除父目录,然后将其推送。拉动(这是第二个标记为已删除的标记应出现在状态上的情况),然后再次推动。 之后,从备份中重新创建整个结构,然后再次推送更改。     
        我认为,提示如何重现该问题将很有帮助,以便更好地理解该问题:
$ 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
复制的第二种方式: 在上面的脚本中,替换以下行:
echo \"*.txt -text\" > .gitattributes
git config core.autocrlf=false
并保持其余各行 以上都是怎么说?在某些情况下,文本文件可以是  用CRLF提交(例如
.gitattributes
中的
-text
/或
core.autocrlf=false
)。 当我们以后想将同一文件视为文本时(
-text
->
text
),将需要再次提交。 当然,您可以暂时将其还原(由Abu Assar正确回答)。在我们的情况下:
echo \"*.txt -text\" > .gitattributes
git checkout -- 1.txt
echo \"*.txt text\" > .gitattributes
答案是:您是否真的要这样做,因为每次更改文件都会引起相同的问题。 作为记录: 要检查哪些文件会在您的仓库中导致此问题,请执行以下命令(git应使用--with-libpcre进行编译):
git grep -I --files-with-matches --perl-regexp \'\\r\' HEAD
通过提交文件(假设您要将其视为文本),与执行此链接http://help.github.com/line-endings/中提出的用于解决此类问题的建议相同。但是,代替删除
.git/index
和执行
reset
,您只需更改文件,然后执行
git checkout -- xyz zyf
,然后提交即可。     
        对我来说,问题不在于行尾。这是关于更改文件夹名称的大小写(Reset_password-> Reset_Password)。该解决方案帮助我: https://stackoverflow.com/a/34919019/1328513     
        我遇到了同样的问题,有趣的是,文件在Windows上更改了,但是从WSL中查看文件时却没有更改。没有任何混乱的行尾,重置等能够改变它。 最终,我在此答案中找到了解决方案。以下是为方便起见的文本: 我已按照以下步骤解决了此问题 1)从Git的索引中删除每个文件。
git rm --cached -r .
2)重写Git索引以拾取所有新行结尾。
git reset --hard
解决方案是git网站上描述的步骤的一部分 https://help.github.com/articles/dealing-with-line-endings/     
        由于git将大小写差异视为不同的文件,而Windows将它们视为同一文件,因此也可能导致此问题。如果仅更改了文件名的大小写,则该存储库的每个Windows用户都将遇到这种情况。 解决方法是确认文件内容正确,然后重新提交。由于两个文件的内容不同,我们不得不将它们合并在一起。然后拉,将存在合并冲突,您可以通过删除重复的文件来解决。重新提交合并分辨率,您将回到稳定状态。     

要回复问题请先登录注册