Git Submodule对其远程存储库的引用错误

时间:2017-05-25 07:44:49

标签: git git-submodules

我的主存储库中有两个子模块,两个子模块都链接到另外两个远程存储库。

  • 当我进入第一个子模块时,我收到一条消息“HEAD脱离 xxxxxxxx” - 这很好,导致远程存储库和子模块具有相同的ID(32位)。 / LI>
  • 当我进入第二个子模块时,我收到一条消息“HEAD脱离来自 yyyyyyyy” - 这是罚款,导致远程存储库和子模块执行具有相同的ID(32位数)。因此,第二个子模块的ID与它所链接的存储库的ID不同。

我想我以某种方式设法将我的第二个子模块放在其他分支或类似的东西上 长话短说,我甚至不能克隆主要代表(git clone --recursive-submodules)因为第二个子模块有一个错误的ID并且无法链接到它的远程代表。
我收到了“error: no ref to the remote rep”。

有人可以帮助我吗? 如何更改子模块的ID?
或者我是否需要在主分支上取回第二个子模块?

2 个答案:

答案 0 :(得分:2)

  

如何更改子模块的ID?

在您的情况下,您无法克隆子模块库,因为其 gitlink ,(special entry in the index of the parent repo)引用了推送的SHA1到所述子模块的远程仓库。

由于您没有子模块文件夹内容(无法检出),您不能简单地从所述子模块添加,推送和提交。

为了完成克隆,最好将关联的gitlink SHA1更改为其先前版本:

git checkout $(git log -1 --format=format:%H yoursubmodule) -- yoursubmodule

yoursubmodule替换为代表您的子模块的文件夹的名称,而不是斜杠(因为它是索引中的条目,而不是文件夹)

然后 git submodule update --init应足以初始化该子模块内容。

最后,请参阅" Git submodules: Specify a branch/tag",并将您的子模块关联到分支:

git config -f .gitmodules submodule.<path>.branch <branch>

这样,下次git submodule update --remote足以将子模块更新为该分支的最新远程SHA1。

答案 1 :(得分:0)

TL; DR:我认为,你所提到的是我在下面提到你未推送子模块提交的情况。所以现在当超级项目从超级项目克隆的子模块中获取一个特定的提交时,它(超级项目Git)找不到它(子模块中的所需提交)。

背景

子模块很痛苦,因为每个子模块本身 Git存储库这一事实与每个“超级项目”(控制子模块)坚持< / em>它知道 提交子模块必须使用。

当所有子模块都是其他人维护的外部库时,这一切都可以正常工作。您编写了一些需要库A,B和C的代码。您可以使用A中的“commit 1234567”,B中的“commit 8888888”和“commit fedcba9”来测试它。 C,它一切正常......所以你判断这个版本的代码总是永远使用这三个子模块中的那三个提交。

您只需通过在超级项目中进行提交即可。每次提交记录都是 提交子模块必须

然后,每当您签出超级项目时,都会告诉您的超级项目Git插入每个子存储库并分离其HEAD。这是为什么你看到“脱离”或“脱离”。此时“at”或“from”部分完全无关:不注意它!当您在这些库时,这是为了您的信息,并且因为您实际上正在处理超级项目,您的超级项目Git假定您正在处理它们

但是有一个问题:如果你希望在他们身上工作怎么办?你的超级项目Git尖叫着你,不不不,你可能不会碰他们!我控制了它们! :-)好吧,它不是相当那么糟糕,但是......它很糟糕。

要在存储库中工作,您通常希望在分支上。所以你必须通过检查一些特定的分支进入子模块并撤消你的超级项目Git所做的事情。现在,您可以正常方式处理子模块。

但这会让你的超级项目Git感到不安。而且,在你将所有内容重新排列之前,你无法真正测试它。您必须输入所有子模块,将它们拉回“branch-y”模式,在其中工作,也许单独测试它们,甚至可以进行提交。现在你可以回到你的超级项目......但你还不能在那里提交,因为他们仍然记得旧的分离的HEAD哈希!

让所有内容全部重新排列的唯一方法是实际在子模块中进行提交。现在每个子模块都有一个 new 哈希ID,当你在那里提交时,每个子模块的Git都被分配了。您现在可以爬回到超级项目并告诉 Git:“我已准备好提交,但在此之前,这是您的新哈希ID。”你可以通过git add再次执行每个子模块,这使你的超级项目Git去读取子模块哈希并将它们放入你的超级项目的索引中。 现在你可以在超级项目中git commit,永久地,永久地,记录新提交,使用每个子模块的新哈希。

请注意,如果您现在推送超级项目,其他所有人都有问题:您在子模块中进行的新提交位于您的子模块存储库中,但这些提交包含尚未被推回到他们可能去的任何地方。获取新超级项目提交的任何人都会收到“子模块A应使用提交feedcab”的提交,但在推送之前,他们无法获取提交feedcab也是。因此,您必须首先推送所有子模块,然后才推送超级项目。

这一切都有效,但请注意这个过程是多么脆弱和脆弱。 Git的子模块随着时间的推移变得越来越好,因为你现在可以实际告诉超级项目控制Git(递归地)下降到每个子模块Git并将放在分支(其分支名称记录在超级项目中) )。这解决了第一个问题。

如果您不是那个控制子模块的远程存储库的人,那么您会得到一组不同的问题。 git submodule update命令增加了大量额外选项,以便尝试适应这些情况。 git submodule foreach命令允许您在每个子模块中运行任何(例如您自己的脚本),这可以让您完全控制,但代价是让您完成控制。但子模块的情况仍然相当混乱,许多组织试图避免它们(我愿意,也会这样做)。