Git Submodule: Managing Dependencies with Precision
Tags: git, submodule, github, gitlab
Published: 2024-02-01 09:30:09


Assume that many files are shared between countable microservices and are crucial for the project life-cycle. Such as the `.proto` file that could be used in both the `gateway` service and many other related services. 
As an approach, you can use a `symbolic link` to have access, but many conflicts like dependency on the file system structure occur. If directories change or if you move your project, links might break. Consider using Git submodules or separate Git repositories for shared `proto` files provides versioning and easier management for this dummy scenario.

## What is the Git Submodule?

Git submodules facilitate the inclusion of one **Git Repository** as a **Subdirectory** within another Git Repository. 
Essentially, a Git submodule is a reference to a specific snapshot of another repository. This functionality 
allows a Git repository to integrate external code, retaining the ability to track its version history.

Git submodules are beneficial in scenarios where strict version control of external dependencies is crucial. Common use cases include:

- Ensuring Stability: If an external component evolves rapidly or anticipated changes may disrupt the API, you can secure the code by fixing it to a specific commit for stability.

- Managing Vendor Dependencies: For components with infrequent updates, Git submodules are useful for tracking them as vendor dependencies.

- Third-Party Integration: Delegating a project segment to a third party becomes more manageable when you want to incorporate their work at a specific time or release, especially when updates are sporadic.

### Git Submodule Practical Commands

These are basic commands, and depending on your specific use case, you might need to explore more advanced submodule commands.
To dig deeper into the concept, reviewing the [ Git Official Documentation is recommended](https://git-scm.com/docs/git-submodule).

- Add a Submodule:

```shell
git submodule add <repository_URL> <path>
```

Example:
```shell
git submodule add https://github.com/example/repo.git vendor/repo
```

- Initialize Submodules After Cloning a Repository:
```shell
git submodule update --init --recursive
```
- Update Submodules: To fetch the latest changes from the submodule repositories.

```shell
git submodule update --remote
```

- Clone a Repository with Submodules: To clone a repository and its submodules.
```shell
git clone --recursive <repository_URL>
```

- Initialize Submodules After Cloning (Older Git Versions): For Git versions older than `1.6.5`.
```shell
git submodule init
```
```shell
git submodule update
```

- Fetch Submodule Changes: To pull changes from the master branch of each submodule.
```shell
git submodule deinit -f -- <submodule_path>
```
```shell
git rm -f <submodule_path>
```
```shell
rm -rf .git/modules/<submodule_path>
```
- Remove a Submodule: After running these commands, you also need to commit the changes.
```shell
git submodule deinit -f -- <submodule_path>
```
```shell
git rm -f <submodule_path>
```
```shell
rm -rf .git/modules/<submodule_path>
```

- Update Submodule URL: If the URL of a submodule has changed, you need to run this command to update the configuration.
```shell
git submodule sync
```

- Clone Submodule Recursively: To clone a repository and its submodules in one step.
```shell
git clone --recursive <repository_URL>
```

Custom Commands
You can use the `git submodule foreach` command to run custom commands on each submodule.

Example:

```shell
git submodule foreach 'git checkout master'
```

This checks out the master branch in each submodule.