Git submodules feature grants you the ability to add links to a Git repository to other repositories as dependencies. When linked, the submodules are integrated as a subdirectory to the main repository you are working on and by default the content is not downloaded, but the Git history. The most simple use case for using this feature is for fetching updates for the submodules from time to time.
Making changes to a submodule does not affect the main repository and vice-versa. The Git history is kept separated, only showing changes when you are in the directory of the repository you want to commit changes. A use-case for this Modularity approach is to manage multiple applications in a centralized place while keeping each code-base logically separated. Particularly, when attempting to move a massive monolithic application into a microservice type of architecture with buy-in from the team. It does not solve every issue with tracking each separate pull request or issue, but this feature can be useful for collecting repositories together and updating each one easily with one command.
Other examples of utilizing Git submodules can be when adding a Design Language System, an internal or external library, creating an Android/iOS native application from a web application, etc. Before adding a submodule, verify if an alternative like NPM or other dependency managers would be better solutions because these tools are very easy to use and have extensive configuration options.
For the following sections, we will be exploring a few commands to get you started on utilizing this feature.
Adding a submodule
To add a submodule to a Git repository is quite simple and all you will need is the URL of the remote repository. This will add a subdirectory with the name of the submodule and a configuration file named
.gitmodules that stores the mapping between the URL of the submodule and the subdirectory where it is contained.
git submodule add url-for-remote-repository
If you run
git status you will see the files mentioned above. Make sure to add and commit these new files to incorporate the submodule. Git won't track changes in the subdirectory as long as you aren't in the directory because it recognizes that it is a submodule.
On Git repository hosting providers like GitHub or GitLab they have a feature where they will display the submodule on the main repository after the changes have been added and If you click the submodule on the platform it navigates you to the repository's page.
Cloning a project that contain submodules
When you clone a repository that contain submodules, by default it won't download the submodule's content. To clone a project and also include the submodules content, you will have to use the
--recurse-submodules[=<pathspec>] flag. By default, if no
pathspec is provided it initializes and clones all submodules, in the repository. If a submodule has submodules this command will also get the content for that repository.
git clone url-for-remote-repository --recurse-submodules
Updating a particular submodule content, you will need to use the
merge command on the submodule directory.
cd module git fetch git merge origin/main
With new changes merged, you can run
git diff --submodule and see that the submodule was updated with a list of commits that were added.
To avoid running all the previous commands, there is an alternative to updating an individual submodule. By default, it will fetch and update the default branch in the URL specified in
origin . Using the
--remote flag, it integrates the changes from the remote repository into the current HEAD. If you leave this flag off, it will only fetch the commit history, but not merge it.
git submodule update --remote name-of-submodule
To change the default branch on your submodule, you utilize the
git config utility. The following command changes the branch for everybody that has access to the remote repository.
git config -f .gitmodules submodule.name-of-submodule.branch new-branch-name
If you only want to change the default branch for yourself locally, leave off the
-f .gitmodules, but depending on your situation it might make more sense for everybody to be tracking the same branch.
Updating all submodules, including submodules of submodules you can use the
git submodule update --remote --recursive
Removing a submodule
Removing a submodule from your main repository, you remove the reference of it first.
git submodule deinit name-of-submodule
When that is completed, you will need to delete the subdirectory of the submodule and
rm -rf .git/modules/name-of-module git rm name-of-module rm -rf name-of-module
- GitLab. “Files · Main · CommitHub / Binary-Clock-Android.” Accessed October 9, 2021. https://gitlab.com/commithub/binary-clock-android/-/tree/main.
- Gallagher, James. “Git Submodules: A Step-By-Step Guide.” Career Karma, July 25, 2020. https://careerkarma.com/blog/git-submodules/.
- “Git - Git-Clone Documentation.” Accessed October 9, 2021. https://www.git-scm.com/docs/git-clone.
- “Git - Git-Rm Documentation.” Accessed October 11, 2021. https://git-scm.com/docs/git-rm.
- “Git - Git-Submodule Documentation.” Accessed October 11, 2021. https://git-scm.com/docs/git-submodule.
- “Git - Submodules.” Accessed October 9, 2021. https://git-scm.com/book/en/v2/Git-Tools-Submodules.
- “How to Add and Update Git Submodules - Studytonight.” Accessed October 11, 2021. https://www.studytonight.com/git-guide/how-to-add-and-update-git-submodules.
- Stack Overflow. “How to Update Submodules in GIT.” Accessed October 9, 2021. https://stackoverflow.com/questions/33714063/how-to-update-submodules-in-git.