NB: You can find git-subtree at on github
Today I used git-subtree for the first time, and I think it’s fantastic.
Working with multiple git repositories for the same codebase is painful. We have an open source project, Astrid, which has a main project and multiple libraries of shared code. In order for collaborators to work on Astrid, they have to git checkout not one, but three different repositories, and put them in the right folders such that relative paths in the Astrid project correctly find their dependencies. It’s a lot of work and easy to get wrong.
With git-subtree, all of those libraries are pulled into one repository. Collaborators only have to check out and commit code to one repository, which:
- is easier when checking out projects,
- is easier when committing, since there’s only one place you need to commit,
- and is easier when performing merges
Love it. It allows you to pull new changes from the external repositories you are mirroring as well as push changes to them.
I’ve used git submodules in the past, but they were so awful to work with that I not only abandoned them, but re-wrote our repository history so that there was no trace of them. They are unintuitive, broken on older versions of git, and difficult to use if you are modifying files inside a subtree.
So, I love git-subtree. Two important use cases for me are sharing code between Ruby on Rails projects and using Android Library Projects in your Android app. I’m sure there are more, so give it a try!
Since the instructions are a little sparse, here’s how I installed and used it on Ubuntu:
git clone https://github.com/apenwarr/git-subtree.git cd git-subtree sudo ./install.sh # all this does is copies a file to your git folder, i.e. /usr/lib/git-core
And then to use it to merge an existing separate git repository into your current one,
git subtree add --prefix=some-folder --squash ../other-repository master
In your history, you see a parent-less commit get merged into your branch: