Subversion vendor branches in Git ?
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.
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.
The method apdapts the read-tree call and add the path to it
git read-tree --prefix=local_path/ -u remote_branch/master:remote_path1/remote_path2
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
.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