I am currently importing a cvs project into git.
After importing, i want to rewrite the history to move an existing directory into a seperate submodule.
Suppose
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