Interactive Git Submodules Guide
Master the Git Submodules workflow with this interactive guide. Learn the essentials, critical workflow, when to use, and how to troubleshoot.
The Essentials
Understand the 3 fundamental pillars of Git submodules.
1. Repository within Repository
A submodule is a complete Git repository nested inside another Git repository. Each maintains its own independent history, branches, and commits.
2. Commit Pointer
The parent repository (superproject) does not store the submodule files, only a pointer to a specific commit in the submodule repository.
3. .gitmodules File
This file tracks which submodules exist, their remote URLs, and their local paths. It is versioned along with the superproject.
Getting Started
When cloning a repository with submodules, you need to explicitly initialize them:
git clone --recurse-submodules <url-do-repositorio>Or, if you already cloned without the flag, initialize submodules later:
git submodule update --init --recursiveCritical Workflow
Follow these 6 steps when making changes to a submodule.
Step 1: Enter the Submodule and Create a Branch
Always work on a named branch, never in "detached HEAD".
cd ./submodulo
git checkout -b meu-novo-branchWhen to Use Submodules
Compare submodules with popular alternatives. Hover over bars for details.
Hover over the bars to see the description of each metric.
Quick Reference
Essential commands and solutions to common problems.
Commands
add
Adds a new repository as a submodule.
Flags: -b, --depth, --name
update
Updates submodules to the commit registered in the superproject.
Flags: --init, --recursive, --remote
init
Registers submodules from .gitmodules to local .git/config.
Flags: '<'path'>'
status
Shows the current state of submodules.
Flags: --cached, --recursive
rm
Removes a submodule from the project.
Flags: -f, --cached
sync
Syncs URLs from .gitmodules to local .git/config.
Flags: --recursive
foreach
Executes a command in each submodule.
Flags: '<'command'>'
Troubleshooting
modified: '<'path'>' (new commits)
Cause: Local submodule commit is ahead of what the superproject expects.
Solution: `git add '<'path'>'` and `git commit` (if intentional) OR `git submodule update` (if unintentional).
Empty submodule directory
Cause: Cloned without --recurse-submodules flag.
Solution: `git submodule update --init --recursive`
fatal: reference is not a tree
Cause: Superproject points to a submodule commit that hasn't been published.
Solution: The author must push the submodule commit.
CONFLICT (submodule)
Cause: Superproject branches being merged point to different submodule commits.
Solution: Resolve manually: `cd '<'path'>'`, decide correct commit, `cd ..`, `git add '<'path'>'`.
Recent work disappeared
Cause: Commits were made in detached HEAD state.
Solution: `cd '<'path'>'`, `git reflog` to find commit, `git branch '<'name'>' '<'hash'>'` to recover.
Still have doubts about Git Submodules?
Deepen your knowledge. Ask a question to our AI Expert Engineer.
Receive site updates
Subscribe to receive site updates directly to your email
We won't send spam. You can unsubscribe at any time.