为什么结帐有时会暂存一个文件?

Why does checkout sometimes stage a file?

当我第一次开始使用 Git 时,我发现 checkout 命令相当混乱。然而,当我适应 Git 的版本控制模型时,它开始变得有意义了。现在我不得不教我的同事Git,我试图简单地解释checkout。我以为我有一个简单的解释(来自documentation):

Checkout a branch or paths to the working tree

这似乎统一了您可以通过结帐执行的一些操作,对于 Git 的新手来说,这些操作似乎是一组不同的操作:

git checkout .
git checkout HEAD .
git checkout HEAD~2
git checkout feature/update-readme README.md

...除了最后一个,因为它不仅会更新工作目录,还会暂存文件。

我如何理解为什么或何时结帐会导致暂存某些内容而不只是复制到工作目录中?

git checkout 实际上总是暂存所有已签出的文件。但是,如果您没有指定路径(如前三个示例所示),您的 HEAD 也将设置为您签出的提交,因此您的阶段与您的 HEAD 相同,即没有要提交的更改。

How can I understand why or when checkout out will result in having something staged instead of just copied into the working directory?

从 Git 2.21(2019 年第一季度)开始,您将确切知道 git checkout 何时修改文件(而不是 HEAD 或分支):“git checkout [<tree-ish>] path...”学会了报告已从索引或树结构中检出的路径数,这使其具有与命令检出分支的情况相同的噪声程度。

参见 commit 0f086e6 (13 Nov 2018) by Nguyễn Thái Ngọc Duy (pclouds)
(由 Junio C Hamano -- gitster -- in commit 4084df4 合并,2019 年 1 月 14 日)

checkout: print something when checking out paths

One of the problems with "git checkout" is that it does so many different things and could confuse people specially when we fail to handle ambiguation correctly.

One way to help with that is tell the user what sort of operation is actually carried out. When switching branches, we always print something unless --quiet, either:

HEAD is now at ..."
Reset branch ..."
Already on ..."
Switched to and reset ..."
Switched to a new branch ..."
Switched to branch ..."

Checking out paths however is silent.

Print something so that if we got the user intention wrong, they won't waste too much time to find that out.

For the remaining cases of checkout we now print either:

Checked out ... paths out of the index
Checked out ... paths out of <abbrev hash>

Since the purpose of printing this is to help disambiguate, only do it when "--" is missing.

然而:“git checkout [<tree-ish>] <pathspec>”开始报号 最近更新的路径,但相同的消息 在 "git checkout -m <pathspec>" 时给出以解决冲突 刚解决。
该消息现在将这些未解析的路径与从索引中检出的路径分开报告。

参见 commit 1d1f689, commit 3c5883b (06 Feb 2019) by Nguyễn Thái Ngọc Duy (pclouds)
(由 Junio C Hamano -- gitster -- in commit 87c9831 合并,2019 年 2 月 9 日)

checkout: count and print -m paths separately

Since 0f086e6 (checkout: print something when checking out paths - 2018-11-13), this command reports how many paths have been updated from what source (either from a tree, or from the index).
I forget that there's a third source: when -m is used, the merge conflict is re-created (granted, also from the index, but it's not a straight copy from the index).

Count and report unmerged paths separately.
There's a bit more update to avoid reporting:

Recreated X merge conflicts
Updated 0 paths from the index

The second line is unnecessary. Though if there's no conflict recreation, we still report

Updated 0 paths from the index

to make it clear we're not really doing anything.