Reputation: 39603
The git checkout-index
command copies files from the index to the working tree.
The documentation includes a cryptic remark about its -u
or --index
command-line parameter:
-u
--index
update stat information for the checked out entries in the index file.
What is "stat information?" What's the difference between updating it and not updating it?
I find that in simple experiments, git checkout-index
just writes files to the working tree, as you'd expect; I can't see any difference between using -u
/--index
and not using it.
Upvotes: 4
Views: 3873
Reputation: 1329892
While git-checkout-index
does copy data from the index to the working tree, it has an annoying bug before Git 2.30 (Q1 2021): "git checkout-index
"(man) did not consistently signal an error with its exit status.
See commit 7e41061, commit 0b809c8 (27 Oct 2020) by Jeff King (peff
).
(Merged by Junio C Hamano -- gitster
-- in commit 92d6bd2, 09 Nov 2020)
checkout-index
: propagate errors to exit codeSigned-off-by: Jeff King
If we encounter an error while checking out an explicit path, we print a message to stderr but do not actually exit with a non-zero code.
While this is a plumbing command and the behavior goes all the way back to 33db5f4d90 (Add a "checkout-cache" command which does what the name suggests., 2005-04-09, Git v0.99), this is almost certainly an oversight:
- we do return an exit code from
checkout_file()
; the caller just never reads it- errors while checking out all paths (with "
-a
") do result in a non-zero exit code.- it would be quite unusual not to use the exit code for an error, as otherwise the caller has no idea the command failed except by scraping stderr
To keep our tests simple and portable, we can use the most obvious error: asking to checkout a path which is not in the index at all.
Upvotes: 0
Reputation: 177895
git-checkout-index
copies data from the index to the working tree. git-update-index
copies metadata from the working tree to the index.
These are low-level commands which need to be specifically told what to do.
That this option exists at all is a wonder of user interface design a useful option to ensure that git's index reflects a consistent view of the working tree after the operation has been performed.
Specifically, this updates (at least) the metadata that doesn't contribute to a git repository but rather is used to determine if files are unchanged. See How to get a human-readable dump of .git/index? and What does the git index contain EXACTLY?.
Added in 415e96c.
By way of an example, I'll follow along with t/t2002-checkout-cache-u.sh
, which runs the command first without and then with -u
(again, that's "the equivalent of git update-index --refresh on the checked out entry").
1) preparation:
echo frotz >path0 &&
git update-index --add path0 &&
t=$(git write-tree)
2) without -u, git checkout-index smudges stat information.
rm -f path0 &&
git read-tree $t &&
git checkout-index -f -a &&
git diff-files --exit-code
output of diff-files:
:100644 100644 8e4020bb5a8d8c873b25de15933e75cc0fc275df 0000000000000000000000000000000000000000 M path0
--> 1
see what's in the index:
$ git ls-files --debug
path0
ctime: 0:0
mtime: 0:0
dev: 0 ino: 0
uid: 0 gid: 0
size: 0 flags: 0
3) with -u, git checkout-index picks up stat information from new files.
rm -f path0 &&
git read-tree $t &&
git checkout-index -u -f -a &&
git diff-files --exit-code
(returns 0)
now the stat(2) is there:
$ git ls-files --debug
path0
ctime: 1491479474:0
mtime: 1491479474:0
dev: 16777220 ino: 50556411
uid: 501 gid: 20
size: 6 flags: 0
Apart from the stat information being recorded, there's one other interesting bit in the output. Why does git-diff-files
say there are differences between the working tree and the index?
The manual says that field in the output is
sha1 for "dst"; 0{40} if creation, unmerged or "look at work tree".
<sha1> is shown as all 0’s if a file is new on the filesystem and it is out of sync with the index.
So this test case is illustrating one way git uses the metadata information: When comparing files in the working tree and the index. If the stat information looks stale (or all zeroes), then the file might have changed. Since git-read-tree
only writes to the index, and not the working tree, it necessarily invalidates the stat information. And if the stat information is valid, git-diff-files
can confidently give the blob ID for that entry.
Upvotes: 3