С git submodule многие плюются, но есть альтернатива.
Первоначально до версии Git 1.7.11 , использовалась subtree merge strategy , после этой версии написали удобную комманду git subtree.
Начнем с преимуществ и недостатков этого подхода по сравнению с git submodule, ну а потом рассмотрим сначало старый подход работы, после - новый, с командой:
+:
1) Управляться с простым воркфлоу просто:)
2) Достаточно старые версии поддерживаются (v1.5.2-)
3) Код подпроектов сразу появляется после clone проекта.
4) subtree не принуждает пользователей проекта учить что-то новое, и они даже не обязаны знать об использовании мердж стратегии сабтри.
5) subtree не добавляет новых файлов метадаты как submodules (.gitmodule)
-:
1) нужно познакомиться с новой мердж стратегией.
2) комитить код в репозитории подмодулей на порядок сложнее.
3) Ответсвенность за то, чтобы не мешать изменения в проекте и подмодуле в одних коммитах лежат на плечах разработчиков, а не системы.
Начинается все с того, что мы добавляем отдельный ремоут, который ссылается на репозиторий внешнего проекта, который будет у нас подмодулем. Тут это можно сделать как я понимаю многими вариациями, но главный вопрос, который нам нужно решать, это нужна ли нам история подмодуля в репозитории нашего проекта или нет.
Расмотрим два варианта решения задачи, один с класической книги http://git-scm.com/book/ , второй от https://bitbucket.org, для которого нужно поменьше буков нажимать.
Создадим бранчу только с кодом подмодуля
А следующая комманда создает в нашем проекте подкаталог submodule1-dir/, код которого вяжется на нашу локальную бранчу submodule1-branch, которая подвязана на удаленную указанную бранчу репозитория подмодуля (submodule1-remote/master)
Получим код с удаленки подмодуля
Сейчас код подмодуля есть в локальном репозитории, а нам нужно сделать так чтобы он появился в поддиректории нашего проекта, и чтобы он тоже начал трекаться проектовским репозиторием. Для этого нужен мердж,а стратегия для такого мерджа назівается subtree
На этот раз мы решили, что история подмодуля в нашем проекте нам не интересна, поэтому ключ --squash. (При этом последующие обновления подмодуля будут приносить новые логи его истории в нашу историю).
Теперь мы готовы делать комит в наш бранч этого мерджа с осмысленным мессиджом:
Чтобы увидеть изменения, которые мы сделали в репозитории проекта в подмодуле, мы должны сделать diff между кодом из подпапки и локальным бранчем чистого кода подмодуля, делается это с помощью отдельной комманды:
Если после этой команды проверить логи, мы увидим два новых коммита:
Теперь каждый раз когда нам нужно обновить подмодуль с его репозитория(upstream-а) делаем следующее:
Ну впринципе, чтобы меньше клацать буков в командах, в случае если мы все же довольно часто решили обоновлять подмодуль, лучше ремоут зарегать в себя в локальном репозитории:
Теперь сослемся на зареганый ремоут, а не на урл:
Когда пришло время обновления делаем:
И конечно же, если мы решили законтрибутить в подмодуль, мы можем это сделать.
Но нужно обязательно помнить что все изменения, которые касаются отдельного подмодуля, должны комиться только с изменениями из этого подмодуля, потому что в противном случае, мы не сможем запушить в удаленные репозитории
http://blogs.atlassian.com/2013/05/alternatives-to-git-submodule-git-subtree/
http://git-scm.com/book/ch6-7.html
Первоначально до версии Git 1.7.11 , использовалась subtree merge strategy , после этой версии написали удобную комманду git subtree.
Начнем с преимуществ и недостатков этого подхода по сравнению с git submodule, ну а потом рассмотрим сначало старый подход работы, после - новый, с командой:
+:
1) Управляться с простым воркфлоу просто:)
2) Достаточно старые версии поддерживаются (v1.5.2-)
3) Код подпроектов сразу появляется после clone проекта.
4) subtree не принуждает пользователей проекта учить что-то новое, и они даже не обязаны знать об использовании мердж стратегии сабтри.
5) subtree не добавляет новых файлов метадаты как submodules (.gitmodule)
-:
1) нужно познакомиться с новой мердж стратегией.
2) комитить код в репозитории подмодулей на порядок сложнее.
3) Ответсвенность за то, чтобы не мешать изменения в проекте и подмодуле в одних коммитах лежат на плечах разработчиков, а не системы.
Subtree merge strategy
Начнем с более старого способа, но который будет работать на более широком диапазоне версий Git.Начинается все с того, что мы добавляем отдельный ремоут, который ссылается на репозиторий внешнего проекта, который будет у нас подмодулем. Тут это можно сделать как я понимаю многими вариациями, но главный вопрос, который нам нужно решать, это нужна ли нам история подмодуля в репозитории нашего проекта или нет.
Расмотрим два варианта решения задачи, один с класической книги http://git-scm.com/book/ , второй от https://bitbucket.org, для которого нужно поменьше буков нажимать.
Класический способ
$ git remote add submodule1-remote https://bitbucket.org/some-mirr/submodule1.git $ git fetch submodule1-remoteИли чтобы вводить меньше буков:
$ git remote add -f submodule1-remote https://bitbucket.org/some-mirr/submodule1.git-f - ключ, который означает сделать сразу fetch после дабавления этого ремоута
Создадим бранчу только с кодом подмодуля
$ git checkout -b submodule1-branch submodule1-remote/master
А следующая комманда создает в нашем проекте подкаталог submodule1-dir/, код которого вяжется на нашу локальную бранчу submodule1-branch, которая подвязана на удаленную указанную бранчу репозитория подмодуля (submodule1-remote/master)
$ git read-tree --prefix=submodule1-dir/ -u submodule1-branch
Получим код с удаленки подмодуля
$ git checkout submodule1-branch $ git pull
Сейчас код подмодуля есть в локальном репозитории, а нам нужно сделать так чтобы он появился в поддиректории нашего проекта, и чтобы он тоже начал трекаться проектовским репозиторием. Для этого нужен мердж,а стратегия для такого мерджа назівается subtree
На этот раз мы решили, что история подмодуля в нашем проекте нам не интересна, поэтому ключ --squash. (При этом последующие обновления подмодуля будут приносить новые логи его истории в нашу историю).
$ git checkout master $ git merge --squash -s subtree --no-commit submodule1-branch Squash commit -- not updating HEAD Automatic merge went well; stopped before committing as requested
Теперь мы готовы делать комит в наш бранч этого мерджа с осмысленным мессиджом:
git commit -m"[subtree] adding submodule1"
Чтобы увидеть изменения, которые мы сделали в репозитории проекта в подмодуле, мы должны сделать diff между кодом из подпапки и локальным бранчем чистого кода подмодуля, делается это с помощью отдельной комманды:
$ git diff-tree -p submodule1-branchЕсли нас интересуют новые внешние изменения в разработке подмодуля, мы можем не обновляя локальный бранч, сделать сравнение с удаленкой
$ git diff-tree -p submodule1-remote/master
Способ с отдельной командой для subtree стратегии
Команда эта из последних версий гита, поэтому ее желательно обновить на убунте:
sudo add-apt-repository ppa:git-core/ppa
sudo apt-get update
sudo apt-get install git
При этом она по-умолчанию не включена, ее нужно включить:
sudo chmod +x /usr/share/doc/git/contrib/subtree/git-subtree.sh
sudo ln -s /usr/share/doc/git/contrib/subtree/git-subtree.sh /usr/lib/git-core/git-subtree
А теперь как же ее пользоваться.
Следующая команда создает указанный подкаталог для модуля, делает fetch с удаленки указанного бранча (мастер в данном случае) и этот код, добавив в новосозданный каталог, коммитит нам в репозиторий проекта, после этого мерджит одинокий коммит в поточную бранчу проекта:
sudo add-apt-repository ppa:git-core/ppa
sudo apt-get update
sudo apt-get install git
При этом она по-умолчанию не включена, ее нужно включить:
sudo chmod +x /usr/share/doc/git/contrib/subtree/git-subtree.sh
sudo ln -s /usr/share/doc/git/contrib/subtree/git-subtree.sh /usr/lib/git-core/git-subtree
А теперь как же ее пользоваться.
Следующая команда создает указанный подкаталог для модуля, делает fetch с удаленки указанного бранча (мастер в данном случае) и этот код, добавив в новосозданный каталог, коммитит нам в репозиторий проекта, после этого мерджит одинокий коммит в поточную бранчу проекта:
git subtree add --prefix submodule1-dir https://bitbucket.org/some-mirr/submodule1.git master --squashЧтобы история подмодуля добавилась нужно не писать директиву --squash
Если после этой команды проверить логи, мы увидим два новых коммита:
1bda0bd [3 minutes ago] (HEAD, stree) Merge commit 'ca1f4da9f0b93346bba9a430c889a95f75dc0a83' as 'submodule1-dir' [Name Surname] ca1f4da [3 minutes ago] Squashed 'submodule1-dir' content from commit 02199ea [Name Surname]
Теперь каждый раз когда нам нужно обновить подмодуль с его репозитория(upstream-а) делаем следующее:
$ git subtree pull --prefix submodule1-dir https://bitbucket.org/some-mirr/submodule1.git master --squashКак видно по коммандам мы не завязались на удаленку подмодуля, а делаем обновления по факту, и не впрыскиваем стороннюю историю в свою -- это оправдано в случае большого проекта и опасности частого обновления подмодулей, особенно если не сохраняется совместимость между версиями.
Ну впринципе, чтобы меньше клацать буков в командах, в случае если мы все же довольно часто решили обоновлять подмодуль, лучше ремоут зарегать в себя в локальном репозитории:
$ git remote add -f submodule1-remote https://bitbucket.org/some-mirr/submodule1.git-f - ключ, который означает сделать сразу fetch после дабавления этого ремоута
Теперь сослемся на зареганый ремоут, а не на урл:
$ git subtree add --prefix submodule1-dir submodule1-remote master --squash
Когда пришло время обновления делаем:
$ git fetch submodule1-remote $ git subtree pull --prefix submodule1-dir submodule1-remote master --squash
И конечно же, если мы решили законтрибутить в подмодуль, мы можем это сделать.
Но нужно обязательно помнить что все изменения, которые касаются отдельного подмодуля, должны комиться только с изменениями из этого подмодуля, потому что в противном случае, мы не сможем запушить в удаленные репозитории
git subtree push --prefix=submodule1-dir submodule1-remote master
http://blogs.atlassian.com/2013/05/alternatives-to-git-submodule-git-subtree/
http://git-scm.com/book/ch6-7.html
Комментариев нет:
Отправить комментарий