如何在不删除内容的情况下取消大量的文件
我不小心使用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
中列出。 但不幸的是,我的文件也被删除执行,即使我已经给了caching选项。 如何清除索引而不丢失内容?
如果有人可以解释这种pipe道操作的方式,这也是有帮助的。
git reset
如果你想要的只是撤销一个过度热闹的“git add”运行:
git reset
您的更改将被取消,随时可以重新添加。
不要运行git reset --hard
。
它不仅会取消您添加的文件,还会恢复您在工作目录中所做的任何更改。 如果您在工作目录中创build了任何新文件,它将不会删除它们。
如果你有一个原始的回购(或头没有设置) [1]你可以简单地
rm .git/index
当然,这将需要您重新添加您想添加的文件。
注意(正如评论中所解释的),这通常只会在回购是全新的(“原始”)或者没有提交时才会发生。 更技术性地说,只要没有结账或工作树。
Jus使它更清楚:)
使用git reset HEAD
重置索引而不删除文件。 (如果你只想重置索引中的特定文件,可以使用git reset HEAD -- /path/to/file
来完成。)
pipe道操作员在一个shell中,将进程的stdout
放在左边,并将其作为stdin
传递给右边的进程。 它基本上相当于:
$ proc1 > proc1.out $ proc2 < proc1.out $ rm proc1.out
而是$ proc1 | proc2
$ proc1 | proc2
,第二个进程可以在第一个输出完成之前开始获取数据,并且不涉及实际的文件。
如果HEAD没有设置,你也可以这样做
git rm -rf --cached .
停止一切。 这和sehe的解决scheme实际上是一样的,但是避免使用Git内部。
git stash && git stash pop
警告:不要使用下面的命令,除非你想失去未提交的工作!
已经解释了使用git reset
,但是您也要求对pipe道命令进行解释,所以这里是:
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知道的文件并删除你的本地副本”。
然后我们得到git diff
,它显示了git知道的不同版本的项目之间的变化。 这些可以是不同树木之间的变化,本地副本和远程副本之间的差异等等。
正如这里所使用的,它显示了未分离的变化; 你已经改变但还没有提交的文件。 选项--name-only
意味着您--name-only
需要(完整)文件名,而--diff-filter=D
意味着您只对已删除的文件感兴趣。 (嘿,我们不是刚刚删除了一堆东西吗?)然后它被传入我们之前看到的xargs -0
,它调用了git rm --cached
对它们进行了caching,这意味着它们从caching中被移除,而工作树应该被单独留下 – 除了你刚刚从工作树中删除所有文件。 现在他们也从您的索引中删除。
换句话说,上演或未上架的所有变化都消失了,你的工作树是空的。 哭了起来,从原始或远程检查您的文件,并重做您的工作。 诅咒写下这些恶行的虐待者; 我不知道为什么有人会想这样做。
TL; DR:你刚刚把一切都弄清楚了; 从现在开始git reset
使用git reset
。
恐怕这些命令行中的第一个无条件地从工作副本中删除了所有在git临时区域中的文件。 第二个分离所有被跟踪的文件,但现在已经被删除。 不幸的是,这意味着你将失去对这些文件的任何未提交的修改。
如果你想让你的工作副本和索引返回到最后一次提交的方式 ,你可以( 仔细地 )使用下面的命令:
git reset --hard
我从git reset --hard
“仔细地”说出git reset --hard
将会消除你的工作副本和索引中未经改变的变化 。 但是,在这种情况下,听起来好像你只是想回到最后一次提交时的状态,而未提交的更改已经丢失了。
更新:这听起来来自你对Amber的回答的评论,你还没有创build任何提交(因为HEAD无法parsing),所以这恐怕没有帮助。
至于这些pipe道是如何工作的: git ls-files -z
和git diff --name-only --diff-filter=D -z
都会输出一个由字节0
分开的文件名列表。 (这很有用,因为与换行符不同,保证0
字节不会出现在类Unix系统上的文件名中)。程序xargs
实质上是从标准input构build命令行,默认情况下从标准input中获取行并将其添加到命令行的结尾。 -0
选项表示期望标准input由0
字节分隔。 xargs
可能会多次调用该命令来使用标准input中的所有参数,确保命令行不会变得太长。
举一个简单的例子,如果你有一个名为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