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

Create Another

This will be our “sub-project” we will kick out into a submodule.

Create Subdir

Add Remote

Now let’s create a remote on Github and push our big project.

Create Repo

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/.

Cloned

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

Filter

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

Set Remote

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/.

Remove Dir

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

Add Submodule

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…

Gotcha

Until you completely get rid of it, it’s still “in the index.”