I resolved my own question, here is the solution:
git-submodule-split library another_library
Script git-submodule-split
:
#!/bin/bash set -eu if [ $# -eq 0 ] then echo "Usage: $0 submodules-to-split" fi export _tmp=$(mktemp -d) export _libs="$@" for i in $_libs do mkdir -p $_tmp/$i done git filter-branch --commit-filter ' function gitCommit() { git add -A if [ -n "$(git diff --cached --name-only)" ] then git commit -F $_msg fi } >/dev/null # from git-filter-branch git checkout-index -f -u -a || die "Could not checkout the index" # files that $commit removed are now still in the working tree; # remove them, else they would be added again git clean -d -q -f -x _git_dir=$GIT_DIR _git_work_tree=$GIT_WORK_TREE _git_index_file=$GIT_INDEX_FILE unset GIT_DIR unset GIT_WORK_TREE unset GIT_INDEX_FILE _msg=$(tempfile) cat /dev/stdin > $_msg for i in $_libs do if [ -d "$i" ] then unset GIT_DIR unset GIT_WORK_TREE unset GIT_INDEX_FILE cd $i if [ -d ".git" ] then gitCommit else git init >/dev/null gitCommit fi cd .. rsync -a -rtu $i/.git/ $_tmp/$i/.git/ export GIT_DIR=$_git_dir export GIT_WORK_TREE=$_git_work_tree export GIT_INDEX_FILE=$_git_index_file git rm -q -r --cached $i git submodule add ./$i >/dev/null git add $i fi done rm $_msg export GIT_DIR=$_git_dir export GIT_WORK_TREE=$_git_work_tree export GIT_INDEX_FILE=$_git_index_file if [ -f ".gitmodules" ] then git add .gitmodules fi _new_rev=$(git write-tree) shift git commit-tree "$_new_rev" "$@"; ' --tag-name-filter cat -- --all for i in $_libs do if [ -d "$_tmp/$i/.git" ] then rsync -a -i -rtu $_tmp/$i/.git/ $i/.git/ cd $i git reset --hard cd .. fi done rm -r $_tmp git for-each-ref refs/original --format="%(refname)" | while read i; do git update-ref -d $i; done git reflog expire --expire=now --all git gc --aggressive --prune=now