如何在不删除内容的情况下取消大量文件

时间:2011-08-18 07:07:21

标签: git version-control

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

如果有人能解释这种管道操作的工作方式,那将会很有帮助。

9 个答案:

答案 0 :(得分:886)

git reset

如果你想要的只是撤消一个过于热心的" git add"运行:

git reset

您的更改将无法使用,随时可以重新添加。


不要跑git reset --hard

它不仅会取消暂存您添加的文件,还会还原您在工作目录中所做的任何更改。如果您在工作目录中创建了任何新文件,则 >将删除它们。

答案 1 :(得分:34)

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

rm .git/index

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


[1] 注意(如评论中所述)这通常只会在回购是全新的时候发生(“原始” “)或者如果没有提交。更技术上,只要没有结账或工作树。

让它更清楚:)

答案 2 :(得分:14)

使用git reset HEAD重置索引而不删除文件。 (如果您只想重置索引中的特定文件,可以使用git reset HEAD -- /path/to/file来执行此操作。)

管道运算符在shell中,获取左侧进程的stdout,并将其作为stdin传递给右侧的进程。它基本上是 相当于:

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

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

答案 3 :(得分:8)

git stash && git stash pop

答案 4 :(得分:8)

如果未设置HEAD,您也可以

git rm -rf --cached .

取消一切。这实际上与sehe的解决方案相同,但避免与Git内部结合。

答案 5 :(得分:5)

警告:除非您想丢失未提交的工作,否则请勿使用以下命令!

已经解释了使用git reset,但您也要求解释管道命令,所以这里有:

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,这意味着在不检查您的批准的情况下删除它们。

换句话说,&#34;列出git知道的所有文件并删除您的本地副本&#34;。

然后我们到达git diff,它显示了git知道的不同版本项目之间的变化。这些可以是不同树之间的变化,本地副本和远程副本之间的差异,等等 如此处所示,它显示了未分级的变化;您已更改但尚未提交的文件。选项--name-only表示您只需要(完整)文件名,--diff-filter=D表示您只对已删除的文件感兴趣。 (嘿,我们没有删除一堆东西?) 然后通过管道传输到我们之前看到的xargs -0,它会在它们上面调用git rm --cached,这意味着它们会从缓存中删除,而工作树应该保持不变 - 除了你自己刚删除工作树中的所有文件。现在他们也从索引中删除了。

换句话说,所有已暂存或未分阶段的更改都已消失,您的工作树已空。哭泣,从原产地或远程检查你的文件,并重做你的工作。诅咒写下这些地狱线的虐待狂;我不知道为什么有人想要这样做。

TL; DR:你只是把所有东西都洗了;重新开始并从现在开始使用git reset

答案 6 :(得分:2)

我担心这些命令行中的第一个无条件地从工作副本中删除了git的暂存区域中的所有文件。第二个未分阶段已跟踪但已被删除的所有文件。不幸的是,这意味着您将丢失对这些文件的任何未提交的修改。

如果您希望将工作副本和索引恢复为上次提交,您可以(小心)使用以下命令:

git reset --hard

我说“小心”,因为git reset --hard 将删除您的工作副本和索引中未提交的更改。但是,在这种情况下,听起来好像你只想回到上一次提交时的状态,无论如何都会丢失未提交的更改。

更新:从您对Amber的答案的评论来看,你还没有创建任何提交(因为HEAD无法解决),所以这无济于事,我很害怕。 < / p>

关于这些管道如何工作:git ls-files -zgit diff --name-only --diff-filter=D -z都输出用字节0分隔的文件名列表。 (这很有用,因为与新行不同,0字节保证不会出现在类Unix系统的文件名中。)程序xargs实际上是从其标准输入构建命令行,默认情况下是来自标准输入的行,并将它们添加到命令行的末尾。 -0选项表示期望标准输入以0字节分隔。 xargs可以多次调用该命令以耗尽标准输入中的所有参数,确保命令行永远不会变得太长。

作为一个简单示例,如果您有一个名为test.txt的文件,则包含以下内容:

hello
goodbye
hello again

...然后命令xargs echo whatever < test.txt将调用命令:

echo whatever hello goodbye hello again

答案 7 :(得分:1)

如果要取消所有更改,请使用以下命令,

git reset --soft HEAD

如果您要取消暂停更改并将其从工作目录还原,

git reset --hard HEAD

答案 8 :(得分:1)

2019更新:

其他人指出,hereherehereherehereherehere ,您现在也可以使用git restore --staged .来做到这一点。

git restoreJuly 2019中引入,并在2.23版中发布。除其他用法外,它还可以还原索引的内容(即,取消暂存未提交的文件)。

在对暂存的未提交文件运行git status时,Git建议现在使用它来暂存文件(而不是v2.23之前的git reset HEAD <file>)。

因此,为了取消登台所有未提交的文件,可以从项目的根目录运行:

git restore --staged .