DEV Community

Cover image for Git Submodules
Colin McDermott
Colin McDermott

Posted on

Git Submodules

This week I have been learning about Git Submodules.
Submodules is a tool built into git. It's designed to make working with repos within repos a lot easier. Why would you be working with repos within repos? Well, let's talk about that.

Repo-ception

Why would you use a repo inside another repo?
There are several reasons you might want to do this. For example, if you have your own component library you use across multiple projects, and you want to work on both the component library and the app itself side by side. Or on a larger project containing multiple pieces worked on by multiple teams, when you don't want code from the various sections of the project interfering with one another during the development process.

Setting up your repo

So to give a simplified example of this set up we are going to have a parent repo, and 2 child repos, childA and childB.
First off, we need to clone the parent repo. To add the two child repos as submodules of parent we are going to go into the parent and run

git add submodule <repo-address>
Enter fullscreen mode Exit fullscreen mode

for each of the children, replacing <repo-address> with the address for the repo.

Once you've done this, you'll notice a new file has been created: .gitmodules Inside .gitmodules you will notice entries for both childA and childB. Something like this:

[submodule "childA"]
    path = childA
    url = https://github.com/path/to/childA
[submodule "childB"]
    path = childB
    url = https://github.com/path/to/childB
Enter fullscreen mode Exit fullscreen mode

Running git status, you should see an entry for childA and childB being created. We can now commit and push these changes.

Congratulations! You have now set up childA and childB as submodules of your parent repo.

Using your submodules

Cloning

Now that you have the submodules set up, next time you clone parent you will see 2 empty directories, 1 for each of the children. Here is where you will start to see the benefits of using submodules.

Before using submodules, to clone any child repos, you needed to go through and run a git clone for each repo. In this example that would mean only 2 commands, but in a large project where there could be 5 or 6 child repos, it could mean quite a few commands. But with submodules, all we need to do is run one single command:

git submodule update --init
Enter fullscreen mode Exit fullscreen mode

This will then go and clone all the submodule repos into their respective directories.

Installing

Now we have all our code checked out, we need to install it. Working with multiple repos this can be a pain, and very time-consuming, moving in and out of each of the repos to run npm install.

Submodules has a solution! As part of the submodules suite of functionality, git contains a foreach command. To use it, we need to pass the command we want to run to it, in this case npm install, and it will then run that command in each of the submodules.

git submodule foreach 'npm install'
Enter fullscreen mode Exit fullscreen mode

In summary, we're going to replace all of those commands, moving in and out of repos, and using npm install in each one, with a single command executed in the parent.

foreach

Let's take a second now and talk about foreach. This is an incredibly useful little command as you can see.

Want to run npm install in each child?

git submodule foreach 'npm install'
Enter fullscreen mode Exit fullscreen mode

Want to switch each child to the dev branch and pull the latest code?

git submodule foreach 'git checkout dev && git pull'
Enter fullscreen mode Exit fullscreen mode

Want to stash all changes?

git submodule foreach 'git add . && git stash'
Enter fullscreen mode Exit fullscreen mode

I'm sure you get the idea. Anything you want to do in every child repo can be done with 1 command.

Summary

Going back to our example, we now have a fully working version of our project, including all sub-repos, and all we needed to do is the following:

git clone https://github.com/path/to/parent
cd parent
git submodule update --init
npm install
git submodule foreach 'npm install'
npm start
Enter fullscreen mode Exit fullscreen mode

This was just a simple example showcasing what git submodules can do. There are plenty more useful features that I would encourage you to check out. Git themselves have some great documentation on submodules available here

Top comments (0)