克隆带有嵌套子模块的存储库不起作用

时间:2019-06-28 21:49:39

标签: git git-submodules

我有多个单独的git repos,其中没有子模块。任务是组装这些存储库的层次结构树,并使用它在用户之间共享。这对于'subtree'或'subrepo'方案来说是微不足道的,但似乎不适用于'submodules'。尝试子模块的原因是nfs系统上的git性能缓慢。就我而言,结帐需要2个小时以上

我正在尝试创建一个包含子模块的共享存储库。到目前为止,第一次克隆尝试失败。这是测试用例:

 mkdir m1 ; cd m1 ; git init ; date > a.txt ; git add --all ; git commit -m added ; cd -
 mkdir m2 ; cd m2 ; git init ; date > b.txt ; git add --all ; git commit -m added ; cd -
 mkdir m3 ; cd m3 ; git init ; date > c.txt ; git add --all ; git commit -m added ; cd -
 mkdir msub; cd msub; git init; date > d.txt; git add --all; git commit -m added;
 git submodule add `realpath ../m1` m1
 cd m1
 git submodule add `realpath ../../m2` m2
 git submodule add `realpath ../../m3` m3
 git commit -m 'added submodules'
 cd ..
 git commit -m 'added a submodule'
 cd ..
 git clone --recursive msub msub1

结果是,它使用单个顶级子模块(m1)创建了msub1。

在其他情况下,在克隆第一个子模块后,我得到了类似的致命错误。

fatal: git upload-pack: not our ref 89434ad65c1e697bfa311cd0260dfe1997985e65
fatal: remote error: upload-pack: not our ref 89434ad65c1e697bfa311cd0260dfe1997985e65
Fetched in submodule path 'soc', but it did not contain 89434ad65c1e697bfa311cd0260dfe1997985e65. Direct fetching of that commit failed.

我尝试将子模块直接添加到“ m1”,这似乎可以改善这种情况,但是我无法使用真正的存储库来做到这一点。

因此,所需的方案似乎无效。有办法解决吗?

2 个答案:

答案 0 :(得分:1)

“不是我们的引用”响应通常意味着您的服务器配置为通过ID限制直接获取对象,并且没有合适的引用允许获取该对象。

Git提供了三个选项来控制是否可以获取任意对象ID:一个选项允许获取Git可以访问的任何任意对象,一个选项允许从引用中获取任何可访问的对象,另一个选项则允许获取可访问的对象。隐藏参考。大多数服务器提供商选择禁用其中一个或多个,这通常意味着只有在非隐藏引用(即分支或标签)指向对象ID时,您才能请求该对象ID。

“不是我们的引用”消息表示您正在尝试通过对象ID获取对象,该对象ID用于子模块,但是由于上述原因,服务器不允许使用该对象。如果您使用Bitbucket Server的ref缓存,这也可能意味着该服务器已缓存过时的数据。在这种情况下,如果需要处理,应该禁用引用缓存。

您可以做几件事。如果需要签出任意修订的功能,则可以创建一个指向该修订的分支。或者,如果您的子模块不需要特定的修订,而只需要分支的最新版本,则可以设置submodule.<name>.branch选项(请参见man gitmodules),然后您将始终签出最新的分支。如果您使用的是自托管服务器,则可以将uploadpack.allowAnySHA1InWant设置为true。最后,您可以手动获取子模块(可能使用git submodule foreach),该子模块通常具有您想要的修订版本。

答案 1 :(得分:1)

git submodule add `realpath ../m1` m1
cd m1
git submodule add `realpath ../../m2` m2
git submodule add `realpath ../../m3` m3

您在这里修改了m1的本地克隆副本,但没有将更改推回原始m1

git commit -m 'added submodules'
cd ..
git commit -m 'added a submodule'

您忘记在子模块中添加更改。

cd ..
git clone --recursive msub msub1

gitmsub克隆到msub1时,它将尝试从其原始目录而不是从m1克隆msub/m1。仅仅是因为在顶层.gitmodules中有通往原始m1的路径。而且原始的m1没有子模块。

要修复整个工作流程,您需要:

  • git add在提交之前更改了m1
  • cd m1 && git push origin master(嗯,push到非裸仓库是行不通的,所以cd是原始版本,而pull则相反)。

因此整个固定脚本为:

#! /bin/sh
set -e

mkdir m1 ; cd m1 ; git init ; date > a.txt ; git add --all ; git commit -m added ; cd -
mkdir m2 ; cd m2 ; git init ; date > b.txt ; git add --all ; git commit -m added ; cd -
mkdir m3 ; cd m3 ; git init ; date > c.txt ; git add --all ; git commit -m added ; cd -
mkdir msub; cd msub; git init; date > d.txt; git add --all; git commit -m added;
git submodule add `realpath ../m1` m1
cd m1
git submodule add `realpath ../../m2` m2
git submodule add `realpath ../../m3` m3
git commit -m 'added submodules'
cd ../../m1
git pull ../msub/m1 master
cd ../msub
git add m1
git commit -m 'added a submodule'
cd ..
git clone --recursive msub msub1