Отслеживание стороннего кода с помощью Git
Я не могу представить, какие различные решения я нашел и изучил
для отслеживания внешнего кода. Не говоря уже о том, как применять их к
мой прецедент...
Вы, ребята, так любезны пролить свет на это и помочь мне с
мой конкретный вариант использования? Каким будет наилучшее решение для
следующая, конкретная проблема? (Я не собираюсь обобщать мои
проблема, поскольку я могу ошибаться в предположениях о материалах, особенно
так как я так новичок в этом...)
Я создаю сайт в Django (веб-фреймворк на Python). Теперь,
есть много сторонних плагинов, доступных для использования с Django
(Django называет их "приложениями" ), которые вы можете добавить в свой проект. Некоторые из
эти приложения могут потребовать немного модификации, чтобы работать, как я
хочу их. Но если вы начнете вносить изменения в сторонний код, вы
ввести проблему обновления этого кода при появлении более новых версий
И в то же время сохраняя ваши локальные модификации.
Итак, способ, которым я мог бы это сделать в Subversion, - использовать ветки поставщика.
Мой макет хранилища будет выглядеть следующим образом:
/trunk
...
/apps
/blog-app
...
/tags
...
/branches
...
/vendor
/django-apps
/blog-app
/1.2
/1.3
/current
/other-app
/3.2
/current
В этом случае /trunk/apps/blog -app было бы svn copy'd одного из
теги в /vendor/django -apps/blog-app. Скажем, что это был v1.2. А также
что я теперь хочу обновить мою версию в trunk до v1.3. Как вы можете
см., я уже обновил /vendor/django -apps/blog-app/current
(используя svn_load_dirs) и 'tagged' (svn copy) это как
/vendor/django -apps/blog-app/1.3.
Теперь я могу обновить /trunk/apps/blog -app с помощью svn merge'ing изменений
между /vendor/django -apps/blog-app/1.2 и
/vendor/django -apps/blog-app/1.3 on/trunk/apps/blog-app. Это будет
сохраните мои локальные изменения.
(для людей, неизвестных этому процессу, это описано в
Справочник по Subversion:
http://svnbook.red-bean.com/en/1.5/svn.advanced.vendorbr.html)
Теперь я хочу сделать весь этот процесс в Git. Как я могу это сделать?
Позвольте мне повторить итерацию требований:
- Я должен уметь размещать внешний код в произвольной позиции в дереве
- Я должен иметь возможность изменять внешний код и сохранять (фиксировать) эти
изменения в моих репозиториях Git
- Я должен быть в состоянии легко обновить внешний код, если новый
версия будет выпущена, сохраняя мои изменения.
Экстра (для бонусных очков;-)):
- Предпочтительно, я хочу сделать это без чего-то вроде svn_load_dirs. я
подумайте, что должно быть возможно отслеживать приложения и их обновления
прямо из своего репозитория (большинство сторонних приложений Django хранятся в
Subversion). Предоставление мне дополнительного преимущества для возможности просмотра
отдельные сообщения совершать сообщения между релизами. И фиксация слияния
конфликтов легче, так как я могу иметь дело с большим количеством мелких коммитов
вместо одного искусственного коммита, созданного svn_load_dirs.
Я думаю, что можно было бы сделать это с помощью svn: externals в Subversion, но у меня есть
никогда не работал с этим раньше...
Решение, в котором может использоваться комбинация обоих методов,
еще более предпочтительным, поскольку могут быть разработчики приложений, которые не
использовать источник управления или не публиковать свои репозиции.
(Значение как svn_load_dirs-like поведения, так и отслеживания прямо из
Репозиция субверсии (или другая Git))
Я думаю, что мне придется либо использовать поддеревья, подмодули, переадресацию, ветки,... или их комбинацию, но, если я знаю, какой из них или как это сделать: S
Я с нетерпением жду ваших ответов! Пожалуйста, будьте максимально подробными
когда я отвечаю, так как мне уже было трудно понять другие
примеры, найденные в Интернете.
Заранее спасибо
Ответы
Ответ 1
Здесь есть две отдельные проблемы:
- Как вы поддерживаете локальные вилки удаленных проектов и
- Как сохранить копию удаленных проектов в своем собственном дереве?
Проблема 1 довольно проста сама по себе. Просто сделайте что-нибудь вроде:
git clone git://example.com/foo.git
cd foo
git remote add upstream git://example.com/foo.git
git remote rm origin
git remote add origin ssh://.../my-forked-foo.git
git push origin
Затем вы можете нормально работать с вашим разветвленным хранилищем. Когда вы хотите объединиться в восходящих изменениях, запустите:
git pull upstream master
Что касается проблемы 2, одним из вариантов является использование подмодулей. Для этого, cd в ваш основной проект и запустите:
git submodule add ssh://.../my-forked-foo.git local/path/for/foo
Если я использую подмодули git, что мне нужно знать?
Вы можете найти подмодули git, чтобы быть немного сложными время от времени. Вот некоторые вещи, которые следует иметь в виду:
- Всегда завершайте подмодуль перед выполнением родительского элемента.
- Всегда подталкивайте подмодуль, прежде чем нажимать родителя.
- Убедитесь, что подмодуль HEAD указывает на ветвь, прежде чем совершать ее. (Если вы являетесь пользователем bash, я рекомендую использовать git -completion, чтобы поместить текущее имя ветки в ваше приглашение.)
- Всегда запускайте 'git обновление подмодуля' после переключения ветвей или вытягивания изменений.
В определенной степени вы можете работать (4), используя псевдоним, созданный одним из моих сотрудников:
git config --global alias.pull-recursive '!git pull && git submodule update --init'
... и затем запустить:
git pull-recursive
Если git подмодули настолько сложны, каковы преимущества?
- Вы можете проверить основной проект, не проверяя подмодули. Это полезно, когда подмодули огромны, и вам не нужны они на определенных платформах.
- Если вы испытали пользователей git, у вас есть возможность иметь несколько вилок вашего подмодуля и связать их с разными вилками вашего основного проекта.
- Когда-нибудь кто-то может исправить git подмодули, чтобы работать более изящно. Самые глубокие части реализации подмодуля на самом деле неплохие; это только инструменты верхнего уровня, которые сломаны.
Подмодули git не для меня. Что дальше?
Если вы не хотите использовать подмодули git, вы можете посмотреть в git merge subtry strategy. Это сохраняет все в одном хранилище.
Что делать, если восходящий репозиторий использует Subversion?
Это довольно просто, если вы знаете, как использовать git svn:
git svn clone -s https://example.com/foo
cd foo
git remote add origin ssh://.../my-forked-foo.git
git push origin
Затем настройте локальную ветвь отслеживания в git.
git push origin master:local-fork
git checkout -b local-fork origin/local-fork
Затем, чтобы слить из восходящего потока, запустите:
git svn fetch
git merge trunk
(Я не тестировал этот код, но он более-менее-то, как мы поддерживаем один подмодуль с восходящим SVN-репозиторием.)
Не используйте git svn rebase, потому что это очень затруднит использование подмодуля git в родительском проекте без потери данных. Просто обработайте ветки Subversion в виде зеркал только для чтения вверх по течению и явно сходите с них.
Если вам нужно получить доступ к репозиторию Subversion вверх по потоку на другом компьютере, попробуйте:
git svn init -s https://example.com/foo
git svn fetch
Затем вы можете слить изменения с восходящего потока, как и раньше.
Ответ 2
Я немного оглянулся и наткнулся на Braid. Это инструмент, который автоматизирует ветки поставщиков в Git. Он может использовать репозитории Git или SVN.
Просканировав исходный код, я обнаружил, что он использует стратегию поддерева. И, похоже, это очень просто! Кроме того, он, похоже, выполняет все мои требования!
Прежде чем я перейду к нему и использую его: есть ли у кого-нибудь какие-либо навыки работы с Braid? Я хотел бы узнать о возможных минусах, если они есть. Кроме того, если вы не использовали Braid, но имеете некоторый опыт в Git, что вы думаете об этом, на первый взгляд?
Ответ 3
Я использую подмодули git для отслеживания многоразовых приложений в моих проектах Django, но в конечном итоге это бесполезно.
Это бесполезно для развертывания, потому что вы не можете получить чистый архив всего дерева (с подмодулями) с помощью архива git. Есть некоторые трюки, но ничего идеального.
Кроме того, mecanism обновления подмодуля не так хорош для работы с ветвями подмодулей.
Возможно, вам придется взглянуть на virtualenv и pip, потому что у них были некоторые усовершенствования для работы с внешними репозиториями.
pip: http://pip.openplans.org/
и работает с pip/virtualenv: http://www.b-list.org/weblog/2008/dec/15/pip/
Ответ 4
Я думаю, что мой ответ на другие вопросы дает точно хорошее решение проблемы, описанной здесь, не вдаваясь в ад подмодулей (которые я пробовал, но даже не приближаюсь к svn: externals я был использован к)
Тем не менее, посмотрите на этот ответ:
Вы управляете версией недействительных приложений или всего проекта или обоих?
Прежде чем удалять мой ответ еще раз, я не знал, что не могу копировать свой собственный ответ на другой вопрос, даже если я убежден, что это полезно в качестве ответа. Извините, но попробуйте этот ответ, это действительно приятное решение.
Поэтому я надеюсь, что мне позволено ссылаться на мой собственный anser на другой вопрос.