Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does checkout sometimes stage a file?

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?

like image 407
Keith Pinson Avatar asked Jan 09 '23 19:01

Keith Pinson


2 Answers

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.

like image 102
wonce Avatar answered Jan 15 '23 23:01

wonce


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.

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 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.

like image 34
VonC Avatar answered Jan 15 '23 23:01

VonC