在我们公司,我们有一个庞大的代码库(> 100000个文件),所以我们把它保存在几个git仓库中。 所以我们有一个仓库的森林和一个只包含子模块引用的超级仓库。
这个想法是把超级仓库当成一个便利的粘合剂,并在开发人员更新任何子模块时自动更新。
我已经试验了接收后的钩子,结束了以下实现:
(它涉及到git plumbing,以便能够直接修改裸仓库)
#!/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
提前致谢。
你所做的实现有好处。 虽然你已经省略了一些可能的边界情况,例如检查其他分支中的未分阶段更改(可能需要先添加/存储)。 替代scheme是使用像Jenkins这样的持续集成系统来处理更新:
https://wiki.jenkins-ci.org/display/JENKINS/Meet+Jenkins
这对于git钩子系统有几个好处。 它可以集中控制(我们遇到了一些问题,让我们的工程师使用的git-hook在不同的操作系统上工作,我们增加了更多的复杂性)。 还有更多的function可用(大量的用户贡献模块)。 我们的回购脚本现在联系jenkins回购状态,并可以相应地更新。