Проекты в рамках проектов, использующих Git
Как настроить проект Git, содержащий другие проекты?
например. Я работаю над онлайн-картографическим приложением. Мы разработали инструмент GPS вместе с оборудованием в SF. Мы одновременно разработали скрипт Python Geomapping вместе с другой задачей (которая заботится только о геомаппинге). Наши собственные базовые файлы объединяют их и основываются на них для нужного нам приложения.
Каждый из проектов должен существовать сам по себе - люди, которые заинтересованы в GPS, интересуются только GPS - но "родительский" проект, который включает в себя все остальные, должен быть доступен как проект.
Я потратил некоторое время, пытаясь понять подмодули, но они, кажется, имеют слишком большую независимость для того, что нужно.
Также, если возможно, было бы неплохо, если бы каждый из этих проектов содержал один или два перекрывающихся скрипта. Может ли один проект Git включать файл, который не является частью его "корня", так что, когда этот файл обновляется любой из команд, обе могут получить выгоду?
Это выполнимо с Git? С ртутью? Имеет ли значение хост (GitHub, Gitorious)?
У меня есть идея использовать Subversion для "родителя" - игнорировать папки.git и использовать Git для проектов (игнорируя папки.svn) - но это только последнее средство.
редактировать:
Чтобы объяснить, почему я не хочу субмодулей:
- Когда пользователи загружают, почтовый индекс не включает подмодули ( здесь и здесь). То же самое, когда даже соавторы пытаются настроить проект. Это шоу-стоппер.
- Подмодули заморожены - они не могут (легко) подобрать последнюю версию проекта, на которую указывают.
- Другие причины, как указано в фантастических ответах ниже и в этом монологе на NoPugs.
Слияние поддеревьев (представленное мне Полом ниже) не подойдет: трудно обновить источник [поддерева] в рамках проекта, в который он сливается, и этот источник должен находиться за пределами корневой папки проект. Будучи веб-приложением, жизненно важно, чтобы все мои страницы имели внутреннюю ссылку на папку внутри них, а тестирование и обновления выполнялись непосредственно в этой папке. (Надеюсь, что это ясно и полезно для других.)
Все еще изучаю настройку "удаленных веток", но другие идеи все еще приветствуются.
6 ответов
Я не нашел подмодулей, которые были бы особенно полезны в (небольших) проектах, над которыми я работал. После того, как вы их настроите, работа над всем проектом требует добавления дополнительных параметров почти к каждой команде, а синтаксис не совсем регулярный. Я полагаю, что если бы я работал над более крупными проектами с большим количеством подмодулей, я бы счел это более выгодным компромиссом.
Существует две возможности сохранить подпроекты в качестве независимых репозиториев git, которые вы извлекаете из основного (интеграционного) репо:
Использование объединения поддеревьев для переноса ваших внешних проектов в отдельные подкаталоги основного репо, включающие ваши основные файлы. Это облегчает обновление основного проекта из внешних проектов, но усложняет отправку изменений обратно во внешние проекты. Я думаю, что это хороший способ включить зависимости проекта, но он не очень хорошо работает с общими файлами. Еще одно простое объяснение (ссылка исправлена).
Настройте каждый проект как удаленную ветвь в вашем основном репо и объедините каждый из них в свой
master
(интеграция) ветка, которая также содержит ваши основные файлы. Это требует некоторой дисциплины: если вы вносите какие-либо изменения во внешние проекты в своем основном репо, они должны быть внесены в ветку, а затем объединены с мастером; и вы никогда не захотите сливаться с ветками проекта. Это облегчает отправку изменений обратно во внешние проекты и является совершенно приемлемым использованием веток в Git.Ваши общие сценарии могут обрабатываться как другая независимая ветвь в вашем главном каталоге, из которой ваши внешние партнеры могут извлекать и передавать в качестве удаленной ветки.
Если вы попытаетесь запустить SVN & Git в одном и том же каталоге, вам будет очень трудно использовать ветвление в любой системе, потому что SVN выполняет ветвление, копируя каталоги файлов, пока Git отслеживает указатели. Ни одна из систем не будет автоматически видеть ветви, которые вы создаете в другой. Я думаю, что "решение" - это больше проблем, чем оно того стоит.
Я использовал git для соединения своего собственного проекта на github и внешней библиотеки пользовательского интерфейса, которую я хотел использовать. Библиотека размещается в хранилище Subversion на sourceforge.
Я использовал git-submodule и git-svn, и он работал достаточно хорошо. Недостатками были:
Для того, чтобы идти в ногу с хранилищем библиотеки, мне пришлось выполнить новый коммит, чтобы обновить подмодуль git hash "pointer". Это связано с тем, что подмодули git, в отличие от svn: externals, прикрепляются к определенному идентификатору коммита. Это не может быть реальным недостатком, если вы действительно хотите закрепить стабильную версию, я работал с кодом, который был WIP.
Первоначальное использование git-репо с подмодулями требует дополнительного шага с помощью "git submodule init". Это не проблема для вас, но для других, использующих ваш код, им придется запомнить или попросить выполнить этот шаг перед компиляцией / выполнением / тестированием вашего кода.
Если вы используете командную строку, легко испортить ваш репозиторий с помощью git-add. Это потому что вы печатаете
git add subm<tab>
завершить кgit add submodule
, но он автоматически завершаетgit add submodule/
- обратите внимание на косую черту. Если вы выполняете команду с завершающей косой чертой, то она подмывает подмодуль и вместо этого добавляет все содержащиеся в нем файлы. Это смягчается использованием git-gui,git add .
или просто тренируясь, чтобы удалить косую черту (это случалось со мной достаточно раз, когда я тренировал себя, чтобы удалить ее)Подмодули коммитов могут испортить git rebase -i. Я забыл точные детали, но это особенно плохо, если у вас есть "грязный" подмодуль и вы запускаете rebase-интерактив. Обычно с грязным деревом вы не можете перебазировать, но подмодули не проверяются. Наличие нескольких подмодульных коммитов в группе ребаз также вызывает проблемы. Последний хеш подмодуля фиксируется для первого выбора в вашем списке, и это довольно сложно исправить позже. Это можно обойти с помощью более тщательного рабочего процесса (т. Е. Тщательно решить, когда выполнять коммиты подмодуля...), но может быть PITA.
Шаги, чтобы настроить это были чем-то вроде:
- Бежать
git svn clone https://project.svn.sourceforge.net/svnroot/project/project/trunk
- Выдвиньте это как "настоящий" проект git к github
- Теперь в вашем собственном git-хранилище запустите
git submodule init
git submodule add git://github.com/project subproject
- Вытолкни это тоже в свой репо на этот раз.
Вот и все, более или менее. У вас будет новый каталог "подпроект", который в вашем случае будет библиотекой геомапинга.
Каждый раз, когда вам нужно обновить код геомапинга, вы запускаете что-то вроде:
cd subproject
git svn rebase
git svn push # this updates the git mirror of the subproject
cd ..
git add subproject # careful with the trailing slash!
git commit -m "update subproject"
git push # this pushes the commit that updates the subproject
Я не видел много учебников по рабочему процессу подмодуля git, поэтому я надеюсь, что это поможет вам принять решение.
git-submodule может быть тем, что вы ищете:
Из того небольшого, что я прочитал о Externals, похоже, что это порт SVN 'externals' для GIT.
Это решает некоторые проблемы с подмодулями GIT, включая автоматическое обновление до последней версии.
Хотя у меня нет опыта работы с SVN externals или с этим проектом, для некоторых это может оказаться лучшим решением, чем для других.
В качестве альтернативы, следующее программное обеспечение (похоже, его можно использовать с GitHub). Для некоторых это может быть еще один способ снять кожу с кошки: Коса ( страница Softpedia)
Это зависит от того, над каким проектом вы работаете, и какие инструменты, если таковые имеются, должны взаимодействовать с вашим SCM. Например, Rails часто использует Capistrano для развертывания, и Capistrano делает определенные предположения о том, как будет выглядеть ваша структура каталогов относительно корня вашего хранилища. В этом случае, если у вас есть несколько взаимосвязанных приложений rails, вам нужно использовать субмодули. Каждое приложение получает свой собственный репозиторий, а затем у вас есть большой репозиторий, который управляет каждым из независимых репозиториев как подмодулями.
Даже если у вас нет инструментов, позволяющих делать подобные предположения, хороший дизайн хранилища требует, чтобы вы немного разбили вещи, даже если есть хоть малейшая вероятность того, что когда-нибудь вы захотите использовать подраздел большого проекта независимо или повторно использовать какой-то большой кусок кода в каком-то независимом проекте.
Извлечение некоторого подраздела репозитория в качестве отдельного объекта при ведении истории версий сложно в git, и поэтому неплохо планировать заранее.
Что касается вашего конкретного вопроса, честно говоря, я бы назвал это идеальным примером того, где пара подмодулей была бы идеальной. Что касается обмена сценариями, если по какой-то причине это проблема, которая оказывается проблематичной, вы всегда можете использовать символическую ссылку.
Я работаю с этими «внешними» подкомпонентами, делая их достаточно независимыми, следуя указаниям https://github.com/jmnavarrol/simplest-git-subrepos (отказ от ответственности: я его автор).
На самом деле я работаю над портом Python, поэтому я могу добавлять сложные функции в Bash, например, конфигурационный файл подрепо, являющийся YAML, что-то вроде, то есть:
---
# Subrepos' definition
#
# subrepos:
# - path: relative_path
# repo: URL to git service
# [gitref: gitref]
subrepos:
- path: 'projects/simplest-git-subrepos'
repo: 'git@github.com:jmnavarrol/simplest-git-subrepos.git'
gitref: 'v1.0.0'
Это позволяет как «исправить» версии для распространения, так и упростить разработку как для «основных», так и для «связанных» проектов.