为什么 "git checkout <filename>" 只适用于非暂存文件?

Why does "git checkout <filename>" only work for non-staged files?

如果我提交然后对文件进行更改 foo,我可以通过 git checkout foo 撤消这些更改。如果我更改 foo 并用 git add foo 添加它们,那么 git checkout foo 不会做任何事情(也不会说任何事情)

这背后的原因是什么?

因为您可以取消暂存它然后再检查它:)

git reset <file>

git checkout <file>

之所以不检查它们,是因为如果您在本地更改文件,然后想更新到 master 分支,例如,您的工作和暂存文件应该被覆盖。

当你说

git checkout foo

在没有额外参数的情况下,您告诉 git 将工作树中的 foo 替换为索引中的 foo。因此,如果您 added(即上演,即 更新索引 )对 foo 的所有更改,那么当然没有任何内容 checkout要执行的命令。

取消更改的正常程序是首先 reset(从 HEAD 提交更新索引)然后 然后 使用 checkout 更新工作版本。

然后,您可以使用checkout从上一次提交

中获取foo的版本
git checkout HEAD foo

这同样有效;两步法可能只是更广为人知,因为它使用 git status 建议的命令来取消暂存和取消更改。

使用 Git 2.23(2019 年 8 月),您现在可以避免使用 confusing git checkout command (which deals with files or branches), and the new (still experimental) git restore command.

You can restore both the index and the working tree (this the same as using git-checkout)

git restore --source=HEAD --staged --worktree hello.c

or the short form which is more practical but less readable:

git restore -s@ -SW hello.c

这将恢复工作树 暂存区(缓存)。