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.