Git:如何恢复2个固定在“已更改但未提交”的文件?

我有一个回购有两个文件,据说我本地更改。

所以我坚持这个:

$ 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说,整个文件的内容已经改变了,即使从目光看似乎是不真实的(似乎是差异似乎无法看到的共同线范围)。

有趣的是,我不记得在本地更改这些文件。 这个回购是用于一个远程回购(私人,在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”?

PS在上面显示的命令列表中,我已经尝试过了,当我的git checkout时,我错误地写了git revert 。 我很抱歉,谢谢你们的答复,我应该尝试checkout 。 我编辑了这个问题来纠正它。 我绝对已经尝试checkout

文件中的结尾是什么? 我打赌他们是CRLF。 如果是,请查看本指南: http : //help.github.com/line-endings/

总之,你需要确保git被设置为在提交时将行结束符转换为LF,然后提交这些文件。 回购的文件应该总是LF,检查出来的文件应该是操作系统的本地,假设你设置正确的git。

我花了好几个小时试图解决一个类似的问题 – 我检查出来的一个远程分支,即使在删除所有文件并再次运行git checkout -f (或其他变体)时,它固执地显示四个文件为“已更改但未更新”文章)!

这四个文件是必要的,但是当然没有被我修改过。 我的最终解决scheme – 说服Git,他们没有改变。 对于所有已签出的文件,显示“已修改”状态的下列文件可以确保您已经提交/保存了任何真正被修改的文件!

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

然而在Mac OSX上,xargs的操作有点不同(thx Daniel的评论):

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

我已经添加了这个作为下次自己的占位符,但我希望它也可以帮助别人。

-Al

这是我如何解决我的情况相同的问题:打开.gitattributes更改:

 * text=auto 

至:

 #* text=auto 

保存并closures,然后恢复或重置,感谢@西蒙东提示

另一种可能性是差异(即阻止你用恢复命令恢复这些文件)是文件模式之一。 这是发生在我身上的事情。 在我的版本的git上,你可以通过使用来发现这个

git diff dir1 / foo.aspx

它会显示你的文件模式的变化。 但它仍然不会让你恢复它们。 为了那个用途

git config core.filemode false

或者通过添加在你的文本编辑器中改变你的git .config

[核心]

 filemode = false 

做完这个之后,你可以使用

git reset HEAD dir1 / foo.aspx

该文件应该消失。

(我从答案中得到了所有这些, 我如何让git忽略模式更改(chmod)? )

尝试恢复本地更改

 git checkout -- dir1/foo.aspx git checkout -- dir2/foo.aspx 

我有一些幻像更改文件,显示为已修改,但实际上是相同的。

运行这个命令有时会起作用
(closuresgit的“聪明”,但往往无益的行结束转换)

 git config --local core.autocrlf false 

但在另一个案例中,我发现这是由于一个.gitattributes文件存在一些行结束设置的根目录,它试图对某些文件应用autocrlf ,即使它被closures。 这实际上并没有帮助,所以我删除了.gitattributes ,提交,并且文件不再显示为已修改。

 git checkout dir1/foo.aspx git checkout dir2/foo.aspx 

对我来说,这个问题不是关于行结束的。 这是关于更改文件夹名称中的大小写(Reset_password – > Reset_Password)。 此解决scheme帮助了我: https : //stackoverflow.com/a/34919019/1328513

我认为提供一个关于如何重现问题的提示是有帮助 ,以便更好地理解问题:

 $ 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 

第二种方法重现:在上面的脚本中replace这一行:
echo "*.txt -text" > .gitattributes

git config core.autocrlf=false
并保留其余的行


以上所说的是什么? 一个文本文件可以 (在某些情况下)用CRLF提交(例如,在.gitattributes /或core.autocrlf=false中的.gitattributes )。

当我们稍后想要将文件作为文本( -text – > text )处理时,它将需要再次提交。
当然,你可以暂时恢复它(正如Abu Assar所正确回答的那样)。 在我们的情况下:

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

答案是 :你真的想这样做,因为每次更改文件都会导致同样的问题。


作为logging:

要检查哪些文件可能导致您的回购问题执行以下命令(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然后提交。