YouTube/@philomatics/25/05/Why everyone hates git submodules
- Why everyone hates git submodules - YouTube
My Notes
- In old versions of git, you had to run
git submodule update --recursiveafter changing a branch, running git pull, merging and rebase, etc. In recent versions of git, you can run these two commands once, which will make it so that when you switch branches or run a git pull or git push, all submodules will be updated automatically as necessary. - Some recommended aliases for submodules
- One alternative to using git submodules is using a package manager like npm or pip and keeping the two repos separate, but including the child repo in the parent repo's package.json or whatever is the equivalent. Most package managers allow you to include a custom URL to a repo. So even if your library is private, you can still use this method. This might actually be less confusing for some teams.
- In old versions of git, you had to run
Video
00:00 Introduction to Git Submodules
What Are Submodules?
Cloning Repositories with Submodules
- When you clone a repo that includes submodules, the code in the submodule will not be downloaded automatically
- To download everything, add the
--recursiveflag when cloning: - This ensures all submodules, including entire git history, are downloaded
- Alternatively, if you've already cloned the repo, run from the parent repo's directory:
How Submodules Work
Recursive Flag
Submodule Behavior
02:16 Making Changes to Submodules
The Detached Head Problem
- Making changes to submodules is one of the most confusing aspects when working with submodules
- Parent repo always pins the submodule to a specific commit hash
- When Git downloads a submodule, it's put into a detached HEAD state
- Detached HEAD means you've checked out a specific commit without any branch checked out
Switching to a Branch
Updating the Parent Repo
- After committing changes in submodule, the parent repo doesn't know about the new commit yet
- Running
git statusin the parent repo shows the submodule has changed - Another way this happens: running
git pullin the submodule directory to get latest changes - To update the pinned commit in the parent repo:
- After pushing parent repo, the pinned commit changes on GitHub as well
04:04 Branching and Auto-Update Configuration
Switching Branches with Submodules
- When switching branches in the parent repo, by default Git will not automatically update the submodule
- Example: main branch has submodule pinned to commit A, older branch has it pinned to commit B
- After switching branches, submodule should have old commit checked out, but Git won't do this automatically
- Running
git statusin parent repo shows Git thinks there are newer commits in submodule
Manual Update Required (Old Git Versions)
Auto-Update Configuration (Newer Git Versions)
Useful Aliases
05:36 Adding and Removing Submodules
06:23 Alternatives and Conclusion
Evaluation of Submodules
Alternative 1: Package Managers
- Use a package manager like npm or pip instead
- Keep the two repos completely separate
- Include the child repo in the parent repo's
package.json(or equivalent) - Most package managers allow custom URLs to repos, even private ones
- Example format:
- Recommendation: Use this method over submodules if you're not already using them
- Benefits:
- Limitation: Not always possible depending on package manager setup and programming language
Alternative 2: Monorepo Approach