问题 Git子模块替代?


我有一些工作树有一些依赖。 AFAIK,git子模块将强制执行以下操作:

  • 使用它(主)在每个工作树的子目录中拥有每个工作树(slave)的副本
  • 主存储库复制来自从属的所有信息

我不介意回购更大,但拥有副本对我来说是非常不可接受的。它会迫使我重新组织所有项目,以便将副本链接起来。此外,编辑错误的文件很容易发生,从而导致混淆。

我有另一个想法:

  • 每个主服务器都存储其所有从服务器的列表。
  • 主站中不需要其他信息。
  • 每次在master中提交时,“快照提交“在奴隶中得到了创造。
  • “snapshot-commit”是工作树当前状态的快照,它忽略了索引的当前状态(我在丢弃一些未经修改的更改之前已经使用了“snapshot-commits”)。
  • “snapshot-commits”收集在一个分支中,该分支的名称来自主人的名字。提交消息包含主提交的哈希。 (恕我直言,这比成千上万的标签充斥更好。)
  • 结账工作照常工作,除非需要递归奴隶。

我能看到的唯一问题如下:

  • 从站中的提交将累积,即使主提交不再存在,也永远不会被删除。
  • 主服务器中的提交不是自包含的,您可以删除主服务器中引用的提交。但我认为不可能偶然发生,所以我可以忍受它。
  • 我无法想象,其他git命令如何支持这一点。但同样,我可以忍受它。

我问的是有人已经实现了它(或者这是一个坏主意)。


8578
2017-07-16 02:00


起源



答案:


我认为这是一个坏主意,因为它很奇怪,它会让你离开许多事情的支持路径。

首先澄清一下:当使用子模块时,'master'(引用)repo不会明显变大。它仅存储存储库引用(可能是URL)和提交ID。但这似乎不是这里的关键点。

在处理这样的问题时,您可以使用三条基本路径:

  1. 将所有内容放在一个存储库中。你有10次说服自己真的需要将事情分开吗?请记住,您可以从一个仓库开始,然后再拆分。还要记住,git merge实际上是有效的,因此开发人员争用并不是一个问题。

  2. 使用一些外部包管理系统。 Git不是,也不是假装是包经理。您正在使用的平台有一个包管理器支持更复杂的依赖情况。 Maven,rubygems,npm,nuget ......有很多。

  3. 在子目录中使用“已安装”子模块。

基本上,在处理您自己的代码时,子模块应该是您的最后选择。它们非常适合处理第三方库,但最终会成为您自己代码的王室痛苦。除此之外,您还提出了一个复杂的解决方案,而且工作起来不会很有趣。


11
2017-08-02 00:20



感谢您的澄清和所有建议。我目前正在做的是使用多个eclipse项目,每个项目都有自己的git存储库。它们之间的依赖关系足够弱以使其工作,而我所追求的将解决唯一剩下的问题:在引用的repo中有时会发生一些变化,需要在引用的变更中进行更改。这使得在这样的边界上复杂化并且我正在寻找的东西可以解决它。我不经常需要它,所以任何可能的问题也很少见。安装的子模块可以做我需要的...... - maaartinus
一直在那里做到这一点,我真的不认为这是值得的努力。拥有一堆子模块是听起来像一个非常好的和优雅的想法(它是)的东西之一,但日常使用只是一个痛苦。我不能鼓励你从一个回购开始。 - Russell Mull
我不同意@Ru​​ssellMull,我想鼓励你不要把所有东西放在一个回购中。将太多东西组合到一个存储库中是一种悲惨的经历,即使在我自己的项目中,我是唯一一个在其上工作的项目。子模块对于这种事情并不是很好,但它们比在一个git仓库中将不相关的项目混合在一起要好得多。 - James Moore


答案:


我认为这是一个坏主意,因为它很奇怪,它会让你离开许多事情的支持路径。

首先澄清一下:当使用子模块时,'master'(引用)repo不会明显变大。它仅存储存储库引用(可能是URL)和提交ID。但这似乎不是这里的关键点。

在处理这样的问题时,您可以使用三条基本路径:

  1. 将所有内容放在一个存储库中。你有10次说服自己真的需要将事情分开吗?请记住,您可以从一个仓库开始,然后再拆分。还要记住,git merge实际上是有效的,因此开发人员争用并不是一个问题。

  2. 使用一些外部包管理系统。 Git不是,也不是假装是包经理。您正在使用的平台有一个包管理器支持更复杂的依赖情况。 Maven,rubygems,npm,nuget ......有很多。

  3. 在子目录中使用“已安装”子模块。

基本上,在处理您自己的代码时,子模块应该是您的最后选择。它们非常适合处理第三方库,但最终会成为您自己代码的王室痛苦。除此之外,您还提出了一个复杂的解决方案,而且工作起来不会很有趣。


11
2017-08-02 00:20



感谢您的澄清和所有建议。我目前正在做的是使用多个eclipse项目,每个项目都有自己的git存储库。它们之间的依赖关系足够弱以使其工作,而我所追求的将解决唯一剩下的问题:在引用的repo中有时会发生一些变化,需要在引用的变更中进行更改。这使得在这样的边界上复杂化并且我正在寻找的东西可以解决它。我不经常需要它,所以任何可能的问题也很少见。安装的子模块可以做我需要的...... - maaartinus
一直在那里做到这一点,我真的不认为这是值得的努力。拥有一堆子模块是听起来像一个非常好的和优雅的想法(它是)的东西之一,但日常使用只是一个痛苦。我不能鼓励你从一个回购开始。 - Russell Mull
我不同意@Ru​​ssellMull,我想鼓励你不要把所有东西放在一个回购中。将太多东西组合到一个存储库中是一种悲惨的经历,即使在我自己的项目中,我是唯一一个在其上工作的项目。子模块对于这种事情并不是很好,但它们比在一个git仓库中将不相关的项目混合在一起要好得多。 - James Moore


我不确定我是否关注您,因为父回购(您的“主”)仅存储对子模块的紧密SHA1的引用(在父回购中检出的子回购)。
父回购的大小根本不受影响。

子树合并策略 (通过git子树更好地管理)会增加父repo的大小,但是(子树合并)不是你所说的。

子模块的另一种替代方案是 git-slave(gits),这有点像你想要实现。


2
2017-07-18 07:42



你的意思是,我错了我的句子“主存储库复制了奴隶的所有信息”?这很可能,但是,我主要担心的是每个主树中是否存在每个从属树的副本(或者我错了吗?)。 - maaartinus
@maaartinus:有一个物理副本(因为它检查了一定的差异),但所有父repo保持是对检出的提交的引用。请参阅此处的“子模块的真实性质”: stackoverflow.com/questions/1979167/git-submodule-update/... - VonC
@maaartinus:然而,每个父级仓库都会检查子模块,这意味着在任何给定时间都会存在所述子模块的几个副本。 - VonC