How to split a git repository

erikpischel profile image Erik Pischel Originally published at on-sw-integration.epischel.de on ・1 min read

Say your git repo consists of a subdirectory “app” and a subdirectory “database” (or “frontend” and “backend” or “team-a” and “team-b”) and you realize each directories content should be in its own repository. Here is how to split the repo.

To create a repo that consists of the content of the “database” dir and its history, execute

git filter-branch --prune-empty --tag-name-filter cat --subdirectory-filter database -- --all

and then push it to a new remote:

git remote rename origin old-origin
git remote add origin <new-remote>
git push -u origin --all
git push -u origin --tags

This is what Gitlab states on a newly created project page. However in

git push -u origin --all

“-all” should be replaced with “–mirror” because “-all” pushes all local branches only so you would need to checkout all branches you want to keep. “–mirror” pushes remote branches, too.

In the same fashion apply “filter-branches” to the “app” directory.

How does it work? "git filter-branches" rewrites git revision history of the mentioned branches by applying filters:

  • The mentioned branches states "--all" so filters are applied to all branches of the repo (you need "--" before "--all" because otherwise "--all" would get interpreted as a revision)
  • "--subdirectory-filter" means "only look at the history which touches this directory" and also make that directory the root of the repo.
  • "--prune-empty" removes any empty commits that may get created
  • Git itself recommends using "--tag-name-filter cat" when not stated, it simply updates tags (apparently "--all" does not include tags).

Posted on by:

erikpischel profile

Erik Pischel


Professional programming since 2000, mostly Enterprise Java backed web apps.


markdown guide

I like the general idea that you've got here, but I'd like to see you (or someone) break down that long command to help people understand what's actually going on.


Hi Corey, I have updated the post to explain how it works. Hope this helps.


That's awesome. Thank you for taking the extra time to explain it.