是否为git子模块指定分支?
我已经在我的git存储库中添加了一个git子模块,它运行良好 在我的“父”存储库中,我创建了一个功能分支:myfeature,它需要对子模块进行一些更改。但我不想影响其他使用相同子模块的团队。因此,我在子模块存储库子模块feature上创建了相应的feature分支,并做了一些更改。然后,我在子模块目录中添加/提交更改,然后在父存储库的根目录中添加/提交更改 但是,当我在“父”存储库上切换回主功能时,子模块仍然位于子模块功能分支上。这不是我所期望的。因为现在当我在master上运行测试时,它们失败了,因为我在子模块功能分支上引入了一些中断性的更改 是否无法将子模块的分支锁定到父存储库分支 编辑: 基于: 看起来我可以在是否为git子模块指定分支?,git,Git,我已经在我的git存储库中添加了一个git子模块,它运行良好 在我的“父”存储库中,我创建了一个功能分支:myfeature,它需要对子模块进行一些更改。但我不想影响其他使用相同子模块的团队。因此,我在子模块存储库子模块feature上创建了相应的feature分支,并做了一些更改。然后,我在子模块目录中添加/提交更改,然后在父存储库的根目录中添加/提交更改 但是,当我在“父”存储库上切换回主功能时,子模块仍然位于子模块功能分支上。这不是我所期望的。因为现在当我在master上运行测试时,它们失
.gitmodules
中为子模块存储库指定分支
[submodule "mysubmodule"]
path = mysubmodule
url = https://bla.git
branch = submodule-feature
并在jenkins中添加以下附加git行为:
以及:
在父级myfeature分支上运行构建时,它克隆/签出子模块功能
分支
但在本地工作时,这当然需要一些手动步骤。但从CI的角度来看,这很容易做到。简短的回答大多是“不”。虽然Jenkins有一个复选框,但在这里使用它可能不是一个好主意,不管它是不是,取决于谁控制名称到ID的映射。其他CI系统可能有也可能没有类似的复选框。要了解我的意思,请继续阅读
子模块的原理是超级项目控制其子模块。我认为,这一部分对任何人来说既不令人惊讶也不令人反感。但关键在于超级项目控制每个子模块的方式。这一部分确实让人惊讶,原因相当简单。这是对Git存储库的基本误解
人们认为Git存储库中重要的是分支,或者更准确地说,分支名称,比如master
和develope
。那根本不是真的。在大多数情况下,这些分支实际上与此无关。对人类来说,这些分支名称有着巨大的、压倒一切的作用。对于Git来说,它们提供了一个基本上微不足道的点,其他任何名称都可以很好地涵盖这一点,例如标记名、远程跟踪名、或refs/stash
、或HEAD@{17}
在Git中,提交,而不是分支名称(或标记名称,或任何其他名称),是中心的、基本的东西。提交是Git的。没有提交,Git就没有功能。对于提交,Git很有用。提交实际上是通过它们的散列ID来标识的,散列ID的真实名称是那些丑陋的大字符串,如b5101f929789889c2e536d915698f58d5c5c6b7a
。像易读的名字这样愚蠢的东西,比如master
或develope
,是为弱者准备的,生物制品。。。人类
当然,我们是弱者,就像我们的名字一样。所以我们在存储库中使用它们。但是,当我们有一个存储库,像一个超级项目一样,控制着另一个存储库,比如一个子模块,在这种情况下,没有人参与。所以Git使用提交ID来控制在每个子模块中提取哪个提交哈希ID
这就是惊喜的来源,除非,一旦你了解Git的来源,这一点都不奇怪当您让超级项目选择子模块提交时,超级项目会根据哈希ID选择子模块提交。任何分支名称都是不相关的。哈希ID是精确的,并且总是正确的。分支名称很草率,它们会随着时间的推移故意在提交之间移动。一个提交哈希ID可以有零个或多个直接指向它的分支名称,或者可以通过提交图到达它。2
您在超级项目中所做的每一次提交都会记录子模块预期已签出的确切子模块哈希ID。因此,当您git checkout
在超级项目中进行一些提交时,通常应立即让每个子模块按照超级项目中指定的哈希ID执行各自的git checkout
。3
请记住,每个子模块都是自己的Git存储库,因此它有自己的头、索引和工作树。子模块中的索引将签出的文件记录到子模块的工作树中,每个子模块中的头处于分离头模式,记录当前签出提交的哈希ID。超级项目的Git通过将此哈希ID存储在超级项目的提交中来选择此哈希ID,子模块的Git负责签出此特定提交。在这个过程中,没有任何地方提到分支名称。分支名称无关紧要
1在Git中,名称的功能除了为弱者提供拐杖外,还保护对象不被垃圾收集。如果无法从某个名称访问对象,则该对象容易被收集。由于大多数提交大多链接在一起,所以一个名称往往可以保护存储库中的大多数提交。另见脚注2
2有关可达性的更多信息,请参阅
3默认情况下,这并不是自动发生的。您必须在配置中使用git checkout--recurse子模块
或设置submodule.recurse
。根据您的具体操作,如果您试图更新子模块,那么自动更新子模块要么很方便,要么非常烦人
那么,为什么您可以首先设置分支名称呢?
如您所述,.gitmodules
文件可以
git submodule update --remote