我不小心用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中列出。但遗憾的是,我的文件在执行时也被删除了,即使我给了缓存选项。如何在不丢失内容的情况下清除索引?

此外,如果有人能解释这个管道操作的工作方式,这将是有帮助的。


当前回答

2019年更新

正如其他人在相关问题中指出的(参见这里,这里,这里,这里,这里,这里,这里和这里),你现在可以用git restore—staging <file>取消文件的阶段。

要取消项目中的所有文件,从存储库的根目录运行以下命令(该命令是递归的):

git restore --staged .

如果你只想取消一个目录中的文件,在运行上述操作之前导航到它或运行:

git restore --staged <directory-path>

笔记

git restore was introduced in July 2019 and released in version 2.23. With the --staged flag, it restores the content of the working tree from HEAD (so it does the opposite of git add and does not delete any change). This is a new command, but the behaviour of the old commands remains unchanged. So the older answers with git reset or git reset HEAD are still perfectly valid. When running git status with staged uncommitted file(s), this is now what Git suggests to use to unstage file(s) (instead of git reset HEAD <file> as it used to prior to v2.23).

其他回答

如果你有一个原始的回购(或HEAD未设置)[1],你可以简单地

rm .git/index

当然,这将要求您重新添加您想要添加的文件。


[1]注意(正如评论中解释的那样)这通常只会在回购是全新的(“原始”)或没有提交时发生。更严格地说,当没有签出或工作树时。

只是想说得更清楚一点:)

恐怕第一个命令行会无条件地从工作副本中删除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没有设置(也就是说,您还没有提交,但您不想因为已经设置了其他想要保留的回购配置而放弃.git),您也可以这样做

git rm -rf --cached .

把一切都取消。这实际上与sehe的解决方案相同,但避免了Git内部的混乱。

git stash && git stash pop

如果你想取消所有的更改使用下面的命令,

git reset --soft HEAD

如果您想取消阶段更改并从工作目录恢复它们,

git reset --hard HEAD