extract multiple directories using git-filter-branch

I have a big repository which currently contains multiple projects in top level subfolders, say /a, /b, /c, and /d.

Now I want to split up that repository into two different repositories: one containing /a and /b and the other containing /c and /d.

I am aware of git filter-branch --subdirectory-filter, which is perfect for extracting a single directory, but it seems not to be able to extract multiple directories at once.

I am also aware of git filter-branch --prune-empty --tree-filter, which would allow me to delete everything, but the two wanted directories. This feels not completely right, as I have to manually specify all toplevel directories that might exist.

Is there a better way to extract two directories out of a big repository?

PS: Of course any good solution using something other than git filter-branch is fine. ;)


Use

git filter-branch -f --prune-empty --tree-filter 'bash preserve-only.sh a b' -- --all

where preserve-only.sh is:

IFS=':'
GLOBIGNORE="$*"
rm -rf *

This should remove everything but a and b from all commits of all branches, which should be the same as extracting exactly the given directories.

To complete the actual split you can use a filter like rm -rf a b to get all the changes not extracted in the first run.


Update: While trying to speed things up using --index-filter I came to an even easier solution:

git filter-branch -f --prune-empty --index-filter \
  'git rm --cached -r -q -- . ; git reset -q $GIT_COMMIT -- a b' -- --all

This just removes everything and afterwards restores the given directories afterwards.


After searching around and trying the proposed solutions, it seems like the recommended way of doing is now with git-filter-repo (see here)

git filter-repo --path a --path b