删除暂存文件并重置为原始版本

Remove staged file and reset to original version

如果我在暂存区中有一个文件(显示在 git diff --cached 中)并且我想完全删除它,我该怎么做?
正在做

git reset HEAD -- file  
git checkout -- file  

可以,但是这 2 个操作有 1 个命令吗?

您可以使用git reset filename.txt

这将从暂存区中删除名为 filename.txt 的文件。

您还可以使用 git reset 取消暂存所有文件。

祝你好运!

是:

git checkout HEAD -- file

成功了。

有很多背景的较长版本

关于此有很多(有时太多)事情要了解。首先,索引(也称为暂存区缓存)保存所有 files-to-be-committed 在 所有时间。事实上,每个文件在 索引中的存在意味着文件将以其在索引中的形式提交。这就是为什么你必须一直做git添加<em>文件</em>:Git 不会将它从 work-tree 复制到索引中,覆盖 旧的 索引版本,直到您告诉 Git 这样做。

当您最初签出某些提交时,索引通常也包含该提交中的每个文件的副本。有一些例外(详情请参阅 Checkout another branch when there are uncommitted changes on the current branch),但通常初始设置为:

  HEAD      index     work-tree
-------------------------------
README.md  README.md  README.md
file1.txt  file1.txt  file1.txt

依此类推,每个文件的所有三个版本匹配

虽然每个副本之间存在一些细微但重要的差异:

  • HEAD 中提交的副本是 read-only。 没有任何内容 可以更改此副本。 (当然,HEAD 本身可以更改为另一个不同的提交;不同的提交可以有文件的不同副本,或者可能根本没有文件。)文件的提交副本位于一种特殊的 Git-only 格式。

  • 索引/staging-area中的副本是read/write。不过,此副本也采用特殊的 Git-only 格式。您可以随时将该文件的不同版本复制到索引中,甚至删除索引条目。

  • work-tree 中的副本是您计算机的正常格式。您可以用它做任何您想做的事,但要遵守您的计算机施加的任何限制。

git status 所做的——嗯,它所做的众多事情之一——是 运行 两个 比较:

  • HEAD 中的内容与索引中的内容。无论 不同 ,Git 列为准备提交。

  • 索引中的内容与 work-tree 中的内容。 不同,Git 列为未准备提交。

这意味着您不必费力地浏览所有相同的庞大列表;你只看到不同.

git add = 从 work-tree 复制到索引

使用 git 添加 <em>path</em> 将 work-tree 版本复制到索引中。这很简单!当然,Git是Git,git add的种类更多,但我们暂时忽略它们。 :-)

git reset = ...嗯,很复杂

git reset 命令做了太多不同的事情。但是,如果你坚持使用 git 重置——<em>path</em>,它会简化很多: 这意味着 HEAD 提交复制到索引 。 work-tree 副本保持不变。

git checkout = copy from ...嗯,也很复杂

git checkout 命令与 git reset 一样,可以做很多不同的事情。但是,如果您坚持使用这两种形式,我们会得到两件很容易解释的事情:

  • git checkout -- <em>path</em> 从索引复制到 work-tree .

  • git checkout HEAD -- <em>path</em>HEAD 提交的副本索引,然后从索引到 work-tree.

这里缺少一个选项:没有简单的方法可以绕过索引从 HEAD 提交复制到 work-tree。 (有几种方法可以做到这一点,但它们有一些注意事项。)

无法在HEAD版本上写入,所以无法复制到HEAD。相反,您将 运行 git commit,这会进行 new 提交,永远冻结(每个文件的!)索引副本。然后新提交 变成 HEAD 提交。事实上,当您 运行 git commit 时,所有文件都已在索引中以其最终形式存在,这是 git commit 如此之快的部分原因。

要从暂存区中删除单个文件,您可以使用:

git reset HEAD -- <file>

要从暂存区中删除整个目录或文件夹,您可以使用:

git reset HEAD -- <directoryName>

对于 Git 的较新版本,您还可以使用:git restore --staged <file>.

有时您可能还需要删除缓存:git rm -r --cached .