本文翻译自:How to unstage large number of files without deleting the content
I accidentally added a lot of temporary files using git add -A
我不小心使用git add -A
添加了很多临时文件
I managed to unstage the files using the following commands and managed to remove the dirty index. 我设法使用以下命令取消暂存文件,并设法删除脏索引。
git ls-files -z | xargs -0 rm -f
git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached
The above commands are listed in the git help rm
. 上面的命令列在git help rm
。 But sadly, my files were also deleted on execution, even though I had given cache option. 但遗憾的是,我的文件在执行时也被删除了,即使我已经给出了缓存选项。 How can I clear the index without losing the content? 如何在不丢失内容的情况下清除索引?
Also it would be helpful if someone can explain the way this pipe operation works. 如果有人能解释这个管道操作的工作方式,也会有所帮助。
#1楼
参考:https://stackoom.com/question/Tnyh/如何在不删除内容的情况下取消大量文件
#2楼
git stash && git stash pop
#3楼
If HEAD isn't set, you can also do 如果未设置HEAD,您也可以这样做
git rm -rf --cached .
to unstage everything. 展开一切。 This is effectively the same as sehe's solution, but avoids mucking with Git internals. 这实际上与sehe的解决方案相同,但避免与Git内部结合。
#4楼
git reset
If all you want is to undo an overzealous "git add" run: 如果你想要的是撤消一个过于热心的“git add”运行:
git reset
Your changes will be unstaged and ready for you to re-add as you please. 您的更改将无法进行,并随时可以重新添加。
DO NOT RUN git reset --hard
. 不要运行git reset --hard
。
It will not only unstage your added files, but will revert any changes you made in your working directory. 它不仅会取消暂存您添加的文件,还会还原您在工作目录中所做的任何更改。 If you created any new files in working directory, it will not delete them though. 如果您在工作目录中创建了任何新文件,它将不会删除它们。
#5楼
If you want to unstage all the changes use below command, 如果要使用以下命令取消暂存所有更改,
git reset --soft HEAD
In the case you want to unstage changes and revert them from the working directory, 如果您要取消暂停更改并将其从工作目录还原,
git reset --hard HEAD
#6楼
Warning: do not use the following command unless you want to lose uncommitted work! 警告:除非您想丢失未提交的工作,否则请勿使用以下命令!
Using git reset
has been explained, but you asked for an explanation of the piped commands as well, so here goes: 已经解释了使用git reset
,但是你也要求解释管道命令,所以这里有:
git ls-files -z | xargs -0 rm -f
git diff --name-only --diff-filter=D -z | xargs -0 git rm --cached
The command git ls-files
lists all files git knows about. 命令git ls-files
列出了git知道的所有文件。 The option -z
imposes a specific format on them, the format expected by xargs -0
, which then invokes rm -f
on them, which means to remove them without checking for your approval. 选项-z
对它们施加特定的格式, xargs -0
期望的格式,然后在它们上调用rm -f
,这意味着删除它们而不检查您的批准。
In other words, "list all files git knows about and remove your local copy". 换句话说,“列出git知道并删除本地副本的所有文件”。
Then we get to git diff
, which shows changes between different versions of items git knows about. 然后我们得到git diff
,它显示了git知道的不同版本项之间的变化。 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. 选项--name-only
表示--name-only
需要(完整)文件名,而--diff-filter=D
表示您只对已删除的文件感兴趣。 (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. (嘿,我们不是刚刚删除了一堆东西吗?)然后通过管道输入我们之前看到的xargs -0
,它会调用git rm --cached
在它们上面,这意味着它们会从缓存中移除,同时工作树应该保持不变 - 除了你刚从工作树中删除了所有文件。 Now they're removed from your index as well. 现在它们也从索引中删除了。
In other words, all changes, staged or unstaged, are gone, and your working tree is empty. 换句话说,所有已暂存或未暂存的更改都将消失,并且您的工作树为空。 Have a cry, checkout your files fresh from origin or remote, and redo your work. 哭泣,从原产地或远程检查你的文件,并重做你的工作。 Curse the sadist who wrote these infernal lines; 诅咒写下这些地狱线的虐待狂; I have no clue whatsoever why anybody would want to do this. 我不知道为什么有人想要这样做。
TL;DR: you just hosed everything; TL; DR:你只是灌输了一切; start over and use git reset
from now on. 重新开始并从现在开始使用git reset
。