How to make an existing directory within a git repository a git submodule
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Git cannot simply "convert" a normal tracked directory into a submodule with one command. A submodule is a separate Git repository recorded by the parent repository as a commit reference, so the real workflow is to extract that directory into its own repo, remove the old tracked directory from the parent, and add the new repo back as a submodule at the same path.
Why an Existing Folder Is Not Already a Submodule
A regular directory inside a repository is just part of the parent repo's tree. A submodule is different:
- It has its own
.gitdata and commit history - The parent repo stores only a pointer to a specific submodule commit
- Clones of the parent repo do not automatically contain the submodule contents unless initialized
That difference is why you cannot run a command that simply toggles a folder from one state into the other while keeping everything in place.
Preserve the Folder History With git subtree split
If the directory already has meaningful history in the parent repository, the cleanest extraction path is to split that history into its own branch first.
That creates a branch containing only the history of libs/shared. You can then push it into a new standalone repository:
At this point, libs/shared has become a real repository with its own history rather than just a copied folder.
Replace the Old Directory in the Parent Repo
Once the standalone repository exists, remove the tracked directory from the parent repository and commit that change.
Now add the new repository back as a submodule at the same path:
The folder path stays the same, but its meaning changes. Instead of storing all file contents directly, the parent repo now tracks a specific commit from the child repository.
Simpler Option if History Does Not Matter
If you do not need to preserve the folder's old history, the process is shorter:
- Copy the folder contents into a new repository manually.
- Commit and push that repository.
- Remove the original directory from the parent repo.
- Add the new repository as a submodule.
That approach is easier, but you lose the old per-file history tied to the original path inside the parent repository.
Working With the New Submodule
After the conversion, collaborators need to initialize submodules when cloning:
When the submodule changes later, you commit inside the submodule repository first, then commit the updated submodule pointer in the parent repository.
Common Pitfalls
- Trying to add the submodule on top of still-tracked files causes conflicts because Git sees both the old directory and the new submodule path.
- Forgetting to push the standalone repository before adding the submodule leaves collaborators with a broken reference.
- Assuming submodules behave like copied folders leads to confusion. They are commit pointers, not embedded snapshots you edit casually from the parent repo.
- Skipping
git submodule update --init --recursiveafter cloning makes the directory look empty or incomplete.
Summary
- You cannot directly flip a tracked directory into a submodule in place.
- The usual path is extract history into a new repo, remove the old directory, then add the new repo as a submodule.
- Use
git subtree splitwhen you want to preserve the folder's history. - After conversion, remember that the parent repo tracks a submodule commit, not the full folder contents.

