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:
Written by Janos Gyerik
Related protips
5 Responses

I recently searched how to do that and I found an answer from the github help: https://help.github.com/articles/splitting-a-subfolder-out-into-a-new-repository

@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!

Oh this is neat, might have to use this soon.
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.
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 https://github.com/firehawkvfx/ansible.git
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 https://github.com/firehawkvfx/ansible.git
fatal: not a git repository: /Users/user/git/firehawk-deploy-dev/firehawk/ansible/../../.git/modules/firehawk/modules/ansible