删除暂存文件并重置为原始版本
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 .
如果我在暂存区中有一个文件(显示在 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 .