我不小心用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 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 reset --soft HEAD

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

git reset --hard HEAD

警告:不要使用以下命令,除非您想丢失未提交的工作!

使用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重置。

使用git reset HEAD重置索引而不删除文件。(如果你只想重置索引中的一个特定文件,你可以使用git reset HEAD——/path/to/file来这样做。)

在shell中,管道操作符从左边的进程中获取标准输出,并将其作为标准输入传递给右边的进程。它本质上相当于:

$ proc1 > proc1.out
$ proc2 < proc1.out
$ rm proc1.out

但是它是$ proc1 | proc2,第二个进程可以在第一个进程输出数据之前开始获取数据,并且不涉及实际的文件。

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

rm .git/index

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


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

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