我不小心使用 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
中 . 但遗憾的是,我的文件在执行时也被删除了,即使我已经给出了缓存选项 . 如何在不丢失内容的情况下清除索引?
如果有人能解释这个管道操作的工作方式,也会有所帮助 .
8 回答
git重置
如果你想要的是撤消一个过于热心的“git add”运行:
您的更改将无法进行,并随时可以重新添加 .
DO NOT RUN git reset --hard.
它不仅会取消暂存您添加的文件,还会还原您在工作目录中所做的任何更改 . 如果您在工作目录中创建了任何新文件,则 will not 会删除它们 .
如果你有一个原始的回购(或没有设置HEAD) [1] 你可以简单
当然,这将要求您重新添加您想要添加的文件 .
[1] 注意(如评论中所述)这通常只会在回购是全新的("pristine")或者没有提交时才会发生 . 更技术上,只要没有结账或工作树 .
只是让它更清楚:)
使用
git reset HEAD
重置索引而不删除文件 . (如果您只想重置索引中的特定文件,可以使用git reset HEAD -- /path/to/file
来执行此操作 . )shell中的管道运算符在左侧获取进程的
stdout
,并将其作为stdin
传递给右侧的进程 . 它基本上相当于:但是它是
$ proc1 | proc2
,第二个进程可以在第一个进程输出数据之前开始获取数据,并且没有涉及的实际文件 .如果未设置HEAD,您也可以这样做
展开一切 . 这实际上与sehe的解决方案相同,但避免与Git内部结合 .
Warning: do not use the following command unless you want to lose uncommitted work!
已经解释了使用
git reset
,但是你也要求解释管道命令,所以这里是:命令
git ls-files
列出了git知道的所有文件 . 选项-z
对它们施加了特定的格式,xargs -0
期望的格式,然后在它们上调用rm -f
,这意味着删除它们而不检查您的批准 .换句话说,“列出git知道并删除本地副本的所有文件” .
然后我们到达
git diff
,它显示了git知道的不同版本项之间的变化 . 这些可以是不同树之间的更改,本地副本和远程副本之间的差异,等等 .如此处所示,它显示了未分级的变化;您已更改但尚未提交的文件 . 选项
--name-only
表示您只需要(完整)文件名,--diff-filter=D
表示您只对已删除的文件感兴趣 . (嘿,我们不是刚刚删除了一堆东西吗?)然后通过管道进入我们之前看到的xargs -0
,它们会调用git rm --cached
,这意味着它们会从缓存中删除,而工作树应该保持独立 - 除了你've just removed all files from your working tree. Now they'也从你的索引中删除 .换句话说,所有已暂存或未暂存的更改都将消失,并且您的工作树为空 . 哭泣,从原产地或远程检查你的文件,并重做你的工作 . 诅咒写下这些地狱线的虐待狂;我不知道为什么有人想要这样做 .
TL;DR: you just hosed everything; start over and use git reset from now on.
我担心这些命令行中的第一个无条件地从工作副本中删除了git的临时区域中的所有文件 . 第二个未分阶段已跟踪但已被删除的所有文件 . 不幸的是,这意味着您将丢失对这些文件的任何未提交的修改 .
如果要将工作副本和索引恢复到上次提交时的状态,可以( carefully )使用以下命令:
我说"carefully"自
git reset --hard
will obliterate uncommitted changes in your working copy 和索引 . 但是,在这种情况下,听起来好像您只是想在上一次提交时返回状态,并且无论如何都未丢失未提交的更改 .更新:它听起来你对Amber 's answer that you haven' t的评论但是创建了任何提交(因为HEAD无法解析),所以这让我害怕了.1108365_恐怕 .
至于这些管道是如何工作的:
git ls-files -z
和git diff --name-only --diff-filter=D -z
都输出一个文件列表用字节0
分隔的名称 . (这很有用,因为与换行符不同,0
字节保证不会出现在类Unix系统的文件名中 . )程序xargs
本质上是从其标准输入构建命令行,默认情况下从标准输入中取出行并将它们添加到命令行的结尾 .-0
选项表示期望标准输入由0
字节分隔 .xargs
可能会多次调用该命令以耗尽标准输入中的所有参数,从而确保命令行永远不会变得太长 .举个简单的例子,如果你有一个名为
test.txt
的文件,其中包含以下内容:...然后命令
xargs echo whatever < test.txt
将调用该命令:如果要使用以下命令取消暂存所有更改,
如果您要取消暂停更改并将其从工作目录还原,