Author avatar

Benney Au

Referencing One Git Repository from Another

Benney Au

  • Sep 28, 2020
  • 5 Min read
  • 227 Views
  • Sep 28, 2020
  • 5 Min read
  • 227 Views
IT Infrastructure
GitHub
DevOps Tools and Methodologies
Source Control Management

Introduction

In a large organization, you may have dozens or even hundreds of Git repositories. These repositories may have common configuration and scripts, or you may be working in a C++ project where you need to compile several repositories from source code. How do you achieve this without copy-pasting files everywhere?

In this guide, you will learn about git subtrees as a solution to this problem. You will set up a repository and perform some common operations. A basic understanding of the git command line and GitHub is assumed knowledge for this guide. You can watch GitHub Getting Started if you need a refresher.

Note: GitHub is in the process of changing its default branch name from master to main. This guide will use the term master branch since it is the current default branch name at the time of writing. You can learn more about this change by reading GitHub's official documentation on renaming the default branch.

Dotfiles Example Use Case

Over a period of several years, you may find yourself working across dozens of different computers. You can keep the settings consistent across your various machines by creating a Git repository with your settings files saved inside. These settings are usually saved in files prefixed with a dot, e.g., .vimrc, .bashrc, etc. Therefore, this setting repository is named dotfiles by convention. As your dotfiles project progresses, you may want to use scripts and configuration that other people have created. You can leverage and contribute back to the open-source community by referencing these repositories inside your dotfiles using git subtrees.

One common use case is embedding VIM plugins that are published as GitHub repositories into your dotfiles repository.

Set Up the Repository

To start using git subtrees in this way, first create a dotfiles repository.

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

Note that these are bash commands. If you are on Windows, you can execute them in git bash.

You have created a dotfiles repository with a blank readme file.

Add a VIM plugin Using Git Subtree

Within your dotfiles project, create a folder vim/pack/github/ to store your plugins. This folder structure is important so that VIM will automatically detect and run the plugin. You will place the contents of other git repositories inside this folder.

To do this, run the git subtree add command.

1
git subtree add --prefix vim/pack/github/vim-sensible [email protected]:tpope/vim-sensible.git master --squash
sh

This command will embed the master branch of Tim Pope's VIM-sensible in your dotfiles. Also note that you used the --squash flag to compress the history. You can run this command several times to embed multiple repositories.

Update Your VIM Plugin

With one or more subtrees, you may want to update to a specific branch or git tag. You can do this by running the git subtree pull command.

1
git subtree pull --prefix vim/pack/github/vim-sensible/ [email protected]:tpope/vim-sensible.git master --squash
sh

This creates a new commit and squashes any changes on top your dotfiles repository.

Contributing Changes Back to the Nested Repositories

As a good open-source citizen, when you find and fix bugs you will want to share your fixes with the community. git subtree makes this easy since you don't need to separately check out that nested repository. To do this, you will perform the following steps: 1. Fork the nested repository, such as vim-sensible, on GitHub. 2. Commit changes in your dotfiles repository. 3. Run the below command to push to your fork.

1
git subtree push --prefix vim/pack/github/vim-sensible/ [email protected]:chinwobble/vim-sensible.git issue-xxx
sh
  1. Create a pull request on the nested repository
  2. Pull the newest of the remote into your dotfiles.

Note that when pushing, you changed the remote to your own fork and you are pushing to a new branch, in the example above, it's issue-xxxx. If you are working on a GitHub issue, you may want to use the issue number as the branch name.

Conclusion

git subtree is a good option to nest one repository in another. It does not require users to learn extra commands to access the nested repositories. You can learn more about this feature by reading About Git subtree merges.

1