8

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

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

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

现在,要为每个(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]

对于b,可能还需要其他东西,例如a v0.9and c 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-submodules, git-subtree, google's git-repo,git-slave等。

对于这样一个复杂的项目,我该如何管理持续集成?

编辑

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

4

2 回答 2

6

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


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

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

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

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

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

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

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

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

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

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

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

等等。有git submodule这些命令,但他们没有做任何你在上面看不到的事情。其余的都一样,您可以将他们所做的一切翻译成类似于上面的那些。

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


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

于 2015-07-03T22:50:35.367 回答
3

作为作者,git slave可以在这种情况下工作。如何使用它取决于您是否可以控制 reposa bc; 我的意思是你可以使分支策略在它们之间同步,以便 v2 分支对每个人都意味着同样的事情。如果这是真的,我强烈建议您,git slave因为您基本上可以将其视为一个大型项目。

如果您不能强制执行一个通用的分支和标记策略,那么您将强加一个,这越来越接近 jthill 建议的工作流的轻量级版本git submodules。具体来说,您可以拥有自己的 repo 跟踪a bc并在每个分支中创建一个branch a分支,这将对应于每个从 repo 的正确分支。就像git submodules您必须手动更新每个 repo 一样(在这种情况下合并)。但是,您不需要在超级项目中执行提交的母亲可能的步骤。使用这种技术不是让从属项目在进行自己的开发时共享相同的分支名称的灌篮用例,但它会起作用。

正如 jthill 所说,持续集成与如何处理项目的问题非常相似。

于 2015-07-04T00:23:12.357 回答