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?
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.
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 pathsOne 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.
However: "git checkout [<tree-ish>] <pathspec>
" started reporting the number
of paths that have got updated recently, but the same messages were
given when "git checkout -m <pathspec>
" to unresolve conflicts that
have just been resolved.
The message now reports these unresolved paths separately from the paths that are checked out from the index.
See commit 1d1f689, commit 3c5883b (06 Feb 2019) by Nguyễn Thái Ngọc Duy (pclouds
).
(Merged by Junio C Hamano -- gitster
-- in commit 87c9831, 09 Feb 2019)
checkout
: count and print-m
paths separatelySince 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.
来源:https://stackoverflow.com/questions/28837246/why-does-checkout-sometimes-stage-a-file