When a code project becomes large in scope, it typically depends on external code that other teams or individuals have written. There are a few ways to incorporate external code into your own repository.
A previous guide, Referencing One Git Repository from Another, covered how to use
git subtree commands to nest one or many repositories inside another. Using Git submodules is an alternative way to incorporate a snapshot of one repository inside another. It can help you keep these repositories in sync without tedious and error-prone copy-pasting.
This guide covers this alternative approach using Git submodules and discusses how to perform some common operations with them.
This guide will use the same dotfiles example repository discussed in Referencing One Git Repository from Another to illustrate the topic.
To get started using
git submodules, initialize a repository in the usual way by creating a folder and committing it.
1cd ~ 2mkdir dotfiles 3cd dotfiles 4git init 5touch readme.md 6git add . && git commit -m "initial commit"
With the root or parent repository created, we can start referencing other repositories using the
git submodule command.
Run the following command:
1git submodule add [email protected]:tpope/vim-dispatch.git vim/pack/start/dispatch -b main
This command adds the submodule and creates a new
vim folder in your root repository.
It is similar to the
git subtree command where you specify the remote repository you would like to clone, the location where you would like it saved, and the branch you want to track.
One difference, however, from the
git subtree is that a new
.gitmodules file has also been created at the root. Its contents are displayed below. It is a mapping file between local submodules' location and their remote repository.
1[submodule "vim/pack/start/dispatch"] 2 path = vim/pack/start/dispatch 3 url = [email protected]:tpope/vim-dispatch.git
These changes are not committed automatically, so you will have to separately commit them.
1git add . 2git commit -m "added vim dispatch submodule"
As the repositories you want to nest are updated with new features and bug fixes, you will want to incorporate them into your
One small advantage of submodules over subtrees is that updating one or many repositories is simpler.
With submodules, you can automatically update all nested repositories with one command.
1git submodule update --remote --merge
This will iterate through your
.gitmodules file and pull the latest commits against the specified tracked branch.
If there are updates, they won't be committed to the repository yet.
This is useful since it gives you an opportunity to test the new code before committing to your own repository.
In contrast, when using
git subtree, you will need to run the
git subtree pull command for each nested repository or manually set up a script to do this.
This can be tedious if you have several nested repositories.
Finally, as you switch computers, you will want to clone your
dotfiles repositories onto them, and you will also want the submodules.
However, to do this, you need to run an additional command or pass a separate flag.
git clone [repo] is insufficient.
If you haven't cloned your repository, remember to specify the
1git clone --recursive [email protected]:chinwobble/dotfiles.git
If the repository is already cloned, run the
git submodule update command:
1git submodule update --init --recursive
This is one of the major disadvantages of
It requires other users of your repository to perform extra actions that they wouldn't normally need to perform.
Git submodules are another way to leverage Git as an external dependency management tool.
Submodules have an additional learning curve over
git subtree for your team, so it's important to consider whether your project actually needs them.