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:
dir\\.gitignore\webpack.config.js\tslint.json
RepositoryB:
dir\\.gitignore\Program.cs
New RepositoryC:
dir\\.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)
shellc:\RepositoryC> git remote -vorigin 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:
shellc:\RepositoryC> git remote add repository-a https://some-example@dev.azure.com/some-example/some-example/_git/RepositoryAc:\RepositoryC> git remote add repository-b https://some-example@dev.azure.com/some-example/some-example/_git/RepositoryA
After:
shellc:\RepositoryC> git remote -vrepository-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
shellc:\RepositoryC> git fetch repository-a* [new branch] master -> repository-a/masterc:\RepositoryC> git fetch repository-b* [new branch] master -> repository-b/master
Merge each of these new branches into your repository
shellc:\RepositoryC> git merge repository-a/master --allow-unrelated-histories
RepositoryC contained.shellc:\RepositoryC> git merge repository-b/master --allow-unrelated-histories
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
shellc:\RepositoryC> git push -u origin HEAD
You did it!
Further reading...