>显然,添加具有子模块的存储库的子树会破坏git submodule init
。下面是重现该问题的脚本:
#!/bin/sh
set -ex
mkdir submod
cd submod
git init
touch foo
git add foo
git commit -asm "This is a submodule"
cd ..
mkdir subtree
cd subtree
git init
git submodule add `realpath ../submod` submod
git commit -asm "This has reference to submodule"
cd ..
mkdir top
cd top
git init
touch bar
git add bar
git commit -asm "Dummy commit so HEAD resolves correctly"
git subtree add --prefix=subtree `realpath ../subtree` master
# This fails!
git submodule init
此脚本正在执行的操作是:
- 创建存储库子模 组
- 创建一个存储库子树,该子树具有对子模组的子模块引用
- 创建具有对子树的子树引用的存储库顶部
经过进一步考虑,问题是什么很清楚:子树机制已将子树的子模块引用添加到树中,但.gitmodules
元数据保留在subtree/.gitmodules
中,而不是顶级.gitmodules
,这意味着git submodule init
失败。如果我们将subtree/.gitmodules
的内容复制到.gitmodules
,相应地调整所有路径,就可以解决问题......
[submodule "submod"]
path = subtree/submod
url = /Users/ezyang/Dev/labs/git-subtree-submod/submod
。但是如果子树有很多子模块,那就有点痛苦了。有没有更好的方法可以做到这一点?
从我阅读文档和源代码可以看出......Git 子树与 Git 子模块完全分开,不会主动管理可能包含在子树项目本身中的任何子模块。
正如您所发现的,.gitmodules
,这对git submodule init
的功能至关重要,需要维护在"主"存储库的根目录中(因为缺乏更好的术语(。
经过进一步考虑,问题出在哪里就很清楚了: 子树机制已将子树的子模块引用添加到 树,但 .gitmodules 元数据保留在子树/.gitmodules 中, 不是顶级 .gitmodules,这意味着 git 子模块 init 失败。如果我们将子树/.gitmodules 的内容复制到 .gitmodules, 相应地调整所有路径,从而解决问题...
我强烈建议不要混合这些功能。