- **Epistemic status:** #evergreen ![[git-submodules.svg]] [[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 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. ```bash 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. ![[Pasted-image-20211009104527.png]] [Source repository](https://gitlab.com/commithub/binary-clock-android/-/tree/main) ## 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. ```bash git clone url-for-remote-repository --recurse-submodules ``` ## Updating submodules Updating a particular submodule content, you will need to use the `fetch` and `merge` command on the submodule directory. ```bash 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. ```bash 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. ```bash 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 `--recursive` flag. ```bash git submodule update --remote --recursive ``` ## Removing a submodule Removing a submodule from your main repository, you remove the reference of it first. ```bash git submodule deinit name-of-submodule ``` When that is completed, you will need to delete the subdirectory of the submodule and `.git/modules/name-of-submodule` directory. ```bash rm -rf .git/modules/name-of-module git rm name-of-module rm -rf name-of-module ``` --- ## References - 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>.