我不小心用git add -A添加了很多临时文件
我设法使用以下命令取消文件,并设法删除脏索引。
git ls-files -z | xargs -0 rm -f
git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached
以上命令在git帮助rm中列出。但遗憾的是,我的文件在执行时也被删除了,即使我给了缓存选项。如何在不丢失内容的情况下清除索引?
此外,如果有人能解释这个管道操作的工作方式,这将是有帮助的。
我不小心用git add -A添加了很多临时文件
我设法使用以下命令取消文件,并设法删除脏索引。
git ls-files -z | xargs -0 rm -f
git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached
以上命令在git帮助rm中列出。但遗憾的是,我的文件在执行时也被删除了,即使我给了缓存选项。如何在不丢失内容的情况下清除索引?
此外,如果有人能解释这个管道操作的工作方式,这将是有帮助的。
当前回答
恐怕第一个命令行会无条件地从工作副本中删除git暂存区的所有文件。第二种方法取消了所有被跟踪的文件,但现在已经删除了。不幸的是,这意味着您将丢失对这些文件的所有未提交的修改。
如果你想让你的工作副本和索引恢复到上次提交时的状态,你可以(小心地)使用以下命令:
git reset --hard
我说“小心”,因为git重置-hard将删除你的工作副本和索引中未提交的更改。然而,在这种情况下,听起来好像您只是想回到上次提交时的状态,而未提交的更改无论如何都会丢失。
更新:从你对Amber的回答的评论中,听起来你还没有创建任何提交(因为HEAD无法解析),所以这恐怕不会有帮助。
As for how those pipes work: git ls-files -z and git diff --name-only --diff-filter=D -z both output a list of file names separated with the byte 0. (This is useful, since, unlike newlines, 0 bytes are guaranteed not to occur in filenames on Unix-like systems.) The program xargs essentially builds command lines from its standard input, by default by taking lines from standard input and adding them to the end of the command line. The -0 option says to expect standard input to by separated by 0 bytes. xargs may invoke the command several times to use up all the parameters from standard input, making sure that the command line never becomes too long.
举个简单的例子,如果你有一个名为test.txt的文件,包含以下内容:
hello
goodbye
hello again
... 然后命令xargs echo whatever < test.txt将调用该命令:
echo whatever hello goodbye hello again
其他回答
如果你有一个原始的回购(或HEAD未设置)[1],你可以简单地
rm .git/index
当然,这将要求您重新添加您想要添加的文件。
[1]注意(正如评论中解释的那样)这通常只会在回购是全新的(“原始”)或没有提交时发生。更严格地说,当没有签出或工作树时。
只是想说得更清楚一点:)
警告:不要使用以下命令,除非您想丢失未提交的工作!
使用git重置已经解释过了,但是你要求对管道命令进行解释,所以这里是:
git ls-files -z | xargs -0 rm -f
git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached
命令git ls-files列出git知道的所有文件。选项-z对它们施加特定的格式,即xargs -0所期望的格式,然后对它们调用rm -f,这意味着在不检查您的批准的情况下删除它们。
换句话说,“列出git知道的所有文件并删除本地副本”。
Then we get to git diff, which shows changes between different versions of items git knows about. Those can be changes between different trees, differences between local copies and remote copies, and so on. As used here, it shows the unstaged changes; the files you have changed but haven't committed yet. The option --name-only means you want the (full) file names only and --diff-filter=D means you're interested in deleted files only. (Hey, didn't we just delete a bunch of stuff?) This then gets piped into the xargs -0 we saw before, which invokes git rm --cached on them, meaning that they get removed from the cache, while the working tree should be left alone — except that you've just removed all files from your working tree. Now they're removed from your index as well.
换句话说,所有的更改(阶段性的或非阶段性的)都消失了,您的工作树是空的。哭一场,从原始文件或远程文件签出你的文件,然后重做你的工作。诅咒写下这些地狱般的诗句的施虐狂;我完全不知道为什么会有人想这么做。
TL, DR:你刚刚冲洗了所有东西;从现在开始重新开始使用git重置。
如果HEAD没有设置(也就是说,您还没有提交,但您不想因为已经设置了其他想要保留的回购配置而放弃.git),您也可以这样做
git rm -rf --cached .
把一切都取消。这实际上与sehe的解决方案相同,但避免了Git内部的混乱。
恐怕第一个命令行会无条件地从工作副本中删除git暂存区的所有文件。第二种方法取消了所有被跟踪的文件,但现在已经删除了。不幸的是,这意味着您将丢失对这些文件的所有未提交的修改。
如果你想让你的工作副本和索引恢复到上次提交时的状态,你可以(小心地)使用以下命令:
git reset --hard
我说“小心”,因为git重置-hard将删除你的工作副本和索引中未提交的更改。然而,在这种情况下,听起来好像您只是想回到上次提交时的状态,而未提交的更改无论如何都会丢失。
更新:从你对Amber的回答的评论中,听起来你还没有创建任何提交(因为HEAD无法解析),所以这恐怕不会有帮助。
As for how those pipes work: git ls-files -z and git diff --name-only --diff-filter=D -z both output a list of file names separated with the byte 0. (This is useful, since, unlike newlines, 0 bytes are guaranteed not to occur in filenames on Unix-like systems.) The program xargs essentially builds command lines from its standard input, by default by taking lines from standard input and adding them to the end of the command line. The -0 option says to expect standard input to by separated by 0 bytes. xargs may invoke the command several times to use up all the parameters from standard input, making sure that the command line never becomes too long.
举个简单的例子,如果你有一个名为test.txt的文件,包含以下内容:
hello
goodbye
hello again
... 然后命令xargs echo whatever < test.txt将调用该命令:
echo whatever hello goodbye hello again
如果你想取消所有的更改使用下面的命令,
git reset --soft HEAD
如果您想取消阶段更改并从工作目录恢复它们,
git reset --hard HEAD