Convert a git folder to a submodule retrospectively?

Quite often it is the case that you're writing a project of some kind, and after a while it becomes clear that some component of the project is actually useful as a standalone component (a library, perhaps). If you've had that idea from early on, then there's a fair chance that most of that code is in it's own folder.

Is there a way to convert one of a git project's sub directories into a submodule? Ideally this would happen such that all of the code in that directory is removed from the parent project , and the submodule project is added in it's place, with all the appropriate history, and such that all the parent project commits point to the correct submodule commits.


To isolate a subdirectory into its own repository, use filter-branch on a clone of the original repository:

git clone <your_project> <your_submodule>
cd <your_submodule>
git filter-branch --subdirectory-filter 'path/to/your/submodule' --prune-empty -- --all

It's then nothing more than deleting your original directory and adding the submodule to your parent project.

First change dir to folder which will be a submodule. Then:

git init
git remote add origin repourl
git add .
git commit -am'first commit in submodule'
git push -u origin master
cd ..
rm -rf folder wich will be a submodule
git commit -am'deleting folder'
git submodule add repourl folder wich will be a submodule
git commit -am'adding submodule'

I know this is an old thread, but the answers here squash any related commits in other branches.

A simple way to clone and keep all those extra branches and commits:

1 - Make sure you have this git alias

git config --global alias.clone-branches '! git branch -a | sed -n "/\/HEAD /d; /\/master$/d; /remotes/p;" | xargs -L1 git checkout -t'

2 - Clone the remote, pull all branches, change the remote, filter your directory, push

git clone new-repo
cd new-repo
git clone-branches
git remote rm origin
git remote add origin
git remote -v
git filter-branch --subdirectory-filter my_directory/ -- --all
git push --all
git push --tags

It can be done, but it's not simple. If you search for git filter-branch, subdirectory and submodule, there are some decent write-ups on the process. It essentially entails creating two clones of your project, using git filter-branch to remove everything except the one subdirectory in one, and removing only that subdirectory in the other. Then you can establish the second repository as a submodule of the first.

Need Your Help

undefined method 'devise' for User

ruby-on-rails ruby devise

I have been looking to get to grips with devise and its workings and have kind of fallen at the first hurdle. I have looked in a few places but cannot seem to find someone with this error exactly....