Заметка из серии «чтобы не забыть» или «может пригодиться».
Периодически возникает задача включить в свой репозиторий часть из другого репозитория. Чаще всего это нужно для подключения различных библиотек. Например, если хочется воспользоваться одним из компонентов ZendFramework-а, но нет желания включать весь проект.
Боле-мене рабочий способ требует наличия модуля git-subtree
Описание метода
Предположим, наш проект имеет следующую структуру:
application/
library/
App/
...
tests/
...
В каталог library/ будем подключать подкаталог Zend/Log из репозитория ZF2. Из всего репозитория нужно взять только Zend/Log. Т.е. в итоге должно получиться так:
application/
library/
App/
Zend/
Log/
...
tests/
...
Во-первых, добавим удаленный репозиторий:
> git remote add zf2 http://github.com/zendframework/zf2
> git fetch zf2
Теперь извлечем из него код в отдельную ветку:
> git checkout -b projects/zf2 zf2/master
Теперь выделим нужный нам каталог в собственную ветку:
> git subtree split --prefix=library/Zend/Log --annotate="[zend_log] " --rejoin -b subtrees/zend_log
Следующим шагом сольем эту ветку в наш мастер:
> git checkout master
> git subtree add --prefix=library/Zend/Log --squash subtrees/zend_log
Added dir 'library/Zend/Log'
На этом импорт закончен. Теперь в репозиторий есть подкаталог library/Zend/Log.
Импортировав таким образом часть чужого репозитория мы решили проблему с включением этого кода в проект, но обрели новую проблему — поддержание импортированного кода в актуальном состоянии.
Обновление импортированного подкаталога
Напомню, что в процессе импорта мы создали две ветки: projects/zf2 и subtrees/zend_log.
Чтобы обновить код, обновим мастер-ветку репозитория ZF2:
> git checkout projects/zf2
> git fetch zf2
> git rebase zf2/master
Затем снова выделим подкаталог:
> git subtree split --prefix=library/Zend/Log --annotate="[zend_log] " --rejoin -b subtrees/zend_log
После чего сольем его с нашим мастером:
> git checkout master
> git subtree merge --prefix=library/Zend/Log --squash subtrees/zend_log
Заключение
Не такой уж и удобный способ, но лучше я пока не нашел. На мой взгляд у него две проблемы:
- сложность в обновлении импортированного кода
- необходимость создавать ветки для каждого нового донора кода и каждого импортируемого подкаталога.


А если весь зенд нужен ?
Включить весь зенд сильно проще — например, можно воспользоваться git submodule
Получается, что если в проекте используется например, только Zend\Log то процесс апдейта ZF2 сопровождается созданием (а затем удалением) тысяч файлов в рабочей директории.
Не создает ли это дискомфорт?
И не пробовал ли ты эту штуку на msysgit под windows?
Да. Именно. Но чекаут у гита очень быстрый — гит не копирует файлы (как svn), он создает жесткие ссылки, что гораздо быстрее.
По крайней мере так работает гит на unix-like системах. За windows не скажу — не пользовал. Но на NTFS я не вижу причин так не делать.
Нет, не пробовал. Я уже несколько лет на винде не веду разработку