What Are Git Submodules?
Git submodules let you include another Git repository inside your project as a subdirectory.
They keep the history of the submodule separate while allowing you to track it at a specific commit.
This is useful when you want to reuse code, include external dependencies, or track shared libraries across multiple projects.
Why Use Submodules?
Submodules can help when you want to:
- Reuse and share code between projects
- Track an external dependency at a known, stable commit
- Keep separate histories for the main project and its dependencies
Adding a Submodule
To add a submodule, use:
git submodule add https://github.com/example/library.git libs/library
This will:
- Clone the repository into libs/library
- Add an entry to your .gitmodules file
- Stage changes so you can commit them
Cloning a Repository with Submodules
When you clone a repository that uses submodules, you need to initialize and fetch their content.
Option 1: Clone and set up submodules manually
git clone https://github.com/user/repo.git
cd repo
git submodule init
git submodule update
Option 2: Clone with submodules in one step
git clone --recurse-submodules https://github.com/user/repo.git
Checking Submodule Status
To view the current commit checked out in each submodule:
git submodule status
Running Commands in All Submodules
You can run a command inside each submodule.
For example, to check the status of all submodules:
git submodule foreach git status
Updating Submodules
To update submodules to the latest commit from their remote branch:
git submodule update --remote
Removing a Submodule
To remove a submodule cleanly:
1.Delete its entry from .gitmodules
2.Remove its directory:
rm -rf path/to/submodule
3.Remove its cached index:
git rm --cached path/to/submodule
4.Commit the changes
About .gitmodules
The .gitmodules file keeps track of your submodules and their URLs:
[submodule "libs/library"]
path = libs/library
url = https://github.com/example/library.git
If you move, rename, or change the URL of a submodule, make sure to update .gitmodules and your local .git/config.
Troubleshooting & Best Practices
- If submodules are empty after cloning, run:
git submodule update --init --recursive
- Remember: submodules point to a fixed commit. You must manually update them to get the latest changes.
- When you change a submodule’s remote URL, update both .gitmodules and your local config.
- For simpler cases, consider alternatives like Git subtree, vendoring, or copying files instead of using submodules.