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

时间:2012-07-03 20:32:01

标签: git git-submodules git-subtree

我在源代码控制下有一个很大的代码库(是subversion,现在是git)。为了编译代码并运行测试,我使用了一组第三方库。这些库可以分为几个类别

  • 仅限二进制文件
  • 第三方来源
  • 第三方来源+本地修改

每个库都有{Windows,Linux} X {debug,release} X {32bit,64bit}配置。此外,这些库随着时间的推移而发展,我的项目的不同版本使用这些库的不同版本/版本。

我的问题是存储这些第三方的最佳方式是什么?

以下是我的偏好设置:

  1. 保持项目源存储库的大小
  2. 让项目源与第三方保持同步,这样我就可以随时编译并运行旧版本
  3. 易于管理
  4. 跨平台
  5. 我试过并考虑了几种解决方案,但都不令人满意:

    1. 使用版本化脚本从手动管理的ftp服务器获取二进制文件,该服务器包含所有版本的库。这可行,但需要仔细管理服务器上的目录结构。这很容易出错,因为有人可能会用新版本覆盖其中一个二进制文件。
    2. SVN外部 - 当时SVN外部无法引用特定标签。今天我正在使用git。
    3. Git子模块 - 拉动整个外部存储库,这可能是巨大的。或者,它需要为每个库管理一个单独的存储库。子模块指向一个特定的标签,这意味着要么我得到所有的外部,当我只需要一些时,或者我在git树中模仿一些奇怪的文件系统。
    4. 我很清楚,第三方来源需要存储在供应商分支中的git中,但二进制文件和标题是不同的故事。

3 个答案:

答案 0 :(得分:13)

我的问题的公平解决方案是git-subtree,它最近被合并到主线git中。它在我的要求和平台限制之间提供了公平的平衡。现在我有多个外部存储库(每个存储库都有一个供应商分支以及本地更改分支),每个项目存储库都将这些外部部分存储到子文件夹中。为了保持井井有条,我保持了一个“垃圾箱”。和' lib'包含指向外部子文件夹中相应文件/文件夹的软链接的文件夹。

git-subtree允许将外部存储库中的子树合并到子文件夹中。子文件夹可以与外部存储库来回合并。

优点/缺点:

  1. 小型存储库 - 存储库不像我希望的那么小,但它只包含来自外部存储库的必要部分。为了节省空间,我尝试保持外部树木小。我认为这是一个很好的代价,作为回报,我得到简单和稳健;因为加载和更新项目是一个简单的git pull,所有与项目相关的数据都包含在一个存储库中

  2. 项目/外部同步 - 由于项目和外部版本在同一个存储库中版本化,我可以签出我想要的任何分支/标记,并期望它能够正常工作。

  3. 简单 - 日常工作是直截了当的。更新外部存储库,创建新存储库或切换到不同版本的外部存储库可能很棘手,需要特殊的语法。然而,这确实发生了太多。最好的事情是,可以先为此项目添加一个新的外部,然后再将它(使用git-subtree)拆分到自己的存储库中。

  4. 跨平台 - 嗯,它的git

  5. 二进制文件 - 我决定避免使用二进制文件并提供Makefile。我做出这个决定是因为我的一些外部因素依赖于其他外部因素,因此很难构建一个不会经常变化的二进制文件。对于某些外部因素,由于构建时间很长,我会存储二进制文件。
  6. 结构:

    /root
       /External
          /External1 (git-subtree from git@git.domain.com:External1 v1.0)
          /External2 (git-subtree from git@git.domain.com:External2 v0.7)
       /lib
          /libExternal1.a -> ../External/External1/libExternal1.a
          /libExternal2.a -> ../External/External1/libExternal2.a
       /include
          /External1 -> ../External/External1/include
          /External2 -> ../External/External2/include
    

答案 1 :(得分:0)

我们选择了您的选项3的变体。在我看来,选项1等同于选项3,但是您需要更多的实施/测试工作,因此更有可能出错。

最终,如果您希望能够完全重新创建构建,则需要将您的外部(包括二进制文件)与代码本身一起版本化并在本地托管。 git子模块可以很好地为你做这件事。

答案 2 :(得分:0)

对于第三方来源,我认为子模块正是您正在寻找的。如果您不希望在每个克隆中都需要整个上游历史记录,请使用您自己的上游仓库前端,包含仅具有必要历史记录的手工分支。查看git commit-tree以了解如何制作这些内容,这很容易。提交ID与权威上游不匹配,但树ID将是。

对于二进制文件,git附件似乎是最常推荐的存储内容的方式,这种内容不适合git的源代码区分。我自己没有使用它,但设计看起来已经准备好用于生产,它还支持多个独立的`存储库,看起来尽可能方便。

这不是交钥匙,所以它并不能真正满足你的第三个,但它会完成其余部分,你需要的是直接使用基本工具。