Git Subtrees

Git sub­trees are an alter­na­tive to sub­mod­ules. Some devel­op­ers pre­fer them because it’s faster to clone a project and get the shared code. Sub­tree is a more recent addi­tion to Git.

Sub­trees allow you to include anoth­er repos­i­to­ry as a sub­di­rec­to­ry in a project. Unlike Sub­mod­ules, Sub­trees don’t cre­ate con­fig­u­ra­tion files or require mul­ti­ple steps to ini­tial­ize and fetch the includ­ed repository’s contents.

And, sim­i­lar to sub­mod­ules, a sub­tree can be altered via commits. 

Adding a Sub­tree #

To add a sub­tree we use the spe­cial sub­tree com­mands. First, we add the repository:

$ git subtree add --prefix my-subdirectory
http://mysite.com/my_other_project.git master --squash

In the above exam­ple we are adding the exter­nal repos­i­to­ry as a sub­tree in the my-subdirectory direc­to­ry. We are request­ing the master branch and using the --squash option to squash all the com­mits into a sin­gle commit.

The out­put should look some­thing like this:

$ git fetch http://mysite.com/my_other_project.git master
warning: no common commits
remote: Counting objects: 338, done.
remote: Compressing objects: 100% (133/133), done.
remote: Total 338 (delta 101), reused 338 (delta 101)
Receiving objects: 100% (338/338), 71.46 KiB | 0 bytes/s, done.
Resolving deltas: 100% (101/101), done.
From http://mysite.com/my_other_project.git
 * branch            master     -> FETCH_HEAD
Added dir 'my-subdirectory'

If we dis­play the log of the project, we’ll see the addi­tion of this repos­i­to­ry and its squashed com­mits as a merge commit:

commit 9702b4c1bfe0f8ffdb423ef6d511a18e040a98b0
Author: Ryan Irelan <[email protected]>
Date:   Fri Apr 15 15:36:45 2016 -0500

	Squashed 'my_other_project' content 
	from commit 02199ea

	git-subtree-dir: my_subdirectory
	git-subtree-split: 02199ea0080d744ec76b79d74ce56d51d25cf7ae

To update the sub­tree repos­i­to­ry we need to run subtree pull:

$ git subtree pull --prefix my-subdirectory 
http://mysite.com/my_other_project.git master --squash

Yes, that’s anoth­er long com­mand just to pull down changes. This is a major draw back of using sub­trees over submodules.(fn) But no solu­tion will be per­fect; choose the one that makes the most sense with your workflow.