Last Updated: October 24, 2020
· janosgyerik

Splitting a project sub-directory to a new Git repo

Recently I realized that a sub-directory in a Git project
would be better as an independent project.
Luckily this is such a common need,
Git has a nice command to make this easy called subtree split.
It creates a new branch in the project,
with only the commits that involved the specified sub-directory.

Let's say you have a project with a sub-directory called plugins/media and you want that in an independent repository:

git subtree split -P plugins/media -b media

This will put all commits related to plugins/media in a new branch named media. You can confirm the result with git log media.

Next, create the target repository, for example on GitHub,
or locally:

git init --bare /tmp/proj-media.git

Create a remote for the repository,
add a remote for it,
and push the media branch to the remote with the name `master:

git remote add proj-media /tmp/proj-media.git
git push proj-media media:master

Note that the original repository is unchanged:
the plugins/media directory still exists, untouched.
Most probably you want to replace the directory with the new project as a submodule:

git rm -r plugins/media
git submodule add url_to_repo plugins/media
git commit -m 'replaced plugins/media with a submodule'

For more on submodules, see this chapter in the Pro Git book:

5 Responses
Add your response

I recently searched how to do that and I found an answer from the github help:

over 1 year ago ·

@gluchet that method is roughly equivalent, but it rewrites the current branch. My method is safer. I also added more tips: the exact steps to replace the directory with a submodule, and pushing to a remote. I also explain in more detail what's going on. But thanks, it's interesting to know other methods too!

over 1 year ago ·

Oh this is neat, might have to use this soon.

over 1 year ago ·

How can we achieve same task using only Subtree(Not submodule)? Currently I am working on android project where I have created base project in one repository. I want to use one of directory (package) from this project as a core for other projects in different repository. I want to create subtree of this package to avoid copy-pasting but don't know how as java uses package structure for projects.

over 1 year ago ·

Thanks for sharing this possible approach. In my case I ran into trouble on the last step and I'm not sure how to fix my repo now. Upon adding the submodule I got an error: " not a git repository". so I tried to remove the created subfodler and try again, but it still didn't work.

Thanks if you could take a moment to help me explore how to fix it.

user@MacBookPro13 firehawk % git submodule add
fatal: not a git repository: /Users/user/git/firehawk-deploy-dev/firehawk/ansible/../../.git/modules/firehawk/modules/ansible
user@MacBookPro13 firehawk % cat ansible/.git
gitdir: ../../.git/modules/firehawk/modules/ansible
user@MacBookPro13 firehawk % git rm -r ansible
fatal: pathspec 'ansible' did not match any files
user@MacBookPro13 firehawk % rm -r ansible
user@MacBookPro13 firehawk % git submodule add
fatal: not a git repository: /Users/user/git/firehawk-deploy-dev/firehawk/ansible/../../.git/modules/firehawk/modules/ansible

over 1 year ago ·