git-submodule
Manage external repositories within a Git repository
TLDR
Install a repository's specified submodules
Add a Git repository as a submodule
Add a Git repository as a submodule at the specified directory
Update every submodule to its latest commit
SYNOPSIS
git submodule
git submodule add [-b
git submodule update [--init] [--remote] [--[no-]recursive] [--force] [--checkout|--rebase|--merge] [--reference
git submodule status [--cached] [--recursive] [--] [
git submodule init [--] [
git submodule deinit [-f|--force] [--]
git submodule foreach [--recursive]
PARAMETERS
add
Adds a new submodule to the repository. The <repository> is the URL of the external repository, and <path> is the relative path where it should be cloned.
update [--init] [--remote] [
Updates the registered submodules to the commit specified by the superproject. --init initializes uninitialized submodules. --remote updates to the HEAD of the submodule's remote tracking branch.
status [
Shows the status of the submodules. It indicates if the submodule is at the specified commit, has local changes, or is uninitialized.
init [
Initializes the submodules by creating their .git/config entries from .gitmodules.
deinit [-f|--force]
Unregisters the given submodules. Removes the submodule entry from .git/config and .gitmodules. Use --force to remove modified submodules.
foreach [--recursive]
Executes an arbitrary shell command in each checked out submodule.
sync [
Synchronizes remote URL configurations for submodules. Useful when the superproject's remote URL changes.
set-url
Sets the URL of the given submodule.
set-branch [-b
Sets the default branch for the given submodule.
absorbgitdirs
Moves the .git directory of a submodule into the superproject's .git/modules directory to simplify submodule management.
--cached
Operates on the index copy of the submodule entry, not the working tree.
--recursive
Processes submodules recursively, i.e., also operates on nested submodules.
--force
Used with update to discard local changes in the submodule working tree, and with deinit to remove modified submodules.
--reference
During add/update, use the local repository as a reference for cloning, allowing a local clone to be used instead of fetching from the network.
--depth
During add/update, creates a shallow clone with a history truncated to the specified number of commits.
DESCRIPTION
The `git-submodule` command is a powerful utility within Git designed to manage repositories embedded inside another repository. It allows a project to incorporate external code or libraries without directly copying them into the main project's repository. Instead, it maintains a reference to a specific commit of another Git repository, known as a submodule. This enables developers to keep external dependencies separate while still tracking which version of those dependencies their project uses. Submodules are particularly useful for managing shared components, third-party libraries, or complex projects broken into smaller, independent parts. They provide a mechanism to ensure that all developers working on a project are using the exact same versions of all dependencies, improving consistency and reproducibility.
CAVEATS
Detached HEAD: Submodules often check out into a detached HEAD state. This means if you make changes directly within the submodule and commit, those changes are not on a branch. You must manually create or switch to a branch, commit, and then update the superproject's reference.
Updating Superproject: After pulling changes in a submodule or switching its branch, the superproject needs to be updated to record the new commit hash. Forgetting this can lead to inconsistencies.
Deleting Submodules: Deleting a submodule requires several manual steps: removing the entry from .gitmodules, removing the entry from .git/config, un-staging the submodule, and finally removing the submodule directory itself. git submodule deinit helps with some of this, but it's not a single-command delete.
Cloning Recursively: New users often forget to clone the superproject with --recursive or run git submodule update --init --recursive after cloning, leading to empty submodule directories.
Branch Management: If a submodule needs to track a specific branch rather than a fixed commit, you must use git submodule update --remote or git submodule set-branch.
.GITMODULES FILE
When you add a submodule, Git automatically creates or updates a .gitmodules file in the superproject's root directory. This file is a plain text file that maps the submodule's name to its path and URL. It acts as a configuration file for all submodules in the project and is version-controlled.
SUPERPROJECT'S ROLE
The superproject does not track the contents of the submodule; it tracks a specific commit hash within the submodule's repository. This means if the submodule's repository changes, the superproject only reflects this if its submodule reference is explicitly updated to the new commit.
ALTERNATIVES
While git-submodule is Git's native solution, other methods exist for managing dependencies, such as Git subtrees (which merge the dependency's history directly into the superproject), or language-specific package managers (e.g., npm, Cargo, pip) that download dependencies outside the Git repository.
HISTORY
`git-submodule` was introduced early in Git's history, around version 1.5.2 in 2007. It was designed to address the common requirement of managing external dependencies and components within a larger project, predating more modern dependency management solutions found in specific programming languages. Its initial implementation provided basic functionality for adding and updating external repositories, and it has since evolved with new commands and options to improve usability and address common workflows, such as deinit and foreach, making it a robust, albeit sometimes complex, solution for nested repositories.
SEE ALSO
git-clone(1), git-init(1), git-config(1), git-add(1), git-rm(1)