Git子模块与Git克隆


18

我正在GitHub上的一个开源项目。

它有一个/ vendor子目录,在其中有几个外部库的副本。项目的原始维护者有时会使用外部库的较新副本来更新此目录。

一位开发商送我的想法拉请求更换该副本git的子模块

我正在考虑这是否是个好主意。

Git子模块的优点:

  • 子模块是为类似情况专门设计的
  • 它消除了意外提交给供应商的可能性,该可能性在下次更新时将被覆盖

Git子模块的缺点:

  • 看起来git子模块将复杂性从维护人员推向了要克隆/拉动项目的人员(克隆开始使用项目后需要执行的其他步骤:“ git submodule init”,“ git submodule update”

您对此有何看法?

还有一件事。这个问题是相当小的库,具有非常有限的外部依赖性。我认为目前任何构建工具都不过分。


4
或者,他们可以执行git clone --recursive然后不必执行子模块命令。没有其他人提到过这个花招。我认识的大多数拥有子模块的人都在README中做广告。
Levi Morrison

Answers:


9

子模块的替代方法是使用git subtree。这带来了好处,git submodule但没有将复杂性推给最终用户。第三方存储库已合并到主项目树中,但是以以下方式存储元数据:

  • 如果进行了任何有趣的更改,请稍后提取第三方存储库
  • 合并来自第三方存储库的新更新(请注意merge,不能覆盖)

对于不够熟练以了解子模块的Git用户,子树方法使获得项目的克隆比其他任何克隆都容易。文档中的简短内容:

子树允许子项目包含在主项目的子目录中,可以选择包括子项目的整个历史记录。

例如,您可以将库的源代码包含在应用程序的子目录中。

子树不要与子模块混淆,子模块用于同一任务。与子模块不同,子树不需要在存储库中存在任何特殊的构造(例如.gitmodule文件或gitlinks),也不会强迫存储库的最终用户做任何特殊的事情或了解子树的工作方式。子树只是一个子目录,可以按照您想要的任何方式与项目一起提交,分支和合并。

我已经使用子模块在工作中建立了一个项目,而在每个人的克隆中保持子模块为最新状态会带来很多麻烦。我最近更改为在各处使用子树,这些问题消失了。

请注意,git-subtree是git/contrib目录的一部分,必须单独安装。


4

使用子模块的一个缺点是Github(以及许多其他服务)上的tarball或zip归档文件不包含子模块的源。也就是说,档案不是独立的。如果存储库很小并且实际上没有构建脚本(例如依赖于JavaScript库的静态HTML站点),则这是一个问题。


3

这是使用子模块的理想场所。它们减少了存储库的大小和复杂性,并使更容易将外部库更新到新版本。

它们并不难弄清楚如何使用,并且在这种情况下相当普遍,因此只需在项目的自述文件中记下您利用了子模块及其功能,人们就应该能够弄清楚出来。第一次遇到带有子模块的存储库时,我在10到15分钟内就将其启动并运行,从此以后就一直没有确定要做什么的问题。


1
作为补充,如果您的应用程序无法初始化,则可能需要进行检查以验证子模块是否已初始化-如果尚未初始化,则提供友好的错误消息。
Jonathan Rich

1
另请参阅Lekensteyn关于缺少子模块文件的zip归档文件的答案。这意味着,如果您公开提供代码,则子模块可能不是最好的方法,但是对于保证可以克隆的私有代码而言,子模块是很好的选择。否则,首选子树。
工程师

3

使用子模块可防止您对代码进行本地更改并在外部存储库上创建依赖项。如果您确定自己永远不想自定义库或进行本地错误修复,并且可以确保当您要克隆新副本时外部服务器将始终可用,那么您就可以使用它们。

简而言之-您只想使用这些库还是将它们视为代码库的一部分?如果它们不是“您的”代码,为什么它们处于版本控制中,而不仅仅是您需要安装的内容?


6
子模块不会阻止您进行本地更改。相反,它们允许您跟踪这些更改并在不同项目中使用库的不同版本(您的调整或库发行版)。
史蒂夫·福洛斯
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.