Git Submodules | An Introduction

Victor Bruce

Victor Bruce

Mon Jan 29 2024

main

I wanted to create a GitHub repository that contains other repositories. The main goal was to organize projects based on topics, type, etc. Through my search, I came across the topic of Git Submodules, which I will be delving into today! So let’s get started!

Git Submodules(What is it?)

Git Submodules allow you to keep a Git repository as a subdirectory of another Git repository. In other words, Git Submodules allow you to have a parent Git repository that contains other Git repositories within as subdirectories.

When or Why do we use Git Submodules?

The common reason for using Git Submodules is to share libraries. Instead of writing your own code, you can add a library and there are several ways of doing that. You can use a package manager like NPM install, Ruby gem, etc., or copy the source code into your project tree.

The issue with including the library is that it is difficult to customize and deploy. Also, the issue with copying the code into your own project is that any custom changes you make are difficult to merge when upstream changes become available.

Git addresses this issue with Git Submodules.

A Practical Example

In the example below, I will want to create a main project called frontend-challenges to house a few sub-projects to organize all of my frontend UI coding challenges projects.

/* frontend-challenges */
├── src
└── README.md

/* challenge-1 (hash commit:ae2345) */
├── src
└── README.md

/* challenge-2 (hash commit:e89cde) */
├── src
└── README.md

/* At the end this is what i want 🏆 */
/* frontend-challenges */
├── src
│   ├── challenge-1 (@ae2345)
│   │   ├── src
│   │   ├── README.md
│   ├── challenge-2 (@e89cde)
│   │   ├── src
│   │   ├── README.md
└── README.md

Adding an existing Git repository as a submodule

Assuming I am already working on the main project(frontend-challenges). To add a new submodule, you use the git submodule add command with the absolute or relative URL of the project you would like to start tracking. In this example, we’ll add a frontend challenge project called challenge-1

git submodule add https://github.com/username/challenge-1

By default, submodules will add the subproject into a directory named the same as the repository. In our case, challenge-1.

.gitmodules

You should notice a new .gitmodules file after adding the subproject. The .gitmodules file is a way Git tracks its submodules. It stores the mapping between the project’s URL and the local subdirectory you’ve pulled into:

[submodule "challenge-1"]
  path = challenge-1
  url = https://github.com/username/challenge-1


Note: the .gitsubmodules file is version-controlled just like the .gitignore file. It is pushed and pulled with the rest of your project. This is how other people who clone this project know where to get the submodule projects from.

Cloning a Project with Submodules.

Assuming we are working on a different machine and want to clone our frontend challenges repository, which now has a submodule. You can run the command:

git clone https://github.com/username/frontend-challenges

Note: When you clone a project with submodules, by default, you get the directories that contain submodules but none of the files within them yet.

In our example, when we clone the frontend-challenges project, we will get an empty directory for the submodule challenge-1. You can add a different path at the end of the command if you want it to go elsewhere.

There are two methods for populating the empty submodule directory under the main project.

  1. While cloning the main project(frontend-challenges), add the --recurse-submodules flag.
git clone --recurse-submodules https://github.com/username/frontend-challenges

2. Alternatively, if you have already cloned the project and forgot the --recurse-submodules , you can combine the two commands:

  • git submodule init to initialize your local configuration file and
  • git submodule update to fetch all data from that project and check out the appropriate commit listed in your main project.
git submodule update --init

Where to go from here

That was just a quick intro to Git Submodules. We looked at adding other Git repositories to a Git repository and how to clone a repository with submodules.


Additionally, you can look into how to pull upstream changes from a project remote, publish submodule changes, merge submodule changes, and other advanced topics on Git Submodules.

Also, I would suggest the following resources for additional information about Git Submodules, which I found very helpful.