How do I add Git submodule to a sub-directory?
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Adding a Git submodule to a sub-directory is the standard way to include another repository inside your project while keeping histories separate. This is useful for shared libraries, vendor code, or internal tools that evolve independently. The workflow is simple once you understand what Git tracks in the parent repository.
Add the Submodule at a Specific Path
Use git submodule add with both repository URL and target folder.
Git creates two things:
- A
.gitmodulesfile containing submodule metadata. - A special entry in the index that stores the submodule commit pointer.
Commit both changes from the parent repository.
The parent repo does not store the submodule file contents directly. It stores the exact commit hash that should be checked out in that directory.
Clone and Initialize Correctly
When teammates clone the parent repository, they must also initialize submodules.
A one-line clone option is even better for new setups.
Without this step, submodule folders appear empty or detached, which causes confusion during builds.
Update a Submodule Intentionally
Inside the submodule directory, fetch and checkout the desired revision, then commit the pointer update in the parent repository.
This explicit pointer update is a feature. It gives parent repository owners control over exactly which dependency revision is used.
Track a Branch in .gitmodules
If your workflow expects updates from a specific branch, add branch metadata and use update commands consistently.
Then update with:
Review changes before committing. Auto-following a branch can pull in surprises if upstream moves quickly.
Move or Remove a Submodule Safely
To move a submodule path, use git mv and verify .gitmodules updates.
To remove a submodule, use deinit and remove the path.
This cleanup avoids stale metadata that can break future clones.
CI and Build Pipeline Considerations
Submodules require explicit handling in CI. If your pipeline checks out only the parent repository, builds can fail because dependency directories are empty. Add a submodule init step to your workflow.
If your submodule URL uses SSH, ensure CI runners have the correct deploy key. If HTTPS with tokens is required, inject credentials through secure CI secrets. Keep these details documented so local setup and CI behavior stay aligned.
Common Pitfalls
One frequent pitfall is forgetting to commit the submodule pointer change in the parent repository after updating inside the submodule folder. Another issue is cloning without --recurse-submodules, then assuming the dependency is missing or broken. Teams also sometimes edit files inside a detached submodule head and lose track of where those commits went. Always check branch state with git -C <path> status before editing. Finally, mixing submodules with ad-hoc copy-paste vendor directories creates unclear ownership boundaries. Pick one strategy and document it in your contribution guide.
Summary
- Add submodules with
git submodule add <url> <subdir>. - Commit both
.gitmodulesand the submodule pointer entry. - Clone with
--recurse-submodulesor initialize after cloning. - Update submodule commits intentionally and commit pointer bumps.
- Clean up metadata correctly when moving or removing submodules.

