Author avatar

Benney Au

Using Git Submodules to Reference One Git Repository from Another

Benney Au

  • Oct 7, 2020
  • 4 Min read
  • 108 Views
  • Oct 7, 2020
  • 4 Min read
  • 108 Views
IT Infrastructure
GitHub
DevOps Tools and Methodologies
Source Control Management

Introduction

When a code project becomes large in scope, it typically depends on external code that other teams or individuals have written. There are a few ways to incorporate external code into your own repository. A previous guide, Referencing One Git Repository from Another, covered how to use git subtree commands to nest one or many repositories inside another. Using Git submodules is an alternative way to incorporate a snapshot of one repository inside another. It can help you keep these repositories in sync without tedious and error-prone copy-pasting.

This guide covers this alternative approach using Git submodules and discusses how to perform some common operations with them.

Dotfiles Example Use Case

This guide will use the same dotfiles example repository discussed in Referencing One Git Repository from Another to illustrate the topic.

Set Up the Repository

To get started using git submodules, initialize a repository in the usual way by creating a folder and committing it.

1
2
3
4
5
6
cd ~
mkdir dotfiles
cd dotfiles
git init
touch readme.md
git add . && git commit -m "initial commit"

Add a VIM Plugin Using Git Submodule

With the root or parent repository created, we can start referencing other repositories using the git submodule command.

Run the following command:

1
git submodule add [email protected]:tpope/vim-dispatch.git vim/pack/start/dispatch -b main

This command adds the submodule and creates a new vim folder in your root repository. It is similar to the git subtree command where you specify the remote repository you would like to clone, the location where you would like it saved, and the branch you want to track.

One difference, however, from the git subtree is that a new .gitmodules file has also been created at the root. Its contents are displayed below. It is a mapping file between local submodules' location and their remote repository.

1
2
3
[submodule "vim/pack/start/dispatch"]
        path = vim/pack/start/dispatch
        url = [email protected]:tpope/vim-dispatch.git

These changes are not committed automatically, so you will have to separately commit them.

1
2
git add .
git commit -m "added vim dispatch submodule"

Update Git Submodules

As the repositories you want to nest are updated with new features and bug fixes, you will want to incorporate them into your dotfiles. One small advantage of submodules over subtrees is that updating one or many repositories is simpler.

With submodules, you can automatically update all nested repositories with one command.

1
git submodule update --remote --merge

This will iterate through your .gitmodules file and pull the latest commits against the specified tracked branch. If there are updates, they won't be committed to the repository yet. This is useful since it gives you an opportunity to test the new code before committing to your own repository.

In contrast, when using git subtree, you will need to run the git subtree pull command for each nested repository or manually set up a script to do this. This can be tedious if you have several nested repositories.

Initialize Git Submodules

Finally, as you switch computers, you will want to clone your dotfiles repositories onto them, and you will also want the submodules. However, to do this, you need to run an additional command or pass a separate flag. git clone [repo] is insufficient.

If you haven't cloned your repository, remember to specify the --recursive flag:

1
git clone --recursive [email protected]:chinwobble/dotfiles.git

If the repository is already cloned, run the git submodule update command:

1
git submodule update --init --recursive

This is one of the major disadvantages of git submodules. It requires other users of your repository to perform extra actions that they wouldn't normally need to perform.

Conclusion

Git submodules are another way to leverage Git as an external dependency management tool. Submodules have an additional learning curve over git subtree for your team, so it's important to consider whether your project actually needs them.

0