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>
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
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
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'
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'
Want to switch each child to the dev
branch and pull the latest code?
git submodule foreach 'git checkout dev && git pull'
Want to stash all changes?
git submodule foreach 'git add . && git stash'
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
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)