引言

当使用git clone --recursive url 拉取一个配置了子模块的仓库后,会卡住。 同时在使用git clone 拉去https的url时,同样可能会出现一直卡在cloning into reposity...本文提供一个简单的脚本来解决该问题。

前置准备

需要配置好git的相关配置,git user.name,git user.email,ssh。

问题一 使用git clone拉去https协议仓库时卡住

以mxnet的仓库为例,如果使用https协议进行克隆,即通过命令git clone https://github.com/apache/mxnet.git,可能会出现卡在cloning into mxnet...的情况。其实解决方法很简单,当将上面https协议的url改成ssh协议即可,即使用命令git clone git@github.com:apache/mxnet.git这样就不会卡住了,但是原理目前并不是很清楚。 注:即使使用ssh进行仓库的克隆,也是需要非常手段。同时需要配置ssh。

问题二 拉取submodules时卡住

拉取子模块卡住还是因为在原始仓库中的配置中使用了https协议的仓库链接进行拉取,想要解决实际上只需要将仓库中的.gitmodules文件中的所有子模块的url改成ssh协议进行拉取即可。 修改只需要将url中的https:://github.com/替换成git@github.com:,但是手动修改的话比较麻烦,因为修改之后需要考虑拉取的子模块也会依赖其他子模块的情况,此时则还需要修改,因此本人简单写了一个脚本,通过递归来实现。代码如下:

#!/bin/bash

pull_submodule_recursive()

{

if [ -f ".gitmodules" ];then

echo ".gitmodules found"

# backup

cp .gitmodules .gitmodules.bak

while read line

do

# substitude the https with ssh

echo ${line} | sed 's/https:\/\/github.com\//git@github.com:/g' >> .new_gitmodules

done < .gitmodules

mv .new_gitmodules .gitmodules

# pull current submodules

git submodule init

git submodule sync

git submodule update

# get the directories of current submodules

local directories=$(cat .gitmodules | grep path | awk '{print $3}')

for directory in $directories

do

if [ -d $directory ];then

# enter the directory

pushd ${directory} > /dev/null

# pull one submodule and its submodules

pull_submodule_recursive

# return to the last working directory

popd > /dev/null

fi

done

else

echo "current submodule has no submodule, return to last directory..."

fi

return 0

}

pull_submodule_recursive

脚本的使用方法,以拉取mxnet为例:

首先需要将不含有子模块的mxnet拉取下来,注意需要使用ssh进行拉取,即使用命令:git clone git@github.com:apache/mxnet.git;进入到仓库路径,此时会在当前目录下出现mxnet目录,只需要进入该目录,创建一个文件,将上面的代码拷贝到文件中,这里我们把名字设置为get_submodules_recursive;执行上述脚本,等待子模块拉取完成,一定要使用bash来执行,sh不支持pushd和popd命令会出现错误,即通过命令bash get_submodules_recursive进行执行。

执行效果如下图: 能够看到此时遍能够成功拉去子模块了,此时git status会显示有新的修改,因为修改了.gitsubmodules文件,不过这个问题不大,如果觉得不想修改的话,只需要根据提示通过git restore命令恢复即可

代码逻辑解释

代码会查找当前目录下的.gitmodules文件,只有找到改文件才回继续进行执行,当找到改文件后,会将改文件中的子模块的url改成ssh协议,更改完成后进行子模块的拉取,拉取后进入到每个子模块中进行检查子模块是否还有子模块…代码会一直重复上述的逻辑,知道所有的子模块全部拉取完成。 也就是代码执行的逻辑与git clone --recursive一致只是在每次拉去的时候需要修改.gitmodles中的url。

可悲

相关文章

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: