April 8, 2020
Monorepos are all the rage. If you already have two git repositories but want to switch to a monorepo without losing history, look no further.
Monorepos let us version our back-end with our front-end, making compability easy with combined builds and deployments using a shared CI/CD pipeline. They also let us make assumptions about relative relationships between folders during development.
It is easier than you think to merge two separate repositories into one.
Say you have RepositoryA and RepositoryB, which you want to merge to create RepositoryC:
RepositoryA:
\
    \.gitignore
    \webpack.config.js
    \tslint.json
RepositoryB:
\
    \.gitignore
    \Program.cs
New RepositoryC:
\
    \.gitignore
    \RepositoryA
        \webpack.config.js
        \tslint.json
    \RepositoryB
        \Program.cs
You'll notice from the above differences that we have a few steps required:
In RepositoryA,
RepositoryA into a sub-directory RepositoryA (except .gitignore)
RepositoryARENAME in git.git push -u origin HEADIn RepositoryB,
RepositoryB into a sub-directory RepositoryB (except .gitignore)
RepositoryBRENAME in git.git push -u origin HEADIn RepositoryC,
Initialize your new repository (maybe clone an existing empty repository)
c:\RepositoryC>  git remote -v
origin  https://some-example@dev.azure.com/some-example/some-example/_git/RepositoryC (fetch)
origin  https://some-example@dev.azure.com/some-example/some-example/_git/RepositoryC (push)
Create an initial commit (maybe add a README.md file)
Add RepositoryA and RepositoryB as remotes
Run:
c:\RepositoryC>  git remote add repository-a https://some-example@dev.azure.com/some-example/some-example/_git/RepositoryA
c:\RepositoryC>  git remote add repository-b https://some-example@dev.azure.com/some-example/some-example/_git/RepositoryA
After:
c:\RepositoryC>  git remote -v
repository-a     https://some-example@dev.azure.com/some-example/some-example/_git/RepositoryA (fetch)
repository-a     https://some-example@dev.azure.com/some-example/some-example/_git/RepositoryA (push)
repository-b     https://some-example@dev.azure.com/some-example/some-example/_git/RepositoryB (fetch)
repository-b     https://some-example@dev.azure.com/some-example/some-example/_git/RepositoryB (push)
origin  https://some-example@dev.azure.com/some-example/some-example/_git/RepositoryC (fetch)
origin  https://some-example@dev.azure.com/some-example/some-example/_git/RepositoryC (push)
Fetch the latest from these newly references remotes
c:\RepositoryC>  git fetch repository-a
* [new branch]      master     -> repository-a/master
c:\RepositoryC>  git fetch repository-b
* [new branch]      master     -> repository-b/master
Merge each of these new branches into your repository
c:\RepositoryC>  git merge repository-a/master --allow-unrelated-histories
RepositoryC contained.c:\RepositoryC>  git merge repository-b/master --allow-unrelated-histories
Note: You may need to manually merge and commit your merge at this point, depending on what you initial commit to RepositoryC contained.
--allow-unrelated-historiesis the magic sauce. Read the docs
At this point, you should have your new file structure containing the full history of both repositories into one. 🎉
Push your new remote
c:\RepositoryC>  git push -u origin HEAD
You did it!
Further reading...