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:

  1. Change to the submodule directory:

    cd lib/tools
    
  2. Fetch and checkout the desired commit or branch:

    git checkout main
    git pull
    
  3. 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

  1. Remove the submodule’s entry from .gitmodules:

    Edit .gitmodules and remove the relevant section.

  2. Stage changes:

    git rm --cached lib/tools
    rm -rf lib/tools
    git commit -m "Remove tools submodule"
    
  3. 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.