Welcome the company of trees

Subversion vendor branches in Git ?

Revision History
Revision 2011-02-22

After using Subversion for a long time the concept of the once quirky vendor branches has become something one is used to. When investigating how to set up a git repository using a similar concept it is in the beginning hard to get an overview of the best way to set up a "Vendor branches" concept.


The first advice one get is "Have you looked into git submodules?". After spending some time reading about the concept it seems more to map the Subversion extern concept. I have not used the extern concept nor the submodules so I can be wrong, but that was my initial impression. It did not seem to be a good fit for the method of vendor branches, reading the Submodules chapter in the ProGit book. But as git is the master of branches, there must be another solution.

Subtree Merging

I first came in contact with the Subtree Merging merging workflow while reading Subtree Merging chapter in the ProGit book. It seemed to fit the vendor branches method much better but there were still some differences. With vendor branches one can use subtrees of the vendor tree in the actual project and the naming of the directories can be different.

I found a suitable solution in the GitHub Supportforums. The discussion described the problem well.

The method apdapts the read-tree call and add the path to it

git read-tree --prefix=local_path/ -u

Comparing the instructions from the ProGit book and the support discussion one sees that a different set of commands are used. The support discussion is using the commands that are used in in the How to use the subtree merge strategy document.

A working solution

Armed with the infomation I went ahead trying to set up a git repositories to use Subtree Merge to handle my usecase of "Vendor branches". My first atempt was to improve my dotfiles git repository. I use nxml-mode under emacs and lately I have started to play with html5. To add html5 capability, I wanted to add the project html5-el to my .emacs.d/site-dist as it was not yet packaged for the distribution I use, Debian.

I added the remote repository, merged it and bind it to my tree and commite the changes.

      git remote add -f html5-el https://github.com/hober/html5-el.git
      git merge -s ours --no-commit html5-el/master
      git read-tree --prefix=.emacs.d/site-dist/html5-el -u html5-el/master
      git commit -m 'merging in html5-el'

Getting more advanced

To do a subtree in a subtree, like for example putting one style from the tree-cutter project inside your own sites git.

      git remote add -f tree-cutter https://source.tree.se/git/tree-cutter.git
      git merge -s ours --no-commit tree-cutter/master
      git read-tree --prefix=style/www -u tree-cutter/master:style/freggies
      git commit -m 'merging in freggies stylesheets to my www'

To later properly merge new chages, one does not use the normal subtree merge, as it in my case picked the wrong subtree. I found that recursive with subtree worked better. Your milage might vary. Check your merge before pushing it to the master repository.

      git pull --no-commit -s recursive -X subtree=style/freggies tree-cutter master
      git commit
      git log --first-parent
      git log -p -m --first-parent