What is a submodule?
A way to nest one Git repository inside another. Use it when you want to reuse a shared library, third-party code, or shared configuration across multiple projects.
Adding a submodule
Bash
# Add a submodule
git submodule add https://github.com/org/shared-lib.git libs/shared
# Track a specific branch
git submodule add -b main https://github.com/org/shared-lib.git libs/shared
# Files created after adding
# .gitmodules — submodule config file
cat .gitmodules
# [submodule "libs/shared"]
# path = libs/shared
# url = https://github.com/org/shared-lib.git
# branch = main
# Commit
git add .gitmodules libs/shared
git commit -m "feat: add shared-lib submodule"Cloning a repo that contains submodules
Bash
# Method 1: clone with submodules in one step
git clone --recurse-submodules https://github.com/org/myproject.git
# Method 2: already cloned
git submodule init
git submodule update
# One-liner
git submodule update --init --recursiveUpdating submodules
Bash
# Update a specific submodule to the latest
cd libs/shared
git pull origin main
cd ../..
git add libs/shared
git commit -m "chore: update shared-lib to latest"
# Update all submodules to the latest at once
git submodule update --remote --merge
# Parallel update (when there are many submodules)
git submodule update --remote --jobs 4Removing a submodule
Bash
# 1. Remove the entry from .gitmodules
git config -f .gitmodules --remove-section submodule.libs/shared
# 2. Remove from .git/config
git config --remove-section submodule.libs/shared
# 3. Unstage
git rm --cached libs/shared
# 4. Delete files
rm -rf libs/shared
# 5. Clean up .git/modules
rm -rf .git/modules/libs/shared
# 6. Commit
git add .gitmodules
git commit -m "chore: remove shared-lib submodule"Checking status
Bash
# Submodule status
git submodule status
# + abc1234 libs/shared (v1.2.3)
# ^ = ahead, - = not initialized, + = modified
# Full status including submodules
git status --recurse-submodules
# Submodule summary
git submodule summaryCommon problems
Bash
# Problem: submodule is an empty directory
git submodule update --init --recursive
# Problem: detached HEAD
cd libs/shared
git checkout main
git pull
# Problem: not updating after a URL change
git submodule sync
git submodule update --init
# Problem: parent repo doesn't pick up submodule changes
cd ..
git add libs/shared # Update the pointer (commit hash)
git commit -m "chore: update submodule pointer"Submodules in GitHub Actions
YAML
- uses: actions/checkout@v4
with:
submodules: recursive # Check out including submodules
token: ${{ secrets.PAT }} # PAT required for private submodulesEditorial note
AI tools may assist drafting. Check the evidence in each guide for whether commands were run and which environment was used. Confirm the current docs for your version before applying instructions, and email us about errors. email us
Topic-related official docs (auto-linked · not per-claim sources)Git documentation ↗
Questions & answers
Ask a question about this guide. We'll review and reply.