What are submodules in git?

If you have worked in software development, you have certainly been developing your application using libraries or packages developed by others, whether it is open-source or not. It could be that your project A depends on a project B both of which are from different git repositories in your organisation.

What happens when you want to be able to treat the two projects as separate yet still be able to use one from within the other?

If you had a package manager and you wanted to develop against a specific version, you could just pull down that version and develop against it.

But then what if you wanted to customise a specific version of the package and test those changes against yours?

Submodules are Git’s way of dealing with this sort of a situation.

Git submodules allow you to copy one repository as a subdirectory of another and use it as if it was all in the same repository and keep the commits in the real repository separate from the one you are developing!

How do I use a submodule?

If you are in a situation like me, where you use a project like Hugo static website generator while its themes are to be installed as submodules then you probably have used submodules. If not you can do this pretty easily.

Add a repository as a submodule to your repository

The git submodule command takes an add command along with the URL of the repository which you wish to make your repository’s submodule.

$ git submodule add https://github.com/superuser/submodrepo
Cloning into 'submodrepo'...
remote: Counting objects: 299, done.
remote: Compressing objects: 100% (299/299), done.
remote: Total 299 (delta 0), reused 299 (delta 0)
Unpacking objects: 100% (299/299), done.
Checking connectivity... done.

Adding a repo as a submodule will automatically get the latest commit of submodule repository into your git repository.

What actually happens is that a new file is created called .gitmodules and this file holds the metadata regarding the submodule repository.

Clone a repo with a submodule

This is what you will most likely have to do when you start working with a project that uses submodules. The easiest way to do this is pass an additional option to the git clone command

$ git clone --recurse-submodules https://github.com/superuser/mainrepo
Cloning into 'mainrepo'...
remote: Counting objects: 123, done.
remote: Compressing objects: 100% (122/122), done.
remote: Total 123 (delta 1), reused 123 (delta 0)
Unpacking objects: 100% (123/123), done.
Checking connectivity... done.
Submodule 'submodrepo' (https://github.com/superuser/submodrepo) registered for path 'submodrepo'
Cloning into 'submodrepo'...
remote: Counting objects: 299, done.
remote: Compressing objects: 100% (299/299), done.
remote: Total 299 (delta 0), reused 299 (delta 0)
Unpacking objects: 100% (299/299), done.
Checking connectivity... done.
Submodule path 'submodrepo': checked out '4706aee0c1c2cf626f67804395742644b14b7c0b'

Get the latest version of the submodule repo

If this is the first time you have checked out a repository that has submodules then you have to run

git submodule update --init --recursive

That should start cloning the submodule’s git repository to the correct directory.

Submodule 'submodules/submodule-project' (https://github.com/fantastic-user/submodule-project.git) registered for path 'submodules/submodule-project'
Cloning into '/home/eakan/github/software-craftsperson/submodules/submodule-project'...
Submodule path 'submodules/submodule-project': checked out 'a3c90af8a4ea04433d95d02a1dc07b0014c5b8b8'

Once you have done this in your git repository that uses submodules, then you could keep your submodule updated by running:

git submodule update --recursive --remote

or

git pull --recurse-submodules

I use the second option quite frequently when working with my blog to ensure I have the latest commit from the theme repository.

That should be sufficient to get started working with Git submodules.