Высокосвязные подмодули w20
У меня есть проект, который нужно разделить на два репозитория: набор общих моделей и симуляцию на основе этих моделей с дополнительным кодом. В конечном счете, может быть несколько симуляций с использованием одного и того же набора моделей, поэтому наличие их в отдельном хранилище является определенным требованием. Очевидным решением является наличие общих моделей в качестве подмодуля моделирования.
К сожалению, два репозитория будут очень сильно связаны. Люди будут очень часто добавлять что-то к своим общим моделям, а затем сразу использовать его в симуляции. Я предполагаю, что это вызовет много головных болей в процессе интеграции репозитория моделирования. Чтобы объединить изменения со многими разработчиками в симуляции, интегратору придется выполнять параллельные слияния в подмодуле общих моделей. С другой стороны, это также делает необходимым использование подмодулей - симуляция действительно должна знать, какую версию общих моделей она должна использовать.
Проект обрабатывается значительным количеством людей. У большинства разработчиков есть только очень поверхностное знание git: они добавляют файлы, фиксируют и извлекают из источника много, и, надеюсь, имеют dev и стабильную ветвь. Интегратор, естественно, узнал немного больше, но что-то, связанное с подмодулями, наверняка будет для него новым. Добавленный бонус: я собираюсь взять месяц отпуска, так что я не смогу выпустить огонь. Результатом является то, что существует множество стимулов для того, чтобы рабочий процесс сильно затруднялся, и чтобы свести к минимуму различия между людьми предыдущих рабочих процессов.
Итак, мои вопросы: буду ли я сожалеть о том, что мы будем использовать подмодули для этого? (Есть ли лучшая идея?) Какие ошибки я могу ожидать от людей, поэтому я могу заранее предупредить их? Есть ли хорошие стратегии рабочего процесса, которые следует иметь в виду?
Изменить: я просто натолкнулся на git slave, что также может стоить взглянуть в этом контексте. Пока не может дать хорошую оценку возможностей/ограничений, выходящих за рамки его веб-сайта.
Ответы
Ответ 1
Подмодуль - хороший выбор для того, чтобы удостовериться в точном пересмотре того или иного компонента.
Как я подробно рассказал в истинном характере подмодулей", вы все равно можете обновить любой из подмодулей при условии, что вы сначала их перенесите (а затем перейдите к родительскому репо и выполните также )
Однако для плотно связанных модулей я постараюсь избежать:
"Я предполагаю, что это вызовет много головных болей в процессе интеграции репозитория моделирования".
Я не вижу эффективного централизованного процесса интеграции: он должен только записывать новые ускоренные эволюции.
Чтобы это произошло, любой пользователь, желающий нажать что-либо, должен сначала вытащить и переустановить свои изменения поверх всех новых изменений, которые уже были перенесены туда.
Разработчик более склонен решать любые конфликты и/или спрашивать у своих коллег о происхождении некоторых изменений, с которыми ему приходится иметь дело во время перезагрузки.
Это (pull, rebase, push) не всегда возможно из-за:
- "расширенный" (менее базовый) Git задействованные операции (и рабочий процесс не точно совпадает с текущим)
- работа (с учетом эволюции от других участников)
- (может быть предпочтительнее настроить дополнительную среду, чтобы сделать эту переадресацию, которая снова "не является базовой"
Но это все равно будет направлением, которое я попробую.
(... но, возможно, не только до одного месяца отпуска;)
Опять же, кто берет весь месяц отпуска?! Никогда не слышал об этом понятии раньше)
Ответ 2
Несколько заметок для всех, кто происходит на этом!
Самая большая ошибка, которую собираются сделать новички, заключается в том, что она совершает с отсоединенным HEAD в подмодуле после обновления подмодуля. Я попытаюсь противостоять этому с сильными предупреждениями от крючков.
Следующим по величине, вероятно, будет неспособность обновить подмодуль после выполнения проверки, которая требует этого. Опять же, крючки могут проверить это и предупредить.
Что касается процесса разработки, эта настройка делает гораздо более важным иметь хорошую тестовую инфраструктуру в подмодуле, поэтому, если возможно, вы можете работать в ней, не выполняя работу в родительском объекте, и полностью избегайте этой проблемы.
Я попытаюсь опубликовать образец кода с помощью крючков, которые я использую, и последую через месяц с (надеюсь, не слишком много) истинными историями ужасов.
Edit:
Вот первые черновики крючков. Имейте в виду, что это спешка, и я легко пойду!
В родительском репо:
Для пост-слияния и последующей проверки мы предупреждаем пользователя, если подмодуль не синхронизирован. (post-merge включается, в частности, для быстрого слияния, вытягивания из источника). Также обратите внимание, что они захотят проверить ветку, хотя подзапрос подзапроса субмодуля также сделает это при запуске обновления подмодуля. Чем больше напоминаний, тем веселее.
#!/bin/bash
if git submodule status | grep '^+' > /dev/null; then
echo "WARNING: common model submodule now out of sync. You probably want to run" 1>&2
echo " git submodule update, then make sure to check out an appropriate branch" 1>&2
echo " in the submodule." 1>&2
fi
Для пост-фиксации, если есть изменения в подмодулях, мы предупреждаем пользователя, что они, возможно, забыли включить их в их фиксацию. В этом очень сложном случае это очень хорошее предположение. Вряд ли пользователь будет модифицировать моделирование и общие модели отдельно.
#!/bin/bash
if git submodule status | grep '^+' > /dev/null; then
echo "WARNING: common model submodule has changes. If the commit you just made depends" 1>&2
echo " on those changes, you must run git add on the submodule, and then run" 1>&2
echo " git commit --amend to fix your commit." 1>&2
fi
И в подмодуле, крюк после проверки, чтобы предупредить об отключенной HEAD:
#!/bin/bash
get_ppid() {
ps --no-headers -o ppid $1
}
# Check to see if this checkout is part of a submodule update
# git submodule calls git checkout, which calls this script, so we need to
# check the grandparent process.
if ps --no-headers -o command $(get_ppid $(get_ppid $$)) | grep 'submodule update' &> /dev/null; then
if ! git symbolic-ref HEAD &> /dev/null; then
echo "WARNING: common model submodule entering detached HEAD state. If you don't know" 1>&2
echo " what this means, and you just ran 'git submodule update', you probably" 1>&2
echo " want to check out an appropriate branch in the submodule repository." 1>&2
echo
# escape the asterisk from SO syntax highlighting (it sees C comments)
branches=($(git for-each-ref --format='%(objectname) %(refname:short)' refs/heads/\* | grep ^$(git rev-parse HEAD) | cut -d\ -f2))
case ${#branches} in
0 )
;;
1 )
echo "Branch '${branches[0]}' is at HEAD"
;;
* )
echo "The following branches are at HEAD: ${branches[@]}"
;;
esac
fi
echo
fi
Я также добавляю крюк pre-commit, чтобы просто прервать фиксации, сделанные с отсоединенным HEAD (если только это не будет rebase). Я очень напуган тем, что классический "все мои коммиты исчезли" в панике. Вы всегда можете обойти его с помощью --no-verify
, если знаете, что делаете.