Replace a Dir with a Submodule
Did part of your project take on its own identity? Would you like to promote it to its own project, but still keep the larger project in tact using Git submodules?
I can show you how.
tl;dr
- Clone the project
- Filter down to the dir
- Replace in main project
1. Setup the Scenario
I’m going to using a Git helper called glitter to generate commits.
Create the Project
This is our “big” project with 10 nonsense commits.
Create Another
This will be our “sub-project” we will kick out into a submodule.
Add Remote
Now let’s create a remote on Github and push our big project.
2. Ready
Now we’re ready to kick bananarama/
out into its own project. To do this we
will:
- Clone the current project
- Rewrite history to scope to this dir
- Create a new repo for it
- Remove the dir from the main project
- Replace it with our new repo (submodule)
Clone It
Clone the existing project into a new one for just bananarama/
.
Pare Down History
Now we rewrite the history to only stuff that has to do with bananarama/
.
Afterward, you can see that we only have the commits/files related to that
directory (aka our new standalone project).
git filter-branch --prune-empty --subdirectory-filter bananarama/ master
Push to Repo
All this remote repo stuff is not really necessary, as Git could just work from the local disk. It’s a bit more realistic, though.
Create a new repo for our standalone project. Now change our remote to use this and push our filtered project up.
git remote set-url origin git@github.com:reergymerej/blog-bananarama.git
3. Replace It
At this point, our bananarama
project has been born! To
carry on with the birth analogy, we will go back to the mother, scrape out the
uterus, and replace it with a sub-module clone of the standalone bananarama.
Remove the Dir
Going back to the main project, we remove bananarama/
.
Add the Submodule
Add a submodule for our new project, renaming it to bananarama
(instead of
blog-bananarama
).
git submodule add git@github.com:reergymerej/blog-bananarama.git bananarama
Bada Bing
That’s it. Now bananarama/
is a standalone project and we’re using it as a
submodule.
Gotchas
If you try to add the submodule before deleting the dir…
git submodule add git@github.com:reergymerej/blog-bananarama.git bananarama
'bananarama' already exists in the index
No, I mean really remove it…
Until you completely get rid of it, it’s still “in the index.”