Git: How to revert 2 files that are stubbornly stuck at “Changed but not committed”?
我有一个repo,有两个文件,据说我在本地更改。
所以我坚持这个:
1 2 3 4 5 6 7 8 9 10 | $ 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") |
做
有趣的是我不记得在本地更改这些文件。此仓库与一个远程仓库(私人,GitHub.com,FWIW)一起使用。
无论我尝试过什么,我都不能放弃这些局部变化。我尝试了所有:
1 2 3 4 5 6 | $ 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他们没有被改变。以下适用于所有已检出文件,显示"已修改"状态 - 确保您已经提交/存储了任何已经修改过的文件!:
1 | git ls-files -m | xargs -i git update-index --assume-unchanged"{}" |
在Mac OSX上,然而xargs运行有点不同(丹尼尔评论):
1 | git ls-files -m | xargs -I {} git update-index --assume-unchanged {} |
我下次已将此作为占位符添加到我自己,但我希望它也可以帮助其他人。
-Al
文件中的行结尾是什么?我打赌他们是CRLF。如果是,请查看本指南:http://help.github.com/line-endings/
简而言之,您需要确保将git设置为在提交时将行结尾转换为LF,然后提交这些文件。 repo中的文件应始终为LF,检出的文件应该是操作系统的本机,假设您正确设置了git。
这就是我在我的情况下修复同样问题的方法:
打开.gitattributes
更改:
1 | * text=auto |
至:
1 | #* text=auto |
保存并关闭,然后恢复或重置,
感谢@Simon East提示
另一种可能性是差异(阻止您使用checkout命令恢复这些文件)是文件模式之一。这就是发生在我身上的事。在我的git版本上你可以通过使用来发现它
git diff dir1/foo.aspx
它会显示文件模式的变化。但它仍然不会让你回复它们。对于那个用途
git config core.filemode false
或者通过添加在文本编辑器中更改你的git .config
[core]
1 filemode = false
执行此操作后,您可以使用
git reset HEAD dir1/foo.aspx
并且文件应该消失。
(我从答案中得到了所有这些如何使git忽略模式更改(chmod)?)
我有一些幻影更改的文件显示为已修改,但实际上是相同的。
运行此命令有时会起作用:
(关闭git的"智能"但通常无益的线路结束转换)
1 | git config --local core.autocrlf false |
但在另一种情况下,我发现这是由于根目录中的
尝试还原本地更改:
1 2 | git checkout -- dir1/foo.aspx git checkout -- dir2/foo.aspx |
1 2 | git checkout dir1/foo.aspx git checkout dir2/foo.aspx |
您也可能遇到与命名字母案例的目录相关的问题。
你的一些同事可能已经改变了目录的名称
从例如myHandler到MyHandler。
如果您稍后推送并拉出了原始目录中的一些文件,那么您在远程存储库上将拥有2个单独的目录,而在本地计算机上只有一个目录,因为在Windows上您只能拥有一个。你遇到了麻烦。
要检查是否是这种情况,只需查看远程存储库是否具有双重结构。
要解决此问题,请在repo之外创建父目录的备份副本,然后删除父目录,将其推送。拉动(这是当标记为已删除的第二个应该出现在状态时)并再次按下。
之后,从备份中重新创建整个结构并再次推送更改。
对我来说,问题不在于线路结束。它是关于更改文件夹名称中的大小写(Reset_password - > Reset_Password)。这个解决方案帮助我:
https://stackoverflow.com/a/34919019/1328513
我认为提供一个如何重现问题的提示会有所帮助,以便更好地理解问题:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 | $ git init $ echo"*.txt -text"> .gitattributes $ echo -e"hello world"> 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 ' ' HEAD HEAD:1.txt |
第二种方式重现:
在上面的脚本中替换此行:
同
并按原样保留其余的行
以上所说的是什么?文本文件可以(在某些情况下)
使用CRLF提交(例如
当我们后来想要将同一个文件视为文本(
当然你可以暂时还原它(正如Abu Assar正确回答的那样)。在我们的情况下:
1 2 3 | echo"*.txt -text"> .gitattributes git checkout -- 1.txt echo"*.txt text"> .gitattributes |
答案是:你真的想这样做,因为每次更改文件都会导致同样的问题。
作为记录:
要在repo中检查哪些文件可能导致此问题,请执行以下命令(git应使用--with-libpcre编译):
1 2 | git grep -I --files-with-matches --perl-regexp ' ' HEAD |
通过提交文件(假设您希望将它们视为文本),与执行此链接http://help.github.com/line-endings/中提出的修复此类问题的内容相同。但是,您可以只更改文件,然后执行