多个git存储库的最佳实践

bet*_*rio 7 git git-submodules git-subtree git-slave git-repo

我有大约20个不同的存储库.许多是独立的并且编译为库,但是其他一些在它们之间具有依赖性.依赖性解析和分支很复杂.

假设我有一个只聚合所有其他存储库的超级项目.它专门用于运行测试 - 这里没有真正的发展.

/superproject  [master, HEAD]
    /a         [master, HEAD]
    /b         [master, HEAD]
    /c         [master, HEAD]
    /...
Run Code Online (Sandbox Code Playgroud)

现在,为每个(a)开发特定的功能或修复,特别是需要特定版本的项目编译或运行的那些(b v2.0c 3.0)我必须创建一个新的分支:

/superproject  [branch-a, HEAD]  <-- branch for 'a' project
    /a         [master]  <-- new commits here
    /b         [v2.0]
    /c         [v3.0]
Run Code Online (Sandbox Code Playgroud)

因为b,可能需要其他东西,比如a v0.9c v3.1:

/superproject  [branch-b, HEAD]  <-- branch for 'b' project
    /a         [v0.9]   <-- older version than 'a'
    /b         [master] <-- new commits go here
    /c         [v3.1]   <-- newer version than 'a'
Run Code Online (Sandbox Code Playgroud)

使用执行有关功能分支,分支的修复程序,发布分支,等有人建议我(和反对决定)共同git的工作流程时,这变得更加纷繁复杂git-submodules,git-subtree谷歌的git-repo,git-slave等等.

如何管理这样一个复杂项目的持续集成

编辑

真正的问题是如何在不必模拟所有其他依赖项目的情况下运行测试?特别是当所有项目可能使用不同版本时. 在git子模块中提交后触发Jenkins测试

jth*_*ill 6

要并行处理多个分支,请尽可能使用并行克隆。 cd每次要切换时,都比结帐和清理以及检查陈旧的碎屑和重新创建缓存要容易得多。


就记录您的测试环境而言,您所描述的正是子模块在每个细节中的作用。对于这么简单的事情,我建议您完全不使用 submodule 命令来设置自己,并在您感到舒适后告诉它您的设置,并且您的子模块问题列表中的最重要项目是击键次数。

从您问题中的设置开始,以下是您如何设置自己以在子项目中记录干净的构建:

cd $superproject
git init .
git add a b c etc
git commit -m "recording test state for $thistest"
Run Code Online (Sandbox Code Playgroud)

就是这样。您已经提交了一个提交 ID 列表,即每个这些存储库中当前检出的提交的 ID。实际内容在那些 repos 中,而不是这个,但就 git 而言,这是文件和子模块之间的全部区别。该.gitmodules文件有随机注释来帮助克隆人,主要是一个建议的存储库,它应该包含必要的提交,以及命令默认值的随机注释,但它所做的很简单明了。

想在 path 处检查正确的提交foo吗?

(commit=`git rev-parse :foo`; cd foo; git checkout $commit)
Run Code Online (Sandbox Code Playgroud)

rev-parse 从索引中获取 foo 的内容 id,cd 和 checkout 会这样做。

以下是您如何找到所有子模块以及应该检查哪些内容以重新创建暂存的 aka 索引环境:

git ls-files -s | grep ^16
Run Code Online (Sandbox Code Playgroud)

检查子模块的当前索引列表以及实际检查的内容:

echo $(git rev-parse :$submodule; (cd $submodule; git rev-parse HEAD))
Run Code Online (Sandbox Code Playgroud)

你去吧。检查所有子模块中的正确提交?

git ls-files -s | grep ^16 | while read mode commit stage path; do
        (cd "$path"; git checkout $commit)
done
Run Code Online (Sandbox Code Playgroud)

有时您会携带想要应用于每次结帐的本地补丁:

git ls-files -s | grep ^16 | while read mode commit stage path; do
        (cd $path; git rebase $commit)
done
Run Code Online (Sandbox Code Playgroud)

等等。有git submodule这些命令,但它们没有做任何你在上面看不到的事情。其余的都一样,你可以将他们所做的一切转化为像上面那样的近乎单行者。

子模块没有什么神秘之处。


持续集成通常使用大量工具中的任何一个完成,我会将其留给其他人解决。