Git Submodules Cheat Sheet

Managing Git submodules — adding, cloning, updating, removing submodules, and keeping nested repositories in sync.

Last Updated: May 1, 2025

Adding & Cloning Submodules

git submodule add url path
Add a submodule at the specified path
git clone --recurse-submodules url
Clone repo AND all submodules in one command
git clone url
Clone normally (submodule dirs will be empty)
git submodule init
Initialize submodule config after a normal clone
git submodule update
Fetch and checkout the committed submodule SHA
git submodule update --init --recursive
Init, update, and recurse into nested submodules
git submodule status
Show current SHA of each submodule

Updating Submodules

cd subdir && git pull origin main
Update submodule to latest remote (manual)
git submodule update --remote
Update all submodules to their remote HEAD
git submodule update --remote --merge
Update and merge remote changes
git submodule foreach git pull origin main
Run git pull in every submodule
git submodule update --recursive
Update submodules and their nested submodules
git diff --submodule
Show submodule SHA changes in diffs

Removing Submodules

git submodule deinit path
Remove submodule from .git/config
git rm path
Remove submodule from the index and working tree
rm -rf .git/modules/path
Delete the submodule's Git data (manual cleanup)
git rm --cached path
Unregister submodule without deleting files
git commit -m Remove submodule
Commit the submodule removal

Pitfalls & Best Practices

ItemDescription
Detached HEADSubmodules always check out a specific commit, not a branch
Branch TrackingSet branch = main in .gitmodules for easier updates
Circular DependenciesAvoid submodules that reference each other
Monorepo AlternativeConsider git subtree or monorepo tools for simpler workflows
CI ConfigurationAlways use --recurse-submodules in CI clone steps
.gitmodules FileTracked config file — commit changes to share with team
Fork & ReplaceIf you need to modify a submodule, fork it first
Shallow Submodulesgit submodule update --depth 1 for faster CI clones
Pro Tip: Always commit the submodule pointer change separately from your own code changes — it makes reviewing and reverting much easier.