Git subtrees are a powerful feature that let you integrate another Git repository into your own as a subdirectory. Unlike Git submodules, which maintain a reference to an external repo, subtrees physically embed the other repository’s contents within your own history-making them easier to manage in many cases.
This post explains how to use Git subtrees to add and update external repositories within your project.
What Is a Git Subtree?#
A Git subtree imports the entire history of an external project into a subdirectory of your repository, usually as a squashed commit (one combined commit, rather than the full log).
This differs from Git submodules, which store only a pointer to a specific commit in another repository. Subtrees are better when:
- You want to vendor dependencies directly into your repo
- You want to avoid extra tooling for submodules
- You want everything under one roof (e.g., for deployment or archiving)
Commands#
Adding a Git Repository as a Subtree#
You can add another repository as a subtree like this:
git subtree add --prefix=target_dir git_remote.git branch --squash--prefix=target_dir: Specifies the directory within your repo to place the external project.git_remote.git: URL or path to the external Git repository.branch: The branch to import.--squash: Combines the subtree’s history into a single commit.
This results in a commit that looks like this:
commit f5ddddda7d42d06cd7883f7c495124f7dd4f503f
Merge: ed74e04 688ea1d
Author: Pascal <pascal@localhost>
Date: Fri Sep 16 12:02:58 2016 +0200
Merge commit '688ea1de2af40776bfda21e59a14f97e6204e294' as 'foo'
commit 688ea1de2af40776bfda21e59a14f97e6204e294
Author: Pascal <pascal@localhost>
Date: Fri Sep 16 12:02:58 2016 +0200
Squashed 'target_dir/' content from commit 62372d7
git-subtree-dir: target_dir
git-subtree-split: 62372d78da03021a81c12972e483d3d074469be7Updating a Git Subtree#
To pull in changes from the upstream project:
git subtree pull --prefix=target_dir git_remote.git branch --squashThis adds a new squashed commit with the updated content.
Further Reading#
For an in-depth comparison of subtrees vs submodules, see Atlassian’s write-up: 👉 The Power of Git Subtree.
