Ramkumar Ramachandra <artag...@gmail.com> writes: > Jens Lehmann wrote: >> When moving a submodule which uses a gitfile to point to the git directory >> stored in .git/modules/<name> of the superproject two changes must be made >> to make the submodule work: the .git file and the core.worktree setting >> must be adjusted to point from work tree to git directory and back. > > Isn't it untrue that the git directory is stored in > .git/modules/<name>: it is stored in .git/modules/path/to/module. > > I thought the whole point of this complex scheme was to avoid name > conflicts with submodules with the same name in other directories.
I think Jens is right on this one. There are three things the code needs to know about a submodule: its name, path and URL. A canonical use case to think about is a project that builds an appliance: * Its zero-th version only has the sources to the userspace for the appliance. * The first version adds the Linux kernel as a submodule bound at kernel/, taking it from git://k.org/linux-2.6.git/. * The second version adds a choice to build the appliance with the BSD kernel, and the project reorganizes the source tree to have Linux kernel at path linux/ and adds the bsd kernel at path bsd/. * By the time the third version is released, the URL to the Linux has migrated to git://k.org/linux.git/; it is still logically the same (i.e. continuation of) the old 2.6.git repository [*1*]. We would want to make it possible to "git checkout" smoothly between these four versions. Switching from v1 to v0 would have to remove the submodule working tree at kernel/ but the user may want to switch back to v1 without having to re-download the kernel submodule, so the kernel/.git repository needs to be stashed away somewhere. Somewhere in $GIT_DIR of the superproject, but where? Switching from v1 to v2 would need to move kernel/ to linux/ and move kernel/.git to linux/.git. The design choice made long time ago (if you recall the collection of old threads I gave you some time ago, this is what was called "Steven's three-level thing") was to give a stable "logical" name for the Linux kernel component, so that no matter where in the working tree the version that happens to be at the tip of the current branch has it, we know where in the superproject's .git/modules it is found. So at the second version when we move the submodule that used to be at kernel/ to linux/, we move the working tree of it, adjust the "path" of the submodule, but keep the name. And that name gives an identity to the submodule, and that is what is used as a key inside $GIT_DIR of the superproject to decide where the repository (together with its object store) of the submodule is stashed away. [Footnote] *1* I mentioned the URL thing only for completeness; it does not come into play in the "checkout" scenario, but when you start thinking about remote interactions, you need to be aware of how that value and the one copied to the configuration upon "submodule init" need to be managed. Which is a separate topic but is an integral part of the canonical example. Ideally, a user who has followed along the life of this project should: * first encounter git://k.org/linux-2.6.git/ in v1; "git submodule init" would copy it to her .git/config in the superproject. * later notice that .gitmodules has git://k.org/linux.git/ location that she hasn't seen for the submodule, and is given a chance to have the URL entry updated in her .git/config. This is becuase even when she checks out an older branch that has 2.6 in .gitmodules, "git submodule update" _should_ go to the new URL, not to the defunct 2.6 URL. We do the "copy initially", but do not do the latter "offer a chance to update when seeing a new one" (at least, not yet). -- To unsubscribe from this list: send the line "unsubscribe git" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html