A submodule is a reference to another Git repository inside a project. Used to include an external library or shared code stored in a separate repository.
💡 A submodule stores a reference to a specific commit of the external repo, not the code.
Add a submodule
# Add a repo as a submodule to a specific path
git submodule add <URL> <path/to/place>
# Example
git submodule add https://github.com/luizdepra/hugo-coder.git themes/hugo-coder
# Commit changes
git commit -m "Add submodule: themes/hugo-coder"
git push
After this, the project will have:
.gitmodulesfile - submodule configuration- Submodule folder - a reference to the external repo
Clone a project with submodules
# Option 1: clone with submodules from the start
git clone --recursive <URL>
# Option 2: if already cloned without submodules
git submodule update --init --recursive
Update a submodule
# Go into the submodule and pull changes
cd themes/hugo-coder
git pull origin main
# Go back to root and commit the new submodule commit
cd ../..
git add themes/hugo-coder
git commit -m "Update submodule: hugo-coder"
git push
Or one command from root:
# Update all submodules to latest remote commits
git submodule update --init --recursive --remote
# Commit the updated references
git add .
git commit -m "Update all submodules"
git push
⚠️
--remotefetches latest commits from remote repos. Without it - only commits already recorded in.gitmodules.
Remove a submodule
# 1. Deinitialize the submodule
git submodule deinit -f themes/hugo-coder
# 2. Remove from index and working directory
git rm -f themes/hugo-coder
# 3. Remove internal data (optional but recommended)
rm -rf .git/modules/themes/hugo-coder
# 4. Commit changes
git commit -m "Remove submodule: themes/hugo-coder"
git push
Useful commands
# Show status of all submodules
git submodule status
# Show which commits are pending update
git submodule foreach 'git log -1 --oneline'
# Sync submodule URLs (if remote changed)
git submodule sync --recursive
# Run a command in all submodules
git submodule foreach 'git fetch'
Typical issues
# Submodule folder is empty after clone
→ git submodule update --init --recursive
# "fatal: not a git repository" inside submodule
→ Delete the submodule folder and run:
git submodule update --init
# Submodule version conflict during merge
→ Choose the correct commit version:
git add themes/hugo-coder
git commit -m "Resolve submodule conflict"