我需要使用git子模块,以便我的父存储库可以跟踪特定分支中发生的更改。我有一个包含测试、测试和生产分支的项目。我的父存储库和子存储库都需要有测试、测试和生产(主)分支。
如果有人能给我一个解决方案,谢谢。
在底层,Git基本上是通过哈希ID工作的,而不是通过分支名称。哈希ID很大,很难看,看起来很随意,人类不可能记住。但对于Git这一计算机程序来说,它们既简单又方便,便于记忆和使用,因此它就是这样做的。
当我们(人类)使用Git时,我们倾向于使用分支名称来掩盖Git真正使用哈希ID的事实。然而,Git中的子模块支持大多拒绝接受这一点。(我稍后会回到这个词,主要是。)每个子模块都由计算机程序控制,所以这里不需要来指定分支名称,Git也不需要麻烦。
请注意,子模块实际上只是另一个Git存储库。唯一让它与众不同的是,一些Git软件不断地进入子模块Git存储库并运行:
git switch --detach <hash>
(或与git checkout
等效),将子模块置于指定提交哈希ID处的分离HEAD模式;控制Git";,我们称之为超级项目,它从存储在您在超级工程中(如果您以通常的方式工作,则在分支上)中的提交中的数据中读取这些哈希ID。您不必查看这些哈希ID,就像您不必在超级项目中查看每个提交的哈希ID一样。
因此:是超级项目Git(您在超级项目存储库中运行的命令)在子模块中执行分离头的操作。在超级项目中运行git switch
,然后在超级项目上运行git submodule update
——或者设置";递归的";模式,只需在超级项目中运行git switch
,它就会为您执行git submodule update
——超级项目会迫使子模块进入分离的HEAD模式。因此,子模块根本不会看到或干扰任何分支名称。超级项目Git在这里使用的哈希ID来自Git称为gitlink的实体。
您应该记住的模型是,想要在子模块中的任何提交都会神奇地出现,可能是凭空出现的。例如,也许你正在使用弗雷德的奇妙奇迹图书馆作为一个子模块。弗雷德制作了一个新版本,你想拿起它,所以你:
cd library/fred
进入子模块git fetch origin
调用Fred的存储库并获得2.0版本git switch --detach v2.0
获取Fred的2.0版本cd ../..
回到您自己的项目- 如果需要/根据需要编辑您的项目,以利用新的神奇功能
- 运行
git add library/fred
为下一次提交更新gitlink - 根据需要在您自己的文件上运行
git add
(您可以在步骤6之前、期间或之后执行此操作);以及 - 运行
git commit
在您的超级项目中进行新的提交
新提交有一个新的gitlink,它在library/fred
中记录2.0版本的新(正确)哈希ID。请注意,在此过程中的任何位置都没有使用分支名称。
当然,有时会使用分支名称:您希望在他的main
上获取Fred的最新提交,而不是标记v2.0
。要执行,请将步骤3更改为:
git switch --detach origin/main
同样,您端上没有使用分支名称,但这次您确实使用了origin/main
:Fred的main
的远程跟踪名称。
这是子模块中存在的分支名称支持的地方
在上面,你必须运行:
(cd library/fred && git fetch origin && git switch --detach origin/main)
或者你想要的任何分支机构名称。通过为子模块设置分支,您可以制作:
git submodule update --remote
为您执行以上命令序列就是这样这里没有魔法。考虑到这几乎没有实际价值,我个人建议你在这里使用你自己的带括号的子命令,哪怕只是为了提醒自己Git中的子模块支持有多差。
如果你的目标是在子模块中完成自己的工作
如果您打算在子模块中执行自己的提交,Git的子模块的工作方式会变得更加痛苦。你最终要做的是将上面的八步序列替换为:
cd library/mine
git checkout develop
... do development work ...
... test, etc., as needed ...
git commit
git push <options>
cd ../..
git add library/mine
git commit # make new gitlink
git push <options>
但这是假设一切都是第一次发生的,这在现实世界中很少是真的。你最终不得不在子模块和超级项目之间来回切换,每隔一段时间你就会发现超级项目Git已经重新分离了你的子模块的HEAD。什么时候会发生这种情况总是可以预测的,然后你去哦,对并修复它,但在实践中,这很痛苦,并导致了哭泣模块的绰号。
子模块执行工作。只要知道你为自己准备了什么样的体验。