git - 多个 git 存储库的最佳实践

标签 git git-submodules git-subtree git-repo git-slave

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

假设我有一个只聚合所有其他存储库的 super 项目。它专门用于运行测试——这里没有真正的开发。

/superproject  [master, HEAD]
    /a         [master, HEAD]
    /b         [master, HEAD]
    /c         [master, HEAD]
    /...

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

/superproject  [branch-a, HEAD]  <-- branch for 'a' project
    /a         [master]  <-- new commits here
    /b         [v2.0]
    /c         [v3.0]

对于 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'

在实现涉及功能分支、修补程序分支、发布分支等的常见 git 工作流时,这变得更加复杂和复杂。有人建议(并建议不要)使用 git-submodulesgit-subtree、google的git-repogit-slave

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

编辑

真正的问题是如何在不必模拟所有其他依赖项目的情况下运行测试?特别是当所有项目可能使用不同的版本时。 Trigger Jenkins tests after commits in git submodules

最佳答案

要并行处理多个分支,请尽可能使用并行克隆。 cd 比 checkout 和 clean 以及 check-for-stale-detritus 和 recreate-caches 每次你想切换要容易得多。


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

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

cd $superproject
git init .
git add a b c etc
git commit -m "recording test state for $thistest"

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

想要检查路径 foo 中的正确提交?

(commit=`git rev-parse :foo`; cd foo; git checkout $commit)

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

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

git ls-files -s | grep ^16

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

echo $(git rev-parse :$submodule; (cd $submodule; git rev-parse HEAD))

好了。检查所有子模块中的正确提交?

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

有时您会携带要应用到每次 checkout 的本地补丁:

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

等等。有用于这些的 git submodule 命令,但它们不会执行您在上面看不到的任何操作。其他人都一样,你可以将他们所做的一切翻译成像上面那样的近乎在线的内容。

子模块没有什么神秘的。


持续集成一般用any of a whole lot of tools来完成,我会把它留给其他人解决。

关于git - 多个 git 存储库的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31211870/

相关文章:

node.js - 运行 node.js git hook 时出现 fatal error

git - 重新创建Android项目后如何 merge Git存储库?

Git 工作流 : commit ! = 操作系统保存

git - 无需克隆即可从远程仓库获取最后一次提交哈希

git - 无法 `git submodule foreach git pull`

git - 将大型 Git 仓库重组为多个新仓库

git - 添加 -A/commit 主/所有子模块的简单方法

git - 使用 git 更新子模块时出现 fatal error "could not read Username"

git - 如何推送到git子树?

git - 管理代码在源代码控制下使用的第三方源代码和二进制文件