Detach many subdirectories into a new, separate Git repository

Instead of having to deal with a subshell and using ext glob (as kynan suggested), try this much simpler approach:

git filter-branch --index-filter 'git rm --cached -qr --ignore-unmatch -- . && git reset -q $GIT_COMMIT -- apps/AAA libs/XXX' --prune-empty -- --all

As mentioned by void.pointer’s comment, this will remove everything except apps/AAA and libs/XXX from current repository.

Prune empty merge commits

This leaves behind lots of empty merges. These can be removed by another pass as described by raphinesse in his answer:

git filter-branch --prune-empty --parent-filter \
'sed "s/-p //g" | xargs -r git show-branch --independent | sed "s/\</-p /g"'

⚠️ Warning: The above must use GNU version of sed and xargs otherwise it would remove all commits as xargs fails. brew install gnu-sed findutils and then use gsed and gxargs:

git filter-branch --prune-empty --parent-filter \
'gsed "s/-p //g" | gxargs git show-branch --independent | gsed "s/\</-p /g"' 

Leave a Comment