gitversion-controlrepositorygit-submodules

What's wrong with nested git repos?


I am in a situation where I cannot use submodules (or subtrees, I believe), and I can only use vanilla nested repos (the reason is somewhat unusual, but it has to do with building inside a docker container).

In general, what are the issues with nesting vanilla git repos in this manner?


Solution

  • 2019: A nested Git repo has no problem, except its parent repo will see it as a gitlink (a special entry in its index, representing a SHA1)

    The problem is: that SHA1 reference has no URL reference, so cloning again the parent repo will lead to an empty folder, because the parent repo does not know where to search for the nested Git repo.
    This differ from a submodule, which records the gitlink (same as a nested repo) and the URL of the nested repo (in a special file: .gitmodules)

    If your parent repo ignore (in a .gitignore) the nested repo entry, then both can co-exist without issue.


    2025 update: TL;DR

    The description above is still essentially correct. The extra gotchas people hit are:

    Longer version:

    A nested repo only becomes a special gitlink entry (mode 160000, just a commit SHA) once you git add the directory:

    # outer repo
    git add inner/
    git ls-files -s inner/
    # 160000 <sha1-of-inner-commit> 0    inner
    

    If you instead ignore it:

    echo "inner/" >> .gitignore
    git add .gitignore
    git commit -m "Ignore nested repo inner/"
    

    then the parent never records anything about inner/ – it is just an untracked directory as far as the outer repo is concerned.

    If you commit inner/ as a gitlink but do not use submodules:

    So it "works", but UIs and teammates may see it as a half-configured submodule.

    If the parent ignores inner/ completely: