Git submodules allow you to include one Git repository within another. They are useful for handling shared libraries, vendor code, or reusable components across different projects without copying files. Each submodule is tied to a specific commit of an external repository, keeping its history and setup distinct from the main project.
This tutorial covers how to add, clone, update, and manage Git submodules properly, including commands and strategies to avoid common mistakes.
The Short Answer Version
Add a submodule to your repository
$ git submodule add https://github.com/user/repo.git path/to/submoduleInitialize submodules in a cloned repository
$ git submodule initUpdate submodules to fetch content
$ git submodule updateClone repository and its submodules in one step
$ git clone --recurse-submodules https://github.com/user/project.gitPull latest commits from submodule’s remote
$ git submodule update --remoteRemove a submodule completely
$ git submodule deinit -f path/to/submodule
$ rm -rf path/to/submodule
$ git rm path/to/submodule
$ rm .gitmodulesMatching infrastructure at centron
No hardware needed to follow along: ccloud³ VMs with full root access start at €3.12 per month, billed by the hour and ready in seconds. Rent a cloud server →
Add a Git Submodule
Submodules enable you to connect another Git repository to your project while keeping its version history and configuration independent. This section demonstrates the steps for adding a submodule to an already initialized Git project.
Command Syntax
To include a submodule, use:
git submodule add <submodule-url> <path><submodule-url>: The remote Git repository’s URL to link.<path>: The directory path inside your project where the submodule will be placed.
Git saves this reference in a .gitmodules file and treats the submodule as a pointer to a specific commit.
Command Demonstration
Create a project directory.
$ mkdir my-project && cd my-projectInitialize the directory as a Git repository.
$ git initAdd a submodule.
$ git submodule add https://github.com/example/repo.git vendor/example-libThis command clones the external repository into the vendor/example-lib folder and creates a .gitmodules file.
Check the .gitmodules file.
$ cat .gitmodulesOutput:
[submodule "vendor/example-lib"]
path = vendor/example-lib
url = https://github.com/example/repo.gitStage the .gitmodules file and the submodule folder.
$ git add .gitmodules vendor/example-libCommit the addition of the submodule.
$ git commit -m "Add example-lib as submodule"Push your committed changes to the remote repository.
$ git push origin mainClone a Repository with a Git Submodule
When cloning a repository that contains submodules, Git will not automatically retrieve the submodule content unless specifically instructed. This section details how to properly initialize and update submodules.
Command Syntax
To initialize and update submodules manually after cloning:
git clone <repo-url>
cd <repo-name>
git submodule init
git submodule updateTo clone the repository and submodules in a single step:
git clone --recurse-submodules <repo-url>--recurse-submodules: Automatically clones and initializes all submodules during the initial clone.git submodule init: Registers submodules defined in.gitmodules.git submodule update: Downloads the contents of the submodules.
To refresh submodules to the most recent remote-tracked commits:
git submodule update --remote--remote: Pulls the latest commit from the tracked branch of the submodule.
Command Demonstration
Clone the primary repository:
$ git clone https://github.com/example/project.gitMove into the repository folder:
$ cd projectInitialize the submodules defined in .gitmodules:
$ git submodule initFetch the submodule contents:
$ git submodule updateAlternative: Clone the repository and submodules in one step.
$ git clone --recurse-submodules https://github.com/example/project.gitOptional: Update submodules to the most recent commit from the remote branch.
$ git submodule update --remoteBy default, submodules point to a fixed commit. Use --remote only if you want to sync to the latest upstream commit from the tracked branch.
Precautions for Adding a Git Submodule
- Submodules point to commits, not branches.
By default, submodules are tied to a fixed commit. They do not follow the latest changes of the remote repository automatically. You must update them manually using
git submodule update --remote. - Submodule updates must be committed.
If you move a submodule to a different commit, the parent repository registers this as a change. You must stage and commit the updated pointer.
- Cloning requires additional steps.
Users must either run
git submodule initandgit submodule updateor clone with--recurse-submodules. - Workflows become more complex.
If branches reference different submodule commits, merges and rebases can be complicated. Ensure coordination when working in teams.
- CI/CD pipelines require submodule handling.
Automated build or deployment processes must include logic to fetch and update submodules. A common issue is forgetting to include
--recurse-submodules.
Submodules should be used only when independent versioning of external repositories is truly required. Otherwise, solutions like package managers or monorepo structures may be simpler to maintain.
Remove a Git Submodule
If you no longer need a Git submodule, follow these steps to remove it completely:
Deinitialize the submodule:
$ git submodule deinit -f vendor/example-libDelete the submodule directory:
$ rm -rf vendor/example-libRemove the submodule entry from .gitmodules:
$ git config -f .gitmodules --remove-section submodule.vendor/example-libStage the modified .gitmodules file:
$ git add .gitmodulesRemove the submodule configuration from Git:
$ git config --remove-section submodule.vendor/example-libRemove the submodule from the Git index:
$ git rm --cached vendor/example-libCommit the cleanup:
$ git commit -m "Remove vendor/example-lib submodule"Push the changes to the remote repository:
$ git push origin mainThese steps ensure that all references to the submodule are completely removed from your Git project.
Conclusion
In this tutorial, you learned how to use Git submodules to organize reusable code across multiple projects. You added submodules to a repository, cloned projects with submodules, updated them to pull remote changes, and removed them when no longer necessary. By leveraging submodules correctly, you can keep project structures modular, avoid code duplication, and ensure consistency in versioning dependencies.
Testen Sie Ihr Setup auf ccloud³
Registrieren Sie sich in der ccloud³ und erhalten Sie 200 € Startguthaben für Ihr Projekt – z. B. für eine PostgreSQL-VM mit automatischen Backups.