How To: Merge a Git submodule into its main repository

Alex Puschinsky
Feb 27, 2019 · 4 min read

Git submodules seem like a good idea at first glance. They allow you to partition your project into several smaller repositories, while keeping a well defined relationship between the main git repository and its submodules.

In practice, at least for us, they have proven to be clunky and hard to work with.

If you just want to merge a single submodule back into your main repository, or if you want to go full blown Monorepo then this is the guide for you.

The naive solution

The simplest solution for this task is to just copy the files from the submodule into the main repository and commit everything in a one big commit. This will work just fine, but you will lose your submodule’s git history. If you’re reading this you probably value the history and won’t accept this compromise. Lets remove this option from the table.

Our goals

  • Have all the code of a submodule appear in the main repository
  • Have the code in whichever directory or sub directory we desire
  • Not lose git history at all

Example project

Lets examine a simple web app. It has an src directory with controllers, routers and views. The models directory is a git submodule. Our goal is to place the models directory into the src directory in the main repository.

main repository git history:

models repository git history:

Stages of execution:

To achieve our goal we will follow the following steps:

  1. Restructure the submodule’s file tree to fit our needs.
  2. Remove the submodule from the main repository.
  3. Merge the submodule master branch into the main repository.

1. Restructure the submodule file tree

Before we can merge the submodule we need to do some directory restructuring. Why? Lets look at the file structure in the models repository:

Our end goal requires the files to be under ./src/models. We need to create the ./src/models directory and move all the tracked files in there.

In the models directory:

  • mkdir -p src/models
  • git ls-tree master --name-only | xargs -I{} git mv {} src/models
  • git commit -m 'Move all files into src/models directory'
  • git push

2. Removing the submodule

Next we need to remove the submodule from the main repository. The submodule is referenced in several locations, so removing it cleanly requires several steps:

1.1 Edit .gitmodules

Git submodules metadata is stored in the .gitmodules file:

  • remove the submodule from that file.
  • git add .gitmodules

1.2 Edit .git/config

.git/config has a similar entry, edit that file as well.

1.3 Remove the submodule from git tracking

git rm --cached models

1.4 Cleanup the .git/modules directory

rm -rf .git/modules/models

1.5 Commit the changes

git commit -m 'Remove models submodule'

1.6 Delete the submodule directory:

The models directory is now untracked, we can delete it.
rm -rf models

3. Merging the submodule

All the pieces are in place. The final step is to merge the models repository into the main repository.

In the main repository run the commands:

  • git remote add models-origin
  • git fetch models-origin
  • git merge --allow-unrelated-histories models-origin/master
  • git remote remove models-origin

Success! Our git history now looks like this:

Lets make this official:

git push origin master

Other team members

Team members will receive the updated repository structure on git pull, If you’ve moved the submodule into a location other than its original — make sure to delete the old, now untracked submodule directory.

WalkMe Engineering

Creative Engineers helping organizations become the best…

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store