Search code examples
gitgit-svngit-rebasegit-filter-branch

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. ;)


Solution

  • 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.