You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Submodule git dir is created at .git/modules/<path>; git uses .git/modules/<name> #7400
When the name of a submodule differs from its path, libgit2 creates the submodule's git directory at $GIT_DIR/modules/<path>. Git creates it, and looks for it, at $GIT_DIR/modules/<name>. Git then fails on a repository that libgit2 initialized.
By default the name equals the path, so the two places are the same. The difference appears only with a custom name (git submodule add --name, or an edited .gitmodules).
Reproduction steps
Superproject .gitmodules:
[submodule "foo"]path = path/foo
url = ../sub
Clone the superproject and initialize its submodules with libgit2: git_submodule_update() with init = 1, or git_submodule_repo_init().
List .git/modules/.
I have not called libgit2 directly. We found the layout in a clone that GitKraken (built on libgit2) made, and the source below shows the cause.
Expected behavior
The git directory is at .git/modules/foo, where git clone --recurse-submodules and git submodule update --init put it.
gitsubmodules(7) says .gitmodules "mainly serves as the mapping between the name and path of submodules in the superproject, such that the submodule's Git directory can be located".
Actual behavior
The git directory is at .git/modules/path/foo.
Both places in src/libgit2/submodule.c that build this directory join the submodule path, not the name:
submodule_repo_create(): the same join. git_submodule_clone() reaches it through git_submodule_update_repo_init_cb.
Git builds the directory from the name: submodule_name_to_gitdir() in git's submodule.c appends modules/<name>.
What breaks in git
The .git file in the submodule points to the libgit2 location, so most git commands work. These do not:
git checkout --recurse-submodules links each submodule whose recorded commit changes to .git/modules/<name>, which does not exist. The submodule becomes unusable, and git still switches the superproject. This part is a git bug, and I reported it to the git list.
After git submodule deinit, git submodule update --init does not find the git dir that libgit2 made. It clones the submodule again into .git/modules/<name>, and local branches stay behind in .git/modules/<path>.
Possible fix
Join sm->name instead of the path. To keep the git dirs that earlier libgit2 versions created, use .git/modules/<path> when it exists and .git/modules/<name> does not.
Version of libgit2 (release number or SHA1)
main as of 2026-10-05 (source reading). Seen in practice in a GitKraken clone.
Operating system(s) tested
Windows 11. The code path does not depend on the platform.
changed the title [-]Title: Submodule git dir is created at .git/modules/<path>; git uses .git/modules/<name>[/-][+]Submodule git dir is created at .git/modules/<path>; git uses .git/modules/<name>[/+]on Oct 5, 2026
Activity
[-]Title: Submodule git dir is created at .git/modules/<path>; git uses .git/modules/<name>[/-][+]Submodule git dir is created at .git/modules/<path>; git uses .git/modules/<name>[/+]