说我递归克隆了一个回购。
$ git clone --recursive ssh://server/project/client
Cloning into 'client'...
remote: Counting objects: 191, done
remote: Finding sources: 100% (191/191)
remote: Total 191 (delta 53), reused 159 (delta 53)
Receiving objects: 100% (191/191), 27.59 KiB | 0 bytes/s, done.
Resolving deltas: 100% (53/53), done.
Checking connectivity... done.
Submodule 'gui' (ssh://server/project/client/gui.git) registered for path 'gui'
Cloning into 'gui'...
remote: Counting objects: 3213, done
remote: Finding sources: 100% (3213/3213)
remote: Total 3213 (delta 1272), reused 3107 (delta 1272)
Receiving objects: 100% (3213/3213), 47.88 MiB | 12.05 MiB/s, done.
Resolving deltas: 100% (1272/1272), done.
Checking connectivity... done.
Submodule path 'gui': checked out '7315db8d7a8b36929f7874dc5477359839ec51ce'
现在我想创建一个本地repo的本地克隆(可能是在本地制作和提交更改之后)。
$ git clone --recursive client/ client_copy
Cloning into 'client_copy'...
done.
Submodule 'gui' (/home/deployer/client/gui.git) registered for path 'gui'
fatal: repository '/home/deployer/client/gui.git' does not exist
Clone of '/home/deployer/client/gui.git' into submodule path 'gui' failed
我的.gitmodules
文件如下所示:
[submodule "gui"]
path = gui
url = ../client/gui.git
为什么会失败,我该如何解决这个问题?
答案 0 :(得分:4)
问题在于您的.gitmodules
文件。项目中的子模块url
被定义为来自超级项目存储库的相对路径,但是当克隆子模块时,它们将使用path
位置放置。
换句话说,git正试图从url
位置提取子模块,但在本地计算机上,它们实际上位于path
位置。
要解决此问题,请仅克隆本地超级项目存储库(git clone /path/to/superproject
),然后转到新克隆的.gitsubmodules
并将url
更改为./<whatever-the-path-is>
。例如,您的gui子模块将变为:
[submodule "gui"]
path = gui
url = ./gui
将.gitmodules
中的每个子模块更改为这样,然后运行:
git submodule sync
git submodule update --init --recursive
那应该这样做!
答案 1 :(得分:0)
我需要一个比这更全面的解决方案,因为gitlab克隆东西的方式很奇怪(SRC是顶层源repo文件夹而DST是请求的顶层目标文件夹):
git clone $SRC $DST
MODULES=$(git -C $SRC config --file .gitmodules --name-only --get-regexp url)
for MODULE in ${MODULES}; do
MODULE_PATH=$(git -C $SRC config ${MODULE});
git -C $DST config ${MODULE} ${MODULE_PATH};
done
git -C $DST submodule update --init --recursive;
如果有一种内置的方法可以做到这一点会很棒......
答案 2 :(得分:0)
注意:使用Git 2.12或更低版本时,由于子模块的某些异常路径,此git submodule update --init --recursive
可能会失败。
这在Git 2.13(2017年第二季度)
commit cf9e55f见Brandon Williams (mbrandonw
)(2017年4月7日)
(Junio C Hamano -- gitster
--于2017年4月24日commit 5bceab4合并)
submodule
:防止子模块名称中的反斜杠扩展尝试在名称中添加带反斜杠的子模块&#39;
git submodule
&#39;以一种有趣的方式失败。我们可以看到一些 反斜杠被扩展导致伪造路径:
git -C main submodule add ../sub\\with\\backslash
fatal: repository '/tmp/test/sub\witackslash' does not exist
fatal: clone of '/tmp/test/sub\witackslash' into submodule path
要解决此问题,请将来电转换为&#39;
read
&#39;到&#39;read -r
&#39;在git-submodule.sh
中,以防止子模块名称中的反斜杠扩展。
答案 3 :(得分:0)
如果我们想从本地克隆的子模块中克隆子模块,请参考以下版本。这仅允许一个级别的子模块。
git clone $src $dst
modules=$(git -C $src config --file .gitmodules --name-only --get-regexp url)
for module in $modules; do
module_path=$(git -C $src config --file .gitmodules ${module%.url}.path)
git -C $dst config ${module} $src/$module_path
done
git -C $dst submodule update --init