Why does checkout sometimes stage a file?

2019-02-18 15:14发布

When I first started using Git, I found the checkout command quite confusing. However, as I adapted to Git's model of version control, it started to make sense. Now I am having to teach Git to my coworkers, and I'm trying to explain checkout simply. I thought I had a simple explanation (from the documentation):

Checkout a branch or paths to the working tree

That seems to unify some of the things you can do with checkout which seem like a diverse set of operations to someone new to Git:

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

...except for the last one, because that doesn't just update the working directory, it stages the file.

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

2条回答
\"骚年 ilove
2楼-- · 2019-02-18 15:37

git checkout does in fact always stage all the files checked out. But if you do not specify a path (as in your first three examples), your HEAD will also be set to the commit you checked out and therefore your stage is identical to your HEAD i.e. there are no changes to commit.

查看更多
做自己的国王
3楼-- · 2019-02-18 15:41

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

Starting with Git 2.21 (Q1 2019), you will know exactly when git checkout modifies a file (instead of HEAD or a branch): "git checkout [<tree-ish>] path..." learned to report the number of paths that have been checked out of the index or the tree-ish, which gives it the same degree of noisy-ness as the case in which the command checks out a branch.

See commit 0f086e6 (13 Nov 2018) by Nguyễn Thái Ngọc Duy (pclouds).
(Merged by Junio C Hamano -- gitster -- in commit 4084df4, 14 Jan 2019)

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.

查看更多
登录 后发表回答