Technical viewpoint: Submodules in Git

It is common while working on a project to need to iuse another project from within it. For example there is a library developed by a third party or the project development is the responsibility of several programmers and the work is done separately. In these situations there is a need for two separate projects while still having the ability to use one from within the other.

This issue is addressed in Git with submodules. Submodules allow keeping one Git repository as a subdirectory of another Git repository. This way you can clone another repository into your project while keeping the commit histories clean and separate. It still behaves like any repository.

Submodules in Practice

You can add a submodule into your repository with git submodule add URL. The command clones the submodule from the given URL to the path defined. It is worth to note that this creates a new file .gitmodules. This file stores the information on how the repositories map and is version controlled.

Cloning a Project with Submodules

When cloning a project (e.g. your project repository) with a submodule in it, you do not get the contents of the submodule, only the directory. In order to get the files, you need to run two commands git submodule init and git submodule update. The first initializes you local configuration file and the second fetches the contents of the submodule. For example:

git clone submodule_URL
cd <submodule>
git submodule init
git submodule update

An easier and recommended way is to use --recurse-submodules when cloning to initialize and update automatically, i.e.

git clone --recurse-submodules URL-of-the-repository

Submodules and Working on the Project

As the work progresses new work needs to be updates from the submodule. It is important to keep in mind that is it defined in the main repository which commit or branch is used from the submodule. There can be situations where the submodule needs to be set to a specific version od the follow a specific branch of the repository. This way we can be sure that the changes occuring in the submodule do not cause unexpected changes in the main repository.

The submodule is updated with

git submodule update --remote

By default the command assumes you wish to fetch main from the submodule. This can be defined in the .gitmodules file with the command

git config -f .gitmodules submodule.submodule_name.branch <branch>
As the submodule is a repository inside a repository it can be updated as a normal reposotory by moving into its folder and running

git fetch and git merge normally.

More Information

You can read more on submodules in the Git book. The documentation is available in: https://git-scm.com/docs/git-submodule.