This question is based on Detach subdirectory into separate Git repository
Instead of detaching a single subdirectory, I want to detach a couple. For example, my current directory tree looks like this:
/apps
/AAA
/BBB
/CCC
/libs
/XXX
/YYY
/ZZZ
And I would like this instead:
/apps
/AAA
/libs
/XXX
The --subdirectory-filter
argument to git filter-branch
won't work because it gets rid of everything except for the given directory the first time it's run. I thought using the --index-filter
argument for all unwanted files would work (albeit tedious), but if I try running it more than once, I get the following message:
Cannot create a new backup.
A previous backup already exists in refs/original/
Force overwriting the backup with -f
Any ideas? TIA
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.
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"'