Working with Git Submodules

Ishalli Garg
4 min readFeb 1, 2021

It often happens that while working on one project, you need to use another project from within it. Perhaps it’s a library that a third party developed or that you’re developing separately and using in multiple parent projects. A common issue arises in these scenarios: you want to be able to treat the two projects as separate yet still be able to use one from within the other.

Git addresses this issue using submodules. Submodules allow you to keep a Git repository as a subdirectory of another Git repository. This lets you clone another repository into your project and keep your commits separate.

Let’s say you’re working on a project called Slingshot. You’ve got code for y-shaped stick and a rubber-band.

At the same time, in another repository, you’ve got another project called Rock — it’s just a generic rock library, but you think it’d be perfect for Slingshot. Now you can add rock as a submodule of slingshot.

Setting up git submodule is rather straightforward. The real problem with git submodules is maintaining dependencies updates and removing dependencies.

Since submodule is another repository, we have to manually update each dependency. Even thought there is an option to pull changes of submodules, there is no way to auto-update dependencies on the pull.

Removing submodule is also not that easy as initialising. To look more deeply in the topic of git submodules I recommend reading Mastering Git submodules.

Let’s start now by adding a submodule.

Adding a submodule

We can add the project as a submodule to a repository(parent) like this,

git submodule add <git-remote-repo-url>

This will clone the submodule repository and add the information of the submodule to the main repository. This information describes which commit the submodule is pointing to. Also, the submodule’s code will not automatically be updated if the submodule repository updated. This situation has a good point because our code might not work with the latest commit of the submodule, then it will prevent unexpected behavior.

Cloning the repository with submodule

When we clone the project with submodules, first we have to clone the main repository.

git clone <git-remote-repo-url>

Cloning will create the directories that contain submodules but it will create directories without any files of submodule repositories.

So for that we have to run two commands,

git submodule init

Then it will update the .git/config by the mapping from the .gitmodules file.

After it, we have to get all data of the submodule.

git submodule update

This will fetch all the data from the submodule and check out the mapped commit in the parent project.

There is another way to do this which is a little simpler, however. If you pass --recurse-submodules to the git clone command, it will automatically initialize and update each submodule in the repository, including nested submodules if any of the submodules in the repository have submodules themselves.

Updating the submodule repository

We use the same data access layer for many projects. Then we update the data access layer in the project and have to share changes with other projects. For that, first we have to commit the changes in the submodule and push it to the submodule and then we have to push the commits to the parent repository.

So when we update inside the submodule repository project. First, we have to commit new changes to the submodule.

cd [submodule directory]
git add .
git commit -m “commit message”

After it, we go back to the main repository and check the current status of the main repository.

cd ..
git status

Now we can see new commits of submodules in the main repository. It will not show details about commits because that is the responsibility of the submodule.

Then we have to push the new commits. For that, first have to push the commits of submodule. After that, we have to commit changes and push the commits of the main repository.

cd [submodule directory]
git push -u origin <branch>

Then go back to the main repository and push the commits.

cd ..
git add .
git commit -m “commit message”
git push -u origin <branch>

Now you can use the latest commits into other projects as well.

It’s important to note that submodules these days keep all their Git data in the top project’s .git directory, so unlike much older versions of Git, destroying a submodule directory won’t lose any commits or branches that you had.

With these tools, submodules can be a fairly simple and effective method for developing on several related but still separate projects simultaneously.

--

--