Home > database >  Renaming git submodules without moving them
Renaming git submodules without moving them

Time:08-29

I have a submodule set up thus:

.gitmodules

[submodule "path/to/submodule"]
    path = path/to/submodule
    url = [email protected]:account/repo.git

Instead of having to reference it from the project root as 'path/to/submodule', I'd like to just be able to reference it as 'my_submodule'. e.g.

git submodule update --remote my_submodule

Everything I've read so far about this explains how to move the submodule, and that's not what I want to do. I have tried simply changing .gitmodules to

[submodule "my_submodule"]
    path = path/to/submodule
    url = [email protected]:account/repo.git

and .git > config to

[submodule "my_submodule"]
    url = [email protected]:account/repo.git
    active = true

but it just throws error: pathspec 'my_submodule' did not match any file(s) known to git

I hope someone out there can help. Thank you.

CodePudding user response:

As phd has noted in comments, a submodule's "logical name" is—at least currently1—used only to locate values within in .gitmodules and the files in .git/modules/. You should leave the logical names alone here because they're private to Git itself. Or, to say this in fewer words: Don't do that!


1There is a lot of work going on, over a long time period, in the background, as part of a project to make submodules not be the sob-modules that they still are. Things in the future may change. That's one reason not to mess with undocumented stuff about submodules now.


Extra information not relevant to the answer but that you should know

It's worth noting a historical oddity: submodules once were implemented by storing the .git directory / folder (whichever term you prefer) within the working tree of the submodule. That is, if you have:

repo/.git     # a top level repository
repo/foo/     # a folder within the superproject containing various files
repo/foo/sub  # a submodule of the superproject, in `foo/sub`

then repo/foo/sub/.git held the actual Git repository for the foo/sub submodule of this repository. Within repo/foo/sub/.git you would find the HEAD file, the refs/ directory, the objects/ directory, and so on.

This still works, but it has a rather obvious and nasty drawback. Suppose we're on the tip commit of branch develop, where we've added this new submodule. We now rewind to main, which does not yet have the submodule. Git needs to remove the foo/thing1, foo/thing2, etc., files, and because there's no submodule, Git wants to remove foo/sub as well.

If Git succeeds at removing foo/sub, the entire submodule repository—not just its checkout—is gone!

To fix this, Git long ago learned to "absorb" submodule Git directories into the superproject, storing them in .git/modules/ in the superproject. The .git in repo/foo/sub/ is now a file containing the path to the stored repository. If you have an old arrangement—which you can get by deliberately creating nested repositories before running git submodule add—you can run git submodule absorbgitdirs to move the submodule .git (repository proper) into the superproject's .git/modules directory. This makes it safe to check out a historical commit in which there is no such submodule: Git can safely remove the .git file without destroying the submodule repository, and later restore that .git file when moving to a commit that does use the submodule.

  • Related