
Git submodules let you embed one Git repository inside another. They're useful for managing shared libraries, vendor code, or reusable components across multiple projects without duplicating files. Each submodule links to a specific commit of an external repo, keeping its history and configuration separate from the parent project.
This article explains how to add, clone, update, and manage Git submodules effectively, with practical commands and tips to avoid common pitfalls.
The Short Answer Version
# Add a submodule to your repository
$ git submodule add https://github.com/user/repo.git path/to/submodule
# Initialize submodules in a cloned repository
$ git submodule init
# Update submodules to fetch content
$ git submodule update
# Clone repository and its submodules in one step
$ git clone --recurse-submodules https://github.com/user/project.git
# Pull latest commits from submodule’s remote
$ git submodule update --remote
# Remove a submodule completely
$ git submodule deinit -f path/to/submodule
$ rm -rf path/to/submodule
$ git rm path/to/submodule
$ rm .gitmodules
Add a Git Submodule
Submodules let you link another Git repository into your project while keeping its history and configuration separate. This section demonstrates how to add a submodule to an initialized Git project.
Command Syntax
To add a submodule:
git submodule add <submodule-url> <path>
<submodule-url>
: The remote URL of the Git repository you want to add.<path>
: The target folder path inside your project where the submodule will live.- Git stores this reference in a
.gitmodules
file and treats the submodule as a pointer to a specific commit.
Command Demonstration
Create a project directory.
console$ mkdir my-project && cd my-project
Initialize the directory as a Git repository.
console$ git init
Add a submodule.
console$ git submodule add https://github.com/example/repo.git vendor/example-lib
This clones the external repository into the
vendor/example-lib
folder and creates a.gitmodules
file.Review
.gitmodules
.console$ cat .gitmodules
Output.
[submodule "vendor/example-lib"] path = vendor/example-lib url = https://github.com/example/repo.git
Stage the
.gitmodules
file and submodule directory.console$ git add .gitmodules vendor/example-lib
Commit the submodule addition.
console$ git commit -m "Add example-lib as submodule"
Push your committed changes to the remote repository.
console$ git push origin main
Clone a Repository with a Git Submodule
When you clone a repository that includes submodules, Git does not fetch submodule content automatically unless explicitly instructed. This section explains how to initialize and update submodules correctly.
Command Syntax
To manually initialize and update submodules after cloning:
git clone <repo-url> cd <repo-name> git submodule init git submodule update
To clone the repository and submodules in a single command:
git clone --recurse-submodules <repo-url>
--recurse-submodules
: Automatically clones and initializes all submodules during the initial clone.git submodule init
: Registers submodules from.gitmodules
.git submodule update
: Fetches the submodule contents.
To update submodules to their latest remote-tracked commits:
git submodule update --remote
--remote
: Pulls the latest commit from the remote branch tracked by the submodule.
Command Demonstration
Clone the main repository.
console$ git clone https://github.com/example/project.git
Change into the project directory.
console$ cd project
Initialize the submodules from
.gitmodules
.console$ git submodule init
Download the contents of each submodule.
console$ git submodule update
(Alternative) Clone the repository and submodules in one step.
console$ git clone --recurse-submodules https://github.com/example/project.git
(Optional) Update submodules to the latest remote commit.
console$ git submodule update --remote
By default, submodules track a specific commit. Use --remote
only if you want to sync to the latest upstream commit on the tracked branch.
Precautions for Adding a Git Submodule
Before using submodules in a project, keep the following in mind:
Submodules track commits, not branches.
By default, submodules point to a specific commit. They do not automatically follow the latest changes in the remote repository. You must manually update them with
git submodule update --remote
.You must commit submodule updates explicitly.
If you update a submodule to point to a new commit, the parent repository treats that as a change. You need to stage and commit the submodule pointer update.
Cloning with submodules requires extra steps.
Users must remember to run
git submodule init
andgit submodule update
, or use the--recurse-submodules
flag during cloning.Submodules complicate pull/merge workflows.
If different branches reference different submodule commits, merges or rebases can get messy. Always coordinate submodule usage in collaborative workflows.
CI/CD pipelines need submodule awareness.
Ensure any automated build or deployment tools include logic to fetch and update submodules. A common failure point is forgetting
--recurse-submodules
.
Use submodules only when you truly need independent versioning of external codebases. Otherwise, simpler solutions like package managers or monorepo structures may be easier to maintain.
If you no longer need a Git submodule, follow these steps to remove it cleanly.
Deinitialize the submodule.
console$ git submodule deinit -f vendor/example-lib
Remove the submodule directory.
console$ rm -rf vendor/example-lib
Remove the entry from
.gitmodules
.console$ git config -f .gitmodules --remove-section submodule.vendor/example-lib
Stage the updated
.gitmodules
file.console$ git add .gitmodules
Remove the submodule from Git configuration.
console$ git config --remove-section submodule.vendor/example-lib
Remove the submodule from Git index.
console$ git rm --cached vendor/example-lib
Commit the changes.
console$ git commit -m "Remove vendor/example-lib submodule"
Push the commit to your remote repository.
console$ git push origin main
These steps completely clean up the submodule reference from your Git project.
Conclusion
In this article, you learned how to use Git submodules to manage reusable code across projects. You added submodules to a repository, cloned projects with submodules, updated them to track remote changes, and removed them cleanly when no longer needed. By using submodules effectively, you maintained modular project structures, avoided code duplication, and ensured version consistency across dependencies.
No comments yet.