我在源代码控制下有一个大型代码库(以前是 subversion,现在是 git)。为了编译代码和运行测试,我使用了一组第 3 方库。这些库可以分为几类L
- 仅限二进制文件
- 第三方来源
- 第 3 方来源 + 本地修改
每个库都有其 {Windows, Linux} X {debug, release} X {32bit, 64bit} 配置。此外,这些库会随着时间的推移而发展,我的项目的不同版本使用这些库的不同版本/构建。
我的问题是存储这些第 3 方的最佳方式是什么?
这是我的一组偏好:
- 保持项目源存储库的大小
- 保持项目源与第 3 方同步,以便我始终可以编译和运行旧版本
- 易于管理
- 跨平台
我尝试并想到了几种解决方案,但都不令人满意:
- 使用版本控制脚本从保存所有版本库的手动管理的 ftp 服务器获取二进制文件。这可行,但需要仔细管理服务器上的目录结构。它很容易出错,因为有人可能会用新版本覆盖其中一个二进制文件。
- SVN 外部 - 当时 SVN 外部无法引用特定标签。今天我在使用 git。
- Git 子模块 - pull 整个外部存储库,这可能是巨大的。或者,它需要为每个库管理一个单独的存储库。子模块指向一个特定的标签,这意味着当我只需要一些时我得到所有的外部,或者我在 git 树中模仿一些奇怪的文件系统。
我很清楚第 3 方源需要存储在供应商分支的 git 中,但二进制文件和 header 是另一回事。
最佳答案
我的问题的合理解决方案是 git-subtree最近 merge 到主线 git 中。它在我的要求和平台限制之间提供了一个公平的平衡。现在我有多个外部存储库(每个存储库都有一个供应商分支和本地更改分支),每个项目存储库都将这些外部存储库的一部分放入子文件夹中。为了让事情井井有条,我维护了一个“bin”和“lib”文件夹,其中包含指向外部子文件夹中相应文件/文件夹的软链接(soft link)。
git-subtree 允许将外部存储库中的子树 merge 到子文件夹中。子文件夹可以与外部存储库来回 merge 。
优点/缺点:
小型存储库 - 存储库并不像我希望的那样小,但它仅包含来自外部存储库的必要部分。为了节省空间,我尽量让外部树木变小。我认为这是一个很好的代价,因为我得到了简单性和健壮性;因为加载和更新项目是一个简单的 git pull,所有项目相关数据都包含在一个存储库中
项目/外部同步 - 由于项目和外部在同一个存储库中进行版本控制,我可以 checkout 我想要的任何分支/标签并期望它正常工作。
简单 - 日常工作很简单。更新外部存储库、创建新存储库或切换到不同版本的外部存储库可能很棘手,并且需要特殊语法。然而,这确实发生得太多了。最好的事情是,可以先向该项目添加一个新的外部,然后才将其拆分(使用 git-subtree)到它自己的存储库中。
跨平台——好吧,就是 git
- 二进制文件——我决定避免持有二进制文件,而是提供 Makefile。我做出这个决定是因为我的一些外部依赖于其他外部,这使得构建一个不经常更改的二进制文件变得非常困难。对于某些外部设备,由于构建时间很长,我会存储二进制文件。
结构:
/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
关于git - 管理代码在源代码控制下使用的第三方源代码和二进制文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11318738/