包管理器与Git子模块/子树

Net*_*ite 8 package-managers git-submodules git-subtree

是否有任何理由使用包管理器而不是git子模块/子树,反之亦然?git解决方案似乎比简单的包管理器麻烦得多.

假设git子模块的节省空间的好处并不重要.

更新:有人在这个问题上添加了一个C++标签,但我已经删除了它.这个问题与C++没有特别的关系.欢迎提供比接受的答案更一般的答案.

vas*_*vas 11

“如果技术环境允许打包和正式的依赖管理,你绝对应该走这条路。”

以上来自Mastering Git submodules,这是一篇写得很好且经过深思熟虑的文章,值得成为这个问题和许多类似 Stackoverflow 问题的最佳答案。

让我引用与这个问题相关的部分:

它们是完成这项工作的正确工具吗?

在许多情况下,模块代码在容器代码中的物理存在是强制性的,通常是因为所使用的技术或框架。例如,Wordpress、Magento 等的主题和插件通常实际上只是安装在项目树内的常规位置,这是“安装”它们的唯一方法。

在这种情况下,使用子模块(或子树)可能是正确的解决方案,前提是您确实需要对该代码进行版本控制并与第三方协作(或将其部署在另一台机器上);对于严格本地化、未版本化的情况,符号链接可能就足够了,但这不是这篇文章的内容。

另一方面,如果技术环境允许打包和正式的依赖管理,你绝对应该走这条路:它可以让你更好地拆分代码库,避免一些影响子模块空间的副作用和陷阱,并让你受益于版本控制方案,例如您的依赖项的语义版本控制 (semver)。

  • 不过请注意这篇文章,它有点过时了,并且其中所写的内容并非仍然正确。例如,“git pull”自编写以来就学习了“--recurse-submodules”。 (2认同)

Von*_*onC 6

git解决方案似乎比简单的包管理器麻烦得多。

这不是麻烦

这是关于构建项目的两种不同方式:

  1. 通过二进制依赖关系,使用程序包管理器(NexusC ++的Conan声明您的依赖关系,然后程序包管理器获取它们并在编译期间使用它们。
  2. 通过依赖关系以及Git子模块或子树,您可以在其中存储对其他源代码的引用,将其导入并重新编译所有内容。

第一个是在构建系统时很好的,其中每个部分都有其自己的发布生命周期,并且您希望依赖于预先构建的依赖项。

当依赖项与主程序之间的联系更加紧密时,使用第二种方法。

或者当没有二进制依赖(这是情况下,例如,与围棋它的模块)。

  • 紧密联系是什么意思? (2认同)