0

I just did git ls-tree in some (not my) repo and saw this in output:

100644 blob   54cfbdae80000000000000000000639faa8ecaee    .gitignore
100644 blob   7c6a8bf6500000000000000000000c84e3fba06d    xxx.py
040000 tree   f9c9cf0760000000000000000000c6c48116bc14    yyy
160000 commit 6f473ed0000000000000000000dffd4ebd48d103    zzz
040000 tree   fb81e98c40000000000000000000f90685a62410    vvv
040000 tree   642e5f2e3000000000000000000063acd187d42d    uuu

zzz is empty dir. If I delete it, it appears as change in git status output. git status don't see anything if I touch some files in it.

What is zzz? How could that be?

1 Answer 1

1

Although the zzz entry creates a directory, it is not meant to represent an empty directory. The key to seeing this is to compare its type and mode with the other directories. The mode for zzz is 160000 and its type is commit; the tree objects yyy, vvv, and uuu, which end up storing non-empty directories, have mode 040000 and type tree.

What this means is that the zzz entry is a so-called "gitlink".

The associated hash ID (clearly you made the ones above up; they have far too many zeros to be coincidence) is the hash of the submodule that Git should check out into that directory. Git will make the directory itself as part of checking out this superproject. Later, though, Git will read the .gitmodules configuration file to find the appropriate subproject URL: it will clone that repository into the zzz directory when you do git submodule init.

You can get Git to do this automatically during the superproject's git clone if you clone with git clone --recursive. See How to `git clone` including submodules? for details.

See also Where does Git store the SHA1 of the commit for a submodule?

Note that if there is no .gitmodules entry for the path, Git does not know what to clone here. These "fake" entries may therefore be (ab)used to create empty directories. It sort-of works. There are no promises that it will keep working in later versions of Git, though, and in any case Git just kind of loses track of files within here, as it thinks they belong to another repository. Most of this paragraph is a link to the answer that describes this in detail.

2
  • I didn't even think about submodules... There is no .gitmodules though. Commented Apr 13, 2017 at 23:18
  • 1
    If there's no .gitmodules file anywhere, Git won't know what to clone. That might be someone's trick of getting Git to create an empty subdirectory—but it doesn't quite work, because Git insists it should find a submodule. See this answer as well.
    – torek
    Commented Apr 13, 2017 at 23:26

Not the answer you're looking for? Browse other questions tagged or ask your own question.