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
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.
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.,
Therefore, this setting repository is named
dotfiles by convention.
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
One common use case is embedding VIM plugins that are published as GitHub repositories into your
To start using
git subtrees in this way, first create a
1 2 3 4 5 6
cd ~ mkdir dotfiles cd dotfiles git init touch readme.md git add . && git commit -m "initial commit"
Note that these are bash commands. If you are on Windows, you can execute them in
You have created a
dotfiles repository with a blank readme file.
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.
git subtree add --prefix vim/pack/github/vim-sensible [email protected]:tpope/vim-sensible.git master --squash
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.
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.
git subtree pull --prefix vim/pack/github/vim-sensible/ [email protected]:tpope/vim-sensible.git master --squash
This creates a new commit and squashes any changes on top your
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
3. Run the below command to push to your fork.
git subtree push --prefix vim/pack/github/vim-sensible/ [email protected]:chinwobble/vim-sensible.git issue-xxx
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
If you are working on a GitHub issue, you may want to use the issue number as the branch name.
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.