Merging Multiple Git Repositories into a Monorepo Without Losing History

In the world of software development, there are times when you might need to consolidate multiple Git repositories into a single monolithic repository, commonly known as a “monorepo”. This can be due to various reasons such as easier codebase management, simplified dependency tracking, or just a change in the architectural decision. One of the challenges developers face during this transition is preserving the commit history of each individual repository.

In this blog post, we’ll walk you through a step-by-step guide on how to merge multiple Git repositories into a single monorepo without losing their commit histories.

Step 1: Prepare a New Repository

Start by creating a new empty repository which will serve as the monorepo.

mkdir monorepo
cd monorepo
git init

Step 2: Add Each Repository as a Remote

For each of the repositories you want to merge, add them as a remote to the new repository.

git remote add application <path_or_url_to_application_repo>
git remote add backend <path_or_url_to_backend_repo>

Step 3: Fetch the Histories

Fetch the histories of all the repositories.

git fetch --all

Step 4: Create a Branch for Each Repository

For clarity, create a branch for each repository’s history.

git branch application_branch application/master
git branch backend_branch backend/master

Step 5: Merge Each Repository into the Monorepo

For each repository, create a directory in the monorepo, and use git read-tree to merge the repository into that directory. This will keep the history intact.

# For the application repo
git checkout -b merge_application
mkdir application
git read-tree --prefix=application/ -u application_branch
git commit -m "Merged application repo into monorepo"
git checkout master
git merge merge_application

# For the backend repo
git checkout -b merge_backend
mkdir backend
git read-tree --prefix=backend/ -u backend_branch
git commit -m "Merged backend repo into monorepo"
git checkout master
git merge merge_backend

Step 6: Clean Up

Once you’ve merged all the repositories, you can remove the temporary branches and remote references.

git branch -d merge_application
git branch -d merge_backend

git remote remove application
git remote remove backend

Step 7: Push to Remote

If you want to push the monorepo to a remote repository (e.g., GitLab), you can do so now.

git remote add origin <url_to_your_gitlab_monorepo>
git push -u origin master

By following these steps, you’ll have a monorepo with the application and backend repositories merged into their respective subdirectories, with their histories intact. This approach ensures that you don’t lose any valuable commit history while transitioning to a monorepo architecture.