Restore git submodules from .gitmodules
我有一个文件夹,是Git回购。它包含一些文件和.gitmodules文件。现在,当我执行
更新:这是我的.gitmodules文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | [submodule"vim-pathogen"] path = vim-pathogen url = git://github.com/tpope/vim-pathogen.git [submodule"bundle/python-mode"] path = bundle/python-mode url = git://github.com/klen/python-mode.git [submodule"bundle/vim-fugitive"] path = bundle/vim-fugitive url = git://github.com/tpope/vim-fugitive.git [submodule"bundle/ctrlp.vim"] path = bundle/ctrlp.vim url = git://github.com/kien/ctrlp.vim.git [submodule"bundle/vim-tomorrow-theme"] path = bundle/vim-tomorrow-theme url = git://github.com/chriskempson/vim-tomorrow-theme.git |
下面是这个目录的列表:
1 2 3 4 5 6 | drwxr-xr-x 4 evgeniuz 100 4096 июня 29 12:06 . drwx------ 60 evgeniuz 100 4096 июня 29 11:43 .. drwxr-xr-x 2 evgeniuz 100 4096 июня 29 10:03 autoload drwxr-xr-x 7 evgeniuz 100 4096 июня 29 12:13 .git -rw-r--r-- 1 evgeniuz 100 542 июня 29 11:45 .gitmodules -rw-r--r-- 1 evgeniuz 100 243 июня 29 11:18 .vimrc |
所以,当然,这是在顶级水平。Git目录没有更改,只完成
1 | git submodule add <url> <path> |
例如,可以使用以下脚本:
1 2 3 4 5 6 7 8 9 10 11 | #!/bin/sh set -e git config -f .gitmodules --get-regexp '^submodule\..*\.path$' | while read path_key path do url_key=$(echo $path_key | sed 's/\.path/.url/') url=$(git config -f .gitmodules --get"$url_key") git submodule add $url $path done |
这是基于
在@mark longair的答案基础上,我编写了一个bash脚本来自动执行以下过程的步骤2和3:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #!/bin/bash set -e rm -rf .git git init git config -f .gitmodules --get-regexp '^submodule\..*\.path$' > tempfile while read -u 3 path_key path do url_key=$(echo $path_key | sed 's/\.path/.url/') url=$(git config -f .gitmodules --get"$url_key") read -p"Are you sure you want to delete $path and re-initialize as a new submodule?" yn case $yn in [Yy]* ) rm -rf $path; git submodule add $url $path; echo"$path has been initialized";; [Nn]* ) exit;; * ) echo"Please answer yes or no.";; esac done 3<tempfile rm tempfile |
注意:子模块将在其主分支的顶部签出,而不是与样板文件repo相同的提交,因此您需要手动执行该操作。
通过管道将输出从git config传输到read循环会导致输入提示出现问题,因此它将输出到临时文件。我的第一个bash脚本的任何改进都将非常受欢迎:)
感谢Mark,https://stackoverflow.com/a/226724/193494,bash:嵌套的交互式读取循环中也使用了read,[email protected]帮助我找到这个解决方案!
扩展优秀@mark longair的答案,添加有关分支和回购名称的子模块。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | #!/bin/sh set -e git config -f .gitmodules --get-regexp '^submodule\..*\.path$' | while read path_key path do name=$(echo $path_key | sed 's/\submodule\.\(.*\)\.path/\1/') url_key=$(echo $path_key | sed 's/\.path/.url/') branch_key=$(echo $path_key | sed 's/\.path/.branch/') url=$(git config -f .gitmodules --get"$url_key") branch=$(git config -f .gitmodules --get"$branch_key" || echo"master") git submodule add -b $branch --name $name $url $path || continue done |
我也有类似的问题。
当我这样做的时候:
我得到:
我在想,GitIgnore(d)路径可能是原因。
我知道已经有一段时间了,但是我想分享这个版本,它只调用一次
1 2 3 4 5 6 7 8 9 10 | git config -f .gitmodules --get-regexp '^submodule\.' | perl -lane' $conf{$F[0]} = $F[1]}{ @mods = map {s,\.path$,,; $_} grep {/\.path$/} keys(%conf); sub expand{$i = shift; map {$conf{$i . $_}} qw(.path .url .branch)} for $i (@mods){ ($path, $url, $branch) = expand($i); print(qq{rm -rf $path}); print(qq{git submodule add -b $branch $url $path}); } ' |
唯一的副作用是命令的输出,不会执行任何操作,因此您可以在提交之前进行审计。
这可以在控制台上使用简单的复制和粘贴,但是放入shell脚本应该很简单。
实例输出:
1 2 3 4 5 6 7 8 9 10 11 12 | rm -rf third-party/dht git submodule add -b post-0.25-transmission https://github.com/transmission/dht third-party/dht rm -rf third-party/libutp git submodule add -b post-3.3-transmission https://github.com/transmission/libutp third-party/libutp rm -rf third-party/libb64 git submodule add -b post-1.2.1-transmission https://github.com/transmission/libb64 third-party/libb64 rm -rf third-party/libnatpmp git submodule add -b post-20151025-transmission https://github.com/transmission/libnatpmp third-party/libnatpmp rm -rf third-party/miniupnpc git submodule add -b post-2.0.20170509-transmission https://github.com/transmission/miniupnpc third-party/miniupnpc rm -rf third-party/libevent git submodule add -b post-2.0.22-transmission https://github.com/transmission/libevent third-party/libevent |