三个脚本
Alexander Mikhailian
cat .gitmodules |while read ido if [[ $i == \[submodule* ]]; then mpath=$(echo $i | cut -d\" -f2) read i; read i; murl=$(echo $i|cut -d\ -f3) mcommit=`eval "git submodule status ${mpath} |cut -d\ -f2"` mname=$(basename $mpath) echo -e "$name\t$mpath\t$murl\t$mcommit" git submodule deinit $mpath git rm -r --cached $mpath rm -rf $mpath git remote add $mname $murl git fetch $mname git branch _$mname $mcommit git read-tree --prefix=$mpath/ -u _$mnamefidonegit rm .gitmodules
Warning:
下文的两个脚本, 写死了 branch 是 master, 如果主分支不是 master, 须要做相应批改.
Nikita240 - Stack Overflow
️Reference:
我对它进行了批改和改良。当初,新的subtree将指向与旧 submodule 雷同的提交。以前,脚本只是从指标存储库下载最新的提交,这可能会导致兼容性问题。
#!/bin/bash -x# This script will convert all your git submodules into git subtrees.# This script ensures that your new subtrees point to the same commits as the# old submodules did, unlike most other scripts that do this.# THIS SCRIPT MUST BE PLACED OUTSIDE OF YOUR REPOSITORY!!!!!!!!!!# Otherwise, the script will interfere with the git commits.# Save the script in your home directory as `~/subtrees.sh`# `cd` into your repository# Run `~/subtrees.sh`# Enjoy!# extract the list of submodules from .gitmodulecat .gitmodules |while read idoif [[ $i == \[submodule* ]]; then echo converting $i read i # extract the module's prefix mpath=$(echo $i | grep -E "(\S+)$" -o) echo path: $mpath read i # extract the url of the submodule murl=$(echo $i|cut -d\= -f2|xargs) echo url: $murl # extract the module name mname=$(basename $mpath) echo name: $mname # extract the referenced commit mcommit=$(git submodule status $mpath | grep -E "\S+" -o | head -1) echo commit: $mcommit # deinit the module git submodule deinit $mpath # remove the module from git git rm -r --cached $mpath # remove the module from the filesystem rm -rf $mpath # commit the change git commit -m "Removed $mpath submodule at commit $mcommit" # add the remote git remote add -f $mname $murl # add the subtree git subtree add --prefix $mpath $mcommit --squash # commit any left over uncommited changes git commit -a -m "$mname cleaned up" # fetch the files git fetch $murl master echofidonegit rm .gitmodulesgit commit -a -m "Removed .gitmodules"
GaspardP - Stack Overflow
️Reference:
我略微批改了一下,调用
subtree add
而不是read-tree
。它将从.gitmodule
中获取submodule的列表,并提取模块的前缀、名称和网址。而后它删除每个 submodule,并在同一地位增加它们作为subtree。它还将每个submodule的remote增加为remote,这样你就能够通过提供它的名字而不是它的网址来更新subtree了(即git subtree pull -P Foo Foo master --squash
而不是git subtree pull -P Foo https://example.com/foo.git master --squash
)。如果你想把subtree的全副历史导入你的版本库,你能够去掉
--squash
参数。应用--squash
,将只导入subtree的 HEAD 到你的版本库。这可能是大多数人想要的。
#!/bin/bash -x# extract the list of submodules from .gitmodulecat .gitmodules |while read idoif [[ $i == \[submodule* ]]; then echo converting $i # extract the module's prefix mpath=$(echo $i | cut -d\" -f2) # skip two lines read i; read i; # extract the url of the submodule murl=$(echo $i|cut -d\= -f2|xargs) # extract the module name mname=$(basename $mpath) # deinit the module git submodule deinit $mpath # remove the module from git git rm -r --cached $mpath # remove the module from the filesystem rm -rf $mpath # commit the change git commit -m "Removed $mpath submodule" # add the remote git remote add -f $mname $murl # add the subtree git subtree add --prefix $mpath $mname master --squash # fetch the files git fetch $murl masterfidonegit rm .gitmodules
️参考文档
- Convert a git repository from submodules to subtrees | Alexander Mikhailian (mova.org)
- Convert Git submodule to subtree - Stack Overflow