Can git ls-tree list the index?

Issue

I created a new sub-directory and created a new file in it. I then added all to the Staging Area. git ls-files -s shows the new file, but does not show the tree that represents the sub-directory.

Is there a way to show the contents of the Staging Area using git ls-tree? Is there a ref pointing to the index?

Solution

The short answer is no.

The index itself doesn’t contain trees,1 and file names as stored in the index are full path names (with forward slashes, even if your host OS uses backward slashes). The git ls-tree command reads tree entries (only), not the index; the git ls-files command reads the index;2 and never the twain shall meet.


1Except, that is, for an extension that can cache a tree object seen earlier. This is meant to speed up a future git commit.

2The git ls-files command also needs, sometimes, to read the working tree. Confusingly, the term working tree has nothing at all to do with Git’s internal tree objects. The term "working tree" encompasses an OS-provided entity, where the OS allows Git to store the de-compressed, un-Git-ified files extracted from a commit. The extraction process consists of reading a commit to find a tree object—the top level tree that stores the snapshot that goes with the commit—and then reading that tree and, recursively, any sub-trees to which that tree refers. These provide the path name components, such as path, to, and file, which the recursive-reading process joins up into a simple string, path/to/file. That simple string winds up in Git’s index aka staging area aka cache; Git then uses the string—in cooperation with the OS, which might demand backwards slashes3—to create or delete or update folders and files-within-folders as necessary.

3Fortunately, even on Windows, the underlying OS allows forward slashes in path-names. (I don’t know whether various Git-for-Windows versions make use of this.) In any case, Git itself is constantly having to analyze paths and handle the inevitable "D-F conflicts" that occur: commit badf00d might have a file named path/a, while commit deadcab has a file named path/a/b. Between the two, path/a has a D-F conflict: it needs to be a directory (sometimes) and a file (sometimes).

Personally, I think it might be interesting to have an OS in which path/to can be opened and used as a file while, at the same time, having path/to/file available as a path name for a file. The OS’s equivalent of lstat would need to be able to tell you that path/to is both directory and file, whenever there are files visible underneath path/to. But all the systems on which Git runs dictate that path/to can only be one of these.

Answered By – torek

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply

(*) Required, Your email will not be published