Git Submodules: Add One Repo Inside Another
Summary: Link external repositories using Git submodules.
Modern software projects often rely on code that lives outside their main repository. Whether you want to reuse in-house libraries, depend on third-party tools, or modularize your codebase, you may need to link one Git repository inside another. Git submodules make this not only possible, but seamless.
In this guide, we'll explain what submodules are, the benefits and caveats of using them, and how to add, update, and remove submodules in your project.
What Are Git Submodules?
A Git submodule is like a pointer from one repository (the “superproject”) to a specific commit in another repository (“submodule”). The superproject tracks which version of the submodule repository it needs, and you can update or lock submodules as needed.
This allows you to:
- Reuse existing repositories (internal or external).
- Link to specific versions of dependencies.
- Maintain consistent dependencies across teams and environments.
Common use cases include:
- Embedding a shared library (your own or a third party).
- Pulling in documentation tools or test suites.
- Splitting large codebases into smaller, more manageable pieces.
How Submodules Work
Under the hood, submodules are managed via a special configuration file called .gitmodules
in the root of your repository. Each submodule is essentially a separate Git repository checked out to a specific commit, living inside a designated directory of your main project.
When you clone a repository containing submodules, you have to initialize and fetch the submodules' content explicitly.
Adding a Git Submodule
Let's go through the steps to add a submodule to an existing repository.
1. Choose Your Submodule Location
Decide where in your repository the submodule will reside. For instance, maybe you want to add a tools library under the lib/
folder.
2. Add the Submodule
git submodule add <repository-url> <path/to/subdir>
Example:
git submodule add https://github.com/example/tools.git lib/tools
https://github.com/example/tools.git
: The URL of the repository you want to embed.lib/tools
: The directory path where the submodule contents will appear.
Git will:
- Clone the submodule repo into the chosen path.
- Create or update the
.gitmodules
configuration file. - Record the submodule’s current commit in your repo.
3. Commit the Changes
After adding a submodule, you'll see changes to:
.gitmodules
- The submodule path (as a gitlink, not the full code)
- Possibly the repository index
Add and commit the changes:
git add .gitmodules lib/tools
git commit -m "Add tools submodule"
Cloning a Repo with Submodules
If you clone a repository that uses submodules, you'll need to initialize and fetch submodules separately.
Clone with submodules:
git clone --recurse-submodules <repo-url>
If you've cloned without submodules, you can fetch submodules at any time:
git submodule update --init --recursive
--init
: Initializes submodules.--recursive
: Fetches nested submodules, if any.
Working with Submodules
Updating Submodules
To pull in the latest changes from the submodule's upstream repository:
-
Change to the submodule directory:
cd lib/tools
-
Fetch and checkout the desired commit or branch:
git checkout main git pull
-
Go back to the main repo, add and commit the updated submodule pointer:
cd ../.. git add lib/tools git commit -m "Update tools submodule to latest commit"
Removing a Submodule
-
Remove the submodule’s entry from
.gitmodules
:Edit
.gitmodules
and remove the relevant section. -
Stage changes:
git rm --cached lib/tools rm -rf lib/tools git commit -m "Remove tools submodule"
-
Optionally, clean up the entry from
.git/config
and any lingering files.
Submodules vs Alternatives
- Subtrees: Subtrees store the actual code in your repo history. Fine for projects you want to absorb and manage yourself.
- Package Managers: For language-specific dependencies, use package managers (npm, pip, etc). Submodules are best for repositories not available as packages.
Submodule Best Practices
- Lock submodules to a specific commit for stability.
- Avoid making changes inside a submodule unless you plan to contribute upstream.
- Document submodule usage and setup in your
README
. - Remember: Submodules are repositories themselves; you’ll need to clone, fetch, and commit within them as you would any other repo.
Conclusion
Git submodules are a powerful tool to combine, modularize, or reuse code across multiple repositories. With a sound workflow, they can make managing complex projects much easier, ensure consistent dependencies, and reduce code duplication.
Ready to try submodules in your project? Go ahead and link your first external repository—your future self will thank you!
If you found this guide helpful, share it with your team and check out Git’s official submodules documentation for more advanced usage.