Git Submodules: Include External Repositories

Learn how to use git submodules to include and manage external repositories within your project. Add, update, and remove submodules.

git submodule add https://github.com/lib/repo.git vendor/lib

Detailed Explanation

What Are Git Submodules?

A submodule is a Git repository embedded inside another Git repository. The parent repo stores a reference to a specific commit in the submodule, not the submodule's files directly. This allows you to include external dependencies while keeping them at a pinned version.

Adding a Submodule

git submodule add https://github.com/lib/repo.git vendor/lib
git commit -m "Add lib as submodule"

This creates a .gitmodules file and records the submodule's commit hash.

Cloning a Repo with Submodules

# Clone and initialize submodules in one step
git clone --recurse-submodules https://github.com/user/project.git

# Or initialize after cloning
git submodule init
git submodule update

Updating Submodules

# Update to the latest commit on the submodule's tracked branch
cd vendor/lib
git pull origin main
cd ../..
git add vendor/lib
git commit -m "Update lib submodule"

# Or update all submodules at once
git submodule update --remote

Removing a Submodule

git submodule deinit vendor/lib
git rm vendor/lib
rm -rf .git/modules/vendor/lib
git commit -m "Remove lib submodule"

Common Pitfalls

  • Forgetting --recurse-submodules when cloning leaves submodule directories empty.
  • Submodule updates require a commit in the parent repo to record the new hash.
  • Merge conflicts in submodule references can be confusing.

Alternatives

For many projects, package managers (npm, pip, cargo) are simpler than submodules. Consider submodules when you need to pin a specific commit of a dependency that does not have a package manager, or when you need to make local modifications to the dependency.

Use Case

A company maintains a shared UI component library as a separate repository and includes it as a submodule in multiple product repositories to ensure consistent versioning.

Try It — Git Command Builder

Open full tool