| Because they merely make really hard things hard and simple things painful. They solve a problem (albeit one that can be better solved by a decent package manager like Cargo/NPM). And in return, basic operations like merge/rebase start breaking in unintuitive ways. E.g., I work on repo ss14 that has submodules RobustToolbox, but never modify them in my PR. I rebase my changes. I have changes in RobustToolbox that are only visible in Git Bash. Other Git clients show no changes... Ofc `git submodules update --recursive` might help or something, but it made a simple operation more complicated. And that's if I didn't change the submodule. If I did, merging/rebasing becomes its own, separate nightmare. > They solve the problem of "pin a specific version of some external 3rd-party repo" really With Cargo/NPM you can pin your dependencies to some version you control like a fork or a local directory, making submodules non-necessary. And unlike submodules, they don't require you to modify your workflow to sprinkle `git submodule update` everywhere. |
It's designed for things like "my project needs to check out pinned versions of these 4 external repos", ideally where the pinned version doesn't move all that often.
Git-submodule is best used as a replacement for the "shell script that clones a bunch of dependencies" pattern, not as a multi-repo workflow coordination tool. And in that context, it works very well.
Imagine you had a CLI tool that tool that consumes some text-file list of repos, commits, and paths. Every repo in the list gets cloned to the path you asked, and each repo's requested hash is checked out. The text-file is controlled in your main Git repo.
That's essentially all that Git-submodule is, except that it's built into Git instead of having to roll your own or introduce another tool dependency. There's also some light integration to handle recursive clones and reporting if the submodule state is dirty.