I was having an issue with renaming a file and was given a solution which included two git commands - git read-tree -i HEAD
and git checkout-index -a -f
. I seems to have figured out what the second one does and tested it, but I can't grasp why I would need the first one even for the simplest case. I thought that it somehow could substitue git add
command and add a file to index, however when I created a new file and run the command and then checked the contents of index with ls-files --staged
it didn't show this files as added, so probably my assumption about the purpose of the command is wrong. I also visited the manual page but still don't understand why I would need that command.
git read-tree
goes like this:
Parses a "tree-ish" passed to it to find an object existing in the Git repository describing a tree.
A tree is what represents a directory in Git: this kind of object lists the SHA-1 and filesystem names of blobs (files) and nested trees (of nested directories) comprising the tree. Each commit references exactly one tree which represents the state of the top-level project directory itself.
A "tree-ish" is a specification whish Git is able to parse down to the name of a tree object. For instance, HEAD
is first parsed as the name of a reference, then the branch it points to is chased to get its tip commit, then it's parsed to get the name of its tree object.
Reads the acquired tree object, recursively, and populates the index with the information on these objects. The index does not contain the actual data of the files—only meta information on them.
IOW, the index is like a miniature filesystem kept in a single file. Its format is optimized for super-fast access over a huge nested sets of files.
Now another command, git checkout-index
can be used to bring the work tree in sync with the index. Commands like git checkout <commit>
do exactly this: call git read-tree
to populate the index and then git checkout-index
to sync the work tree with it.
That's the basics. The command is able to do more than that:
-m
command line option, it's able to merge the tree(s) passed to it into the index.--prefix
).--empty
).In the simplest form we've called it when we've been dealing with your original problem, it just replaced the contents of the index with what was referenced by HEAD
at the moment.
Note that git read-tree
is a plumbing command, not intended to be routinely used by users. It's called automatically when you do things like git checkout <commit>
. I've advised to call it directly because who knows if running git checkout HEAD
would really update your index or it would decide that since it anyway reflects the state of the HEAD
nothing should be done. Calling it by hand ensured the index started to contain exactly the state we needed. In the general case you don't need this program and hence that's why it's hard to come up with a trivial usage example.
The read-tree command takes a git tree object and copies its state into the index. In your case you are taking the tree currently marked as HEAD and resetting the index to match this tree - that is equivalent to git reset --mixed HEAD. The first command can be used when you need to bring in a discontinuous history from some other repository (see this blog entry) such as a converted CVS repository. Once you have the index in a state that matches what you need you can create a commit as normal. The read-tree command is not going to be like add - it will not look at anything in the current working folder set. It is doing reset.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With