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

Git 如何在不删除内容的情况下取消显示大量文件,git,version-control,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中。但遗憾的是,我的文件在执行时也被删除了,尽管我已经给了缓存选项。如何在不丢失内容的情况下清除索引 另外,如果有人能够解释管道操作的工作方式,也会很有帮助。使用git rese

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


另外,如果有人能够解释管道操作的工作方式,也会很有帮助。

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

shell中的管道操作符获取左侧进程的
stdout
,并将其作为
stdin
传递到右侧进程。它本质上相当于:

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

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

恐怕第一个命令行会无条件地从工作区中删除git暂存区中的所有文件。第二个选项取消了所有跟踪但现在已被删除的文件的分级。不幸的是,这意味着您将丢失对这些文件的任何未提交的修改

如果要使工作副本和索引恢复到上次提交时的状态,可以(小心地()使用以下命令:

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

更新:从您对Amber答案的评论中可以看出,您还没有创建任何提交(因为HEAD无法解析),所以恐怕这不会有帮助

至于这些管道的工作方式:
gitls files-z
git diff--name only--diff filter=D-z
都输出一个文件名列表,文件名以字节
0
分隔。(这很有用,因为与换行不同,
0
字节保证不会出现在类Unix系统的文件名中。)程序
xargs
基本上是从标准输入中生成命令行,默认情况下,从标准输入中获取行并将它们添加到命令行的末尾。
-0
选项表示希望标准输入以
0
字节分隔
xargs
可以多次调用该命令以使用标准输入中的所有参数,确保命令行不会变得太长

举个简单的例子,如果您有一个名为
test.txt
的文件,其中包含以下内容:

hello
goodbye
hello again
。。。然后命令
xargs echo which
将调用该命令:

echo whatever hello goodbye hello again

如果你有一个原始的回购协议(或未设定本金)[1],你可以

rm .git/index
当然,这将要求您重新添加您确实希望添加的文件


[1]注意(如评论中所述),这通常只会发生在回购是全新的(“原始”)或未作出承诺的情况下。更严格地说,当没有签出或工作树时

更清楚一点:)

如果HEAD没有设置(即,您还没有提交,但您不想因为已经设置了其他要保留的repo配置而将其吹走,您也可以这样做

git rm -rf --cached .
把一切都拆开。这实际上与sehe的解决方案相同,但避免了Git内部的混乱。

Git reset
如果您只想撤消一次过于热心的“git add”运行:

您所做的更改将取消分级,并可随时重新添加


不要运行
git reset--hard


它不仅会取消您添加的文件的存储,还会恢复您在工作目录中所做的任何更改。如果您在工作目录中创建了任何新文件,它将不会删除这些文件。

如果要取消显示所有更改,请使用下面的命令

git reset --soft HEAD
如果要取消保存更改并将其从工作目录还原

git reset --hard HEAD

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

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

换句话说,“列出git知道的所有文件并删除本地副本”

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

在其他方面
git reset --hard HEAD
git ls-files -z | xargs -0 rm -f
git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached