如果我在暂存区域中有一个文件(显示在 中git diff --cached
)并且我想完全删除它,我该怎么做?
正在做
git reset HEAD -- file
git checkout -- file
是这样,但是这 2 个动作有 1 个命令吗?
是的:
git checkout HEAD -- file
成功了。
关于这一点,有很多(太多,有时)需要了解的事情。首先,索引(也称为暂存区或缓存)始终保存所有要提交的文件。事实上,每个文件在索引中的存在意味着文件将被提交,以它在索引中的形式。这就是为什么你必须一直这样做:Git 不会将它从工作树复制到索引中,覆盖旧的索引版本,直到你告诉 Git 这样做。git add file
当您最初签出某个提交时,索引通常也会保存该提交中每个文件的副本。有一些例外(有关详细信息,请参阅Checkout another branch when there are uncommitted changes on current branch),但通常初始设置是:
HEAD index work-tree
-------------------------------
README.md README.md README.md
file1.txt file1.txt file1.txt
依此类推,每个文件的所有三个版本都匹配.
但是,每个副本之间都有一些细微但重要的区别:
提交中的副本 inHEAD
是只读的。没有什么可以改变这个副本。(当然,HEAD
它本身可以更改为另一个不同的提交;不同的提交可以有文件的不同副本,或者可能根本没有文件。)文件的提交副本位于特殊的 Git-only格式。
索引/暂存区中的副本是读/写的。不过,此副本也是特殊的仅 Git 格式。您可以随时将该文件的不同版本复制到索引中,甚至删除索引条目。
工作树中的副本是您计算机的正常格式。你可以用它做任何你喜欢的事情,受你的计算机施加的任何限制。
做什么git status
——嗯,它做的许多事情之一——是进行两次比较:
索引中HEAD
的内容与索引中的内容。无论有什么不同,Git 都会将其列为暂存提交。
索引中的内容与工作树中的内容。无论有什么不同,Git 都会将其列为未暂存提交。
这意味着您不必费力地浏览大量相同的东西;你只看到有什么不同。
git add
= 从工作树复制到索引Using将工作树版本复制到索引中。这很简单!当然,Git 就是 Git,还有更多种类,但我们暂时忽略它们。:-)git add path
git add
git reset
= ...好吧,这很复杂该git reset
命令做了太多不同的事情。但是,如果您坚持使用git reset -- path
,它会简化很多:这意味着从HEAD
提交复制到索引。工作树副本保持不变。
git checkout
= 复制自...好吧,这也很复杂该git checkout
命令,如git reset
,做了太多不同的事情。但是,如果您坚持使用这两种形式,我们会得到两件容易解释的事情:
git checkout -- path
从索引复制到工作树。
git checkout HEAD -- path
从HEAD
提交复制到索引,然后从索引复制到工作树。
这里缺少一个选项:没有简单的方法可以HEAD
绕过索引从提交复制到工作树。(有几种方法可以做到这一点,但它们有一些警告。)
你不能在HEAD
版本上写,所以没有办法复制到HEAD
. 相反,您将运行git commit
,它会进行新的提交,永远冻结索引副本(每个文件的!)。然后新的提交成为提交HEAD
。当您运行时,所有文件在索引中都已经处于最终形式,这一事实是速度如此之快git commit
的部分原因。git commit
您可以使用git reset filename.txt
这将从暂存区域中删除一个名为 filename.txt 的文件。
您还可以使用git reset
取消暂存所有文件。
祝你好运!
要从暂存区域中删除单个文件,您可以使用:
git reset HEAD -- <file>
要从暂存区域中删除整个目录或文件夹,您可以使用:
git reset HEAD -- <directoryName>
对于较新版本的 Git,您还可以使用:git restore --staged <file>.
有时您可能还需要删除缓存:git rm -r --cached .