Git Submodules allows to use a git repository as a subdirectory of another repository. This enables us to use another repository with a reference that can be tracked separately from the main repository.
When to use
Often an application (hosted on git), will have dependencies on other external code. There are different ways to incorporate those in the primary repository.
- Directly copy paste the code into the main repository
This is the simplest way to use the code, but it might become problematic soon when there is update to the dependency. Then the changes would need to be updated across everywhere it was used. - Using it as a package
This is the most used method and almost all 3rd party libraries provide themselves as a package that can be installed in the primary repository through the use of a package manager. For example, NPM, which is the package manager for Node packages. The issue with this approach is the requirement to release a version for every change and test. It is also difficult to track changes in this external repository. - Using Git Submodules
With using this approach, it keeps a track of the specific commits of the external repository, and can be updated whenever required.
Adding a Git Submodule
To add a submodule to an existing repository, change-directory to the folder using the Command Line, and then:
cd primary-repo/
git submodule add path-to-external-repo/library-name.git
This is going to create a .gitmodules file in the base folder, which would contain information (or metadata) about the added submodule. This will also create a folder (library-name/ for the above command) to host the library.
// .gitmodules
[submodule "library-name"]
path = library-name
url = path-to-external-repo/library-name.git
Every submodule added will insert additional entries to this file. Additional configurations for adding a submodule can be found here.
Now commit the newly added .gitmodules file and the library folder, and push to repository.
Working with Git Submodules
For anyone cloning the repo after this, they are going to get the .gitmodules file as well as folder with the reference to the commit from the library. To initialize the new repo with the submodules included:
git clone path-to-parent-repo.git
git submodule init
git submodule update
If you have multiple recursive repositories in submodules, then can run the command
git submodule update --init --recursive
The submodules have their own git repository management. So you can perform all those git actions directly on those folders. Be aware that when you init/update the submodules, they are checked out to a particular commit. So switch to the right branch, before starting to make changes.
cd library-name/
// this takes us to the repo of the library and out of the main repository
git checkout feature/my_branch
git add .
git commit -m "My changes to library from inside of parent repository"
git push
Now to make sure that the parent repo also has the reference to the right commit, go back to the parent repo, and commit the reference change in commit-id of the submodule/library.
cd ..
git add library-name
git commit -m "Updating reference to library's recent commit"
git push
This sums up the working with Git Submodules. For more git related topics, click here.