в нашей компании у нас огромная база кода (> 100000 файлов), поэтому мы храним ее в нескольких репозиториях git. Итак, у нас есть лес репозиториев и один суперпозиторий, содержащий только ссылки на подмодули.
Идея состоит в том, чтобы иметь суперпозиторий просто в качестве удобного клея и автоматически обновлять его всякий раз, когда разработчик обновляет какой-либо подмодуль.
Я экспериментировал с пост-получение hook и в итоге получил следующую реализацию:
(он включает git-сантехнику, чтобы иметь возможность напрямую изменять голый репозиторий)
#!/bin/bash -e
UPDATED_BRANCHES="^(master|develop)$"
UPDATED_REPOS="^submodules/.+$"
# determine what branch gets modified
read REV_OLD REV_NEW FULL_REF
BRANCH=${FULL_REF##refs/heads/}
if [[ "${BRANCH}" =~ ${UPDATED_BRANCHES} ]] && [[ "${GL_REPO}" =~ ${UPDATED_REPOS} ]];
then
# determine the name of the branch in the super repository
SUPERBRANCH=$FULL_REF
SUBMODULE_NAME=${GL_REPO##submodules/}
# clean the submodule repo related environment
unset $(git rev-parse --local-env-vars)
# move to the super repository
cd $SUPERREPO_DIR
echo "Automaticaly updating the '$SUBMODULE_NAME' reference in the super repository..."
# modify the index - replace the submodule reference hash
git ls-tree $SUPERBRANCH | \
sed "s/\([1-8]*\) commit \([0-9a-f]*\)\t$SUBMODULE_NAME/\1 commit $REV_NEW\t$SUBMODULE_NAME/g" | \
git update-index --index-info
# write the tree containing the modified index
TREE_NEW=$(git write-tree)
COMMIT_OLD=$(git show-ref --hash $SUPERBRANCH)
# write the tree to a new commit and use the current commit as its parent
COMMIT_NEW=$(echo "Auto-update submodule: $SUBMODULE_NAME" | git commit-tree $TREE_NEW -p $COMMIT_OLD)
# update the branch reference
git update-ref $SUPERBRANCH $COMMIT_NEW
# shall we also update the HEAD?
# git symbolic-ref HEAD $SUPERBRANCH
fi
Заранее спасибо.
В реализованной вами реализации есть свои преимущества. Хотя вы пропустили некоторые возможные крайние случаи, такие как проверка неэтапных изменений в других ветвях (вы можете сначала добавить / спрятать). Альтернативой этому является использование системы непрерывной интеграции, такой как Jenkins, для обработки обновлений:
https://wiki.jenkins-ci.org/display/JENKINS/Meet+Jenkins
У этого есть несколько преимуществ перед системой хуков git. Ею можно управлять централизованно (мы столкнулись с проблемами, заставляющими git-hooks работать в разных операционных системах, которые наши инженеры использовали, чем сложнее мы добавили). Доступны и другие функции (множество модулей, добавленных пользователями). Наши сценарии репо теперь связываются с Jenkins для получения статуса репо и могут соответствующим образом обновляться.