1

我们有一个大型项目,包括以下内容:

  • A:C++ 源代码/库
  • B:使用 SWIG 包装 C++ 库的 Java 和 Python
  • C:用 Java 编写的 GUI,依赖于 Java API/包装。

人们以所有可能的方式使用该项目:

  • 使用 C++ API 的 C++ 项目
  • 使用 Java API 的 Java 项目
  • Python 脚本
  • MATLAB 脚本(使用 Java API)
  • 通过 Java GUI

目前,A、B 和 C 都在一个 Subversion 存储库中。我们正在迁移到 git/GitHub,因此我们有机会进行重组。我们正在考虑将 A、B 和 C 拆分为他们自己的存储库。这给我们提出了几个问题:

  1. 将 Java 和 Python SWIG 包装(即接口 (*.i) 文件)拆分到单独的存储库中是否有意义?
  2. 目前,SWIG 生成的 .java 文件在 GUI 的源代码树中输出,并在 SVN 中进行跟踪。由于我们不想在 git 存储库中跟踪机器生成的文件,那么维护 GUI 对 SWIG 生成的 .java/.jar 文件的依赖关系的最佳方法是什么?考虑一下:如果一个新开发人员想要构建 Java GUI,他们不应该需要从头开始构建 A 和 B;他们应该能够获得 C 的副本,他们可以从中立即构建 GUI。
  3. 版本控制:当一切都在一个存储库中时,A、B 和 C 必须彼此一致。当我们有不同的存储库时,GUI 需要使用已知版本的包装,并且包装需要使用已知版本的 C++ API。管理此问题的最佳方法是什么?

我们对每个问题都进行了深入思考,但想听听社区将如何处理这些问题。也许 git submodule/subtree 是其中一些解决方案的一部分?这些我们都没有使用过,似乎子模块让人有些头疼。有没有人有这两种方法的成功故事?

4

1 回答 1

0

好的,我查看了与您类似的问题(多个交互项目),并尝试了三种可能性subtreesubmodules以及一个包含多个文件夹的普通存储库,其中包含各个部分。如果有更多/更好的解决方案,我不知道。

简而言之,我选择了一个存储库,但这可能不是您的最佳解决方案,这取决于...

  • 这样做的好处submodules是它允许轻松管理,因为每个部分本身就是一个回购。因此,各方只能在他们的 repo 上工作,而其他部分可以从预定义的二进制版本/...(无论你喜欢什么)中添加。您必须添加一个将各个存储库连接在一起的附加存储库。
    这既是优点也是缺点:此 repo 中的每个提交都定义了一个运行配置。理想情况下,您的开发人员必须将每次提交两次,一次用于“工作存储库”(A 到 C),一次用于配置存储库。
    因此,如果您希望您的部分 AC 大部分独立且不经常更改(仅适用于新版本),则此方法可能非常适合。
  • 我不得不承认我subtree个人不喜欢这种方法。对我(个人)来说,语法似乎很笨拙,而且好处不是太大。
    好处是远程修改很容易获取和插入,但您会丢失远程历史记录。因此,您应该避免干扰远程开发。
    这是不利的一面:如果您打算对零件进行修改,则必须始终担心历史记录。您当然可以在 git 远程开发并测试/合并/集成对master分支的更改。这对于主要读取远程存储库是可以的(如果我只在 A 上开发但需要 B 和 C)但不适用于定期修改(在 A 的示例中)。
  • 最后一种可能性是一个简单的仓库,每个部分都有文件夹。好处是不需要直接保持部件同步的管理。但是,您将无法保证每个提交都是正在运行的提交。此外,您的开发人员将不得不手动进行管理。

您会看到选择取决于各个部分 AC 互连的紧密程度。在这里我只能猜测:
如果您处于开发的早期阶段,整个源代码树中的修改很常见,那么一个大型 repo 比拆分版本更易于处理。如果您的接口大部分是恒定的,则拆分允许更小的存储库和更严格的事物分离。
SWIG 代码和 C++ 代码似乎非常接近。因此,将这两者分开似乎不如将 GUI 与其他部分分开(我的猜测)。

对于您的其他问题“如何处理新开发人员/(未)跟踪机器生成的代码?”:
进行/需要多少次提交(仅发布或每个单独的提交)?如果只对版本感兴趣,您可以使用二进制包。如果您打算共享每个提交,则必须提供许多不同的二进制版本。在这里,我建议让他们在几分钟内编译整个树,然后从那里重建只是很短的时间make,不应该花费太长时间。这甚至可以使用钩子自动化。

于 2015-08-31T07:52:02.980 回答