我有多个单独的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”,这似乎可以改善这种情况,但是我无法使用真正的存储库来做到这一点。
因此,所需的方案似乎无效。有办法解决吗?
答案 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
当git
将msub
克隆到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