There are many reasons why you might want to merge multiple Git repositories into one, but perhaps the most common is when you’re transitioning to a monorepo.

It’s simpler than it sounds, though the steps aren’t necessarily obvious. In this guide, we’ll walk through the process of merging repo-A (a single application) into repo-B (the target monorepo).

Prerequisites

  • Both repositories should be clean (no uncommitted changes).
  • Back up your repositories or work on a separate branch before proceeding.

Step 1: Prepare the Source Repository

In repo-A, you need to move all files into the subdirectory where you want them to live in the target monorepo.

# Move into the directory for repo-A
cd repo-A

# Create the target directory structure (e.g., apps/app-A)
mkdir -p apps/app-A

# Move all tracked files into the new directory
# (Excluding the new directory itself)
git ls-tree -z -r --name-only HEAD | xargs -0 -I {} mv {} apps/app-A/

# Commit and push these changes
git add .
git commit -m "Relocate files to apps/app-A for monorepo migration"
git push origin main

Step 2: Merge into the Target Repository

Now, move to repo-B and add the source repository as a remote.

# Move into the target monorepo (repo-B)
cd repo-B

# Add repo-A as a new remote
git remote add repo-a-remote https://github.com/user/repo-A.git

# Fetch the remote data
git fetch repo-a-remote

# Merge repo-A's branch into repo-B's current branch
# Using --allow-unrelated-histories is essential here
git merge repo-a-remote/main --allow-unrelated-histories

Step 3: Cleanup

Once the merge is successful and you’ve verified that the history is intact, you can remove the remote.

git remote remove repo-a-remote

That’s it! You should now have all the Git history from repo-A preserved within repo-B, with all files correctly located in their new subdirectories.