将大型git仓库拆分

5
我们有一个非常庞大的C++代码仓库,大小为80GB,包含近20万个文件,其中包含多个组件。
这些库(归档文件)是多个组件共用的,耦合度很高。
由于以上原因,Git操作和编译构建某个特定组件都需要很长时间。
请给出如何将这个单一仓库分成多个仓库的建议。

3
对于西方读者,1 lakh 等同于 100,000。 - PaulProgrammer
2
这真的是80GB的源代码吗?还是你提交了构建对象或其他二进制资源? - Useless
1
可能是将大型Git存储库拆分为多个较小的存储库的重复问题。 - dkinzer
我已经编辑了我的回答,提到了 git-lts。 - VonC
2个回答

4
首先,20万个源文件很可能不会占用超过80GB的空间(除非每个文件代表着400KB的源码!)
更新于2015年:git-lts实际上可以管理这种规模的数据量。请参阅“在Git存储库中高效存储二进制文件”。

原始答案(2013年)

这意味着:

  • 需要将任何生成的二进制文件从git仓库中排除
  • 需要存储任何大型二进制文件(可以在类似于Nexus的 构件存储库或其他存储空间中,例如使用git-annex

其次,只有当我们谈论一个巨大的repo时,git操作才会变慢。
git用于管理多个小型repos(甚至是git Linux内核repo也远远不如您提到的大小和文件数量)

因此你需要:

  • 将庞大的git存储库分割成:

    • 功能组件 (一个组件是一组表示程序主要功能块的文件: GUI、调度器、启动器以及实现程序主要功能块的任何东西)
    • 技术组件 (所有这些通用技术库,被多个其他组件重复使用,提供不可见于最终用户、只由开发人员使用的功能)
  • 通过使用二进制依赖项来加速编译过程,特别是在进行单元或小型集成测试时: 而不是获取所有源代码并重新编译全部内容,您可以针对每个项目设置,让它们使用其他项目生成的二进制文件/exes以便于特定项目的编译和运行。
    这取决于你的库与其他组件的紧密耦合程度。


OP user2463892 在评论中添加了:

我听说过 GIT 子模块,它可以帮助我们将大型代码库分割成多个部分。
我对此不熟悉,有人能帮我理解以下几个问题吗?

1) GIT 子模块是如何工作的?它会将庞大的代码划分为多个仓库吗?这样我们就可以解决 GIT 缓慢的问题了吗?

子模块是在另一个仓库内声明的 git 仓库(该仓库成为“父”仓库)。

父仓库对子模块仓库有一个固定的已知引用,作为一个特殊条目,这意味着:
当你克隆一个父仓库时,默认情况下你不会克隆其中声明的所有子模块 在你的情况下,这可能很有趣,因为你不需要克隆所有的源代码才能进行增量编译。
此外,多个仓库意味着更小的仓库,使用像checkoutlogdiffstatus等命令更快。
假设我们使用这些子模块将主仓库分成多个仓库... 这样是否可以解决我们所面临的问题(仓库之间的依赖关系)?
例如:假设我们将主要核心仓库分为 Super RepoA RepoB RepoC 等... 然后是否可以编译所有这些仓库?

RepoA 可以访问其他仓库(SuperRepoBRepoC等)中的库吗? 互相依赖关系仍然会存在,但您可以:
- 仅在需要进行的步骤中检出所需的仓库 - 将编译后的库存储在这些仓库之外,以便 repoBrepoC 使用。 目标是从仅源代码的依赖关系切换到(生成的)二进制依赖关系,其中 repoB 可以根据由 repoA 编译步骤生成的二进制文件进行编译。

感谢您的快速回复... 是的,我们有200,000个源文件(包括.cpp、.h、.lib_def、.exe_def、.tst_def、.sdl、.oml等...)。正如您所提到的,我们尝试使用以下步骤拆分组件: - user2463892
  1. 预编译当前存储库中的所有库
  2. 将与功能组件相关的代码移动并在编译/构建这些功能组件期间使用预编译的库
  3. 从这些组件生成预构建以在公共代码中使用。
- user2463892
但是,使用这种机制我们遇到了一些问题...由于我们的代码库紧密耦合或具有双向依赖关系(例如,主要仓库库在分裂的仓库中使用,而这些分裂的仓库的库在主要仓库中使用)。因此,在我们的回归测试阶段,每当公共代码发生变化时- - user2463892
假设我们将主核心存储库分成Super、RepoA、RepoB、RepoC等,那么是否可以将所有这些存储库一起编译?RepoA能否访问其他存储库(Super、RepoB、RepoC等)中的库,反之亦然? - user2463892
@user2463892 我已经编辑了答案来解决你提出的一个问题。我建议不要在这里使用子树。 - VonC
显示剩余2条评论

1
您可以使用以下命令在Github中为文件夹创建存储库。
git filter-branch --prune-empty --subdirectory-filter foldername master

这里假设您已经确定了要提取哪些组件,并在创建存储库后解决了构建过程的问题。
参考:

3
命令中没有反斜杠。Stackoverflow不允许我自己进行编辑。 - enigmaticPhysicist

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接